1. 程式人生 > >STL基礎--演算法(已排序資料的演算法,數值演算法)

STL基礎--演算法(已排序資料的演算法,數值演算法)

已排序資料的演算法

  • Binary search, merge, set operations
  • 每個已排序資料演算法都有一個同名的更一般的形式

vector

1. 二分法搜尋

// 搜尋元素
bool found = binary_search(vec.begin(), vec.end(), 9);  

vector<int> s = {9, 45, 66};
bool found = includes(vec.begin(), vec.end(),     // Range #1
                        s.begin(), s.end());        // Range #2
// s的所有元素是否都在vec中
// vec和s都必須已排序   

// 搜尋位置
itr = lower_bound(vec.begin(), vec.end(), 9);  // vec[1]  
// 搜尋第一個可插入的位置,插入後仍然是排序的

itr = upper_bound(vec.begin(), vec.end(), 9);  // vec[4] 
// 尋找最後一個可插入的位置,插入後仍然保持排序

pair_of_itr = equal_range(vec.begin(), vec.end(), 9); 
// 返回第一個和最後一個位置

2. 合併

vector<int> vec = {8,9,9,10}; 
vector<int> vec2 = {7,9,10}; 
merge(vec.begin(), vec.end(),      // Input Range #1
        vec2.begin(), vec2.end(),    // input Range #2
        vec_out.begin());               // Output 
      //vec和vec2都必須已排序
      // 重複的元素保留
// vec_out: {7,8,9,9,9,10,10}

vector<int> vec = {1,2,3,4,1,2,3,4,5}  // vec中兩部分都已排序
inplace_merge(vec.begin(), vec.begin()+4, vec.end());  
// vec: {1,1,2,2,3,3,4,4,5} 

3. 集合操作

//    - 輸入資料都必須已排序
//    - 結果也是排序的
vector<int> vec = {8,9,9,10}; 
vector<int> vec2 = {7,9,10}; 
vector<int> vec_out[5]; 
set_union(vec.begin(), vec.end(),      // Input Range #1
            vec2.begin(), vec2.end(),    // input Range #2
            vec_out.begin());               // Output 
// 並集,兩者都有的元素在結果中只保留一個
// vec_out: {7,8,9,9,10}

set_intersection(vec.begin(), vec.end(),      // Input Range #1
                   vec2.begin(), vec2.end(),    // input Range #2
                   vec_out.begin());               // Output 
// 交集,兩者都有的元素才儲存在結果中vec_out
// vec_out: {9,10,0,0,0}

vector<int> vec = {8,9,9,10}; 
vector<int> vec2 = {7,9,10}; 
vector<int> vec_out[5]; 
set_difference(vec.begin(), vec.end(),      // Input Range #1
                 vec2.begin(), vec2.end(),    // input Range #2
                 vec_out.begin());               // Output 
// 差集,vec有且vec2沒有的元素儲存
// vec_out: {8,9,0,0,0}

set_symmetric_difference(vec.begin(), vec.end(),      // Input Range #1
                 vec2.begin(), vec2.end(),       // input Range #2
                 vec_out.begin());               // Output 
// 交集的補集,只有其中1方有的元素
// vec_out: {7,8,9,0,0}

數值演算法

  • Accumulate, inner product, partial sum, adjacent difference

1. 累積

int x = accumulate(vec.begin(), vec.end(), 10);     //預設 + 
// 10 + vec[0] + vec[1] + vec[2] + ...

int x = accumulate(vec.begin(), vec.end(), 10, multiplies<int>());    //自定義運算
// 10 * vec[0] * vec[1] * vec[2] * ...

2. 內積

//vector<int> vec = {9,60,70,8,45,87,90};     // 7 items
int x = inner_product(vec.begin(), vec.begin()+3,  // Range #1
                       vec.end()-3,                 // Range #2
                         10);                         // Init Value
// 10 + vec[0]*vec[4] + vec[1]*vec[5] + vec[2]*vec[6]
        
int x = inner_product(vec.begin(), vec.begin()+3,  // Range #1
                        vec.end()-3,                 // Range #2
                          10,                          // Init Value
                          multiplies<int>(),
                          plus<int>());
// 10 * (vec[0]+vec[4]) * (vec[1]+vec[5]) * (vec[2]+vec[6])

3. 部分和

partial_sum(vec.begin(), vec.end(), vec2.begin());
// vec2[0] = vec[0]
// vec2[1] = vec[0] + vec[1];
// vec2[2] = vec[0] + vec[1] + vec[2]; 
// vec2[3] = vec[0] + vec[1] + vec[2] + vec[3]; 
// ...

partial_sum(vec.begin(), vec.end(), vec2.begin(), multiplies<int>());

4. 鄰差

adjacent_difference(vec.begin(), vec.end(), vec2.begin());
// vec2[0] = vec[0]
// vec2[1] = vec[1] - vec[0];
// vec2[2] = vec[2] - vec[1]; 
// vec2[3] = vec[3] - vec[2]; 
// ...

adjacent_difference(vec.begin(), vec.end(), vec2.begin(), plus<int>());