iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 8
1
Software Development

C++ 30天屠龍記系列 第 8

C++ 30天屠龍記(第8天): Vector 與他的兄弟(二):神級通用函數

  • 分享至 

  • xImage
  •  

先建一個例子

vector<int> numbers = {1,5,4,3,5,6,3,2,3,2,4,2,1,3};
  • 之後用這個例子講解
  • 需要引入 #include<algorithm>

複製

int vector<int> numbers2;
numbers2 = numbers;

清空

numbers.clear();

切片

auto slice = vector<int>(numbers.begin()+2,numbers.begin()+6);
//{4 3 5 6}
  • 切出第三個元素到第六個元素之間的vector

合併

vector<string> bag2{"凝血丹","乾糧"};
bag.emplace( bag.end(), bag2.begin(), bag.end() );
// 這看起來有點難理解
// 意思其實是在bag的最後面(bag.end())
// 加入 bag2的所有(從begin()到end())變量
// bag現在包含了 {"屠龍刀","睏仙索","桂圓","?","凝血丹","乾糧"}

Find尋找

尋找第一個符合(function)條件的元素

* 專門尋找一個元素的Index
auto result = find(numbers.begin(),numbers.end(),3);
auto index = distance(numbers.begin(),result);
  • 這是Lambda的例子,是標準做法
//我們先建一個數字例子
vector<int> numbers = {1,5,4,3,5,6,3,2,3,2,4,2,1,3};

auto result = find_if(numbers.begin(),numbers.end(),[](auto element){
  return element > 5;
});
  • element是vector裏每個元素的名字,你可以改成其他名字都可以,例如下面
auto result = find_if(numbers.begin(),numbers.end(),[](auto i){
  return i > 5;
});
  • 以下是普通函數的例子,比較長,不太建議
auto morethan5(int element){
  return element > 5;
}
auto result = find_if(numbers.begin(), numbers.end(), morethan5);
  • 獲取結果
//拿取結果一定要在result前打*的
cout << *result << endl;
  • 尋找第一個符合條件的元素的Index
auto result = find_if(numbers.begin(),numbers.end(),[](auto element){
  return element > 5;
});

auto index = distance(numbers.begin(),result);
  • 整片代碼就是
#include <iostream>
#include <vector>
#include <algorithm> 
using namespace std;
int main(){
  vector<int> numbers = {1,5,4,3,5,6,8,2,3,7,4,9,1,3};
  auto result = find_if(numbers.begin(),numbers.end(),[](auto element){
    return element > 5;
  });

  auto index = distance(numbers.begin(),result);
  cout << "搜尋結果是" << *result << "。\n他的位置是" << index << "。\n";
  
  return 0;
}
  • 輸出結果
搜尋結果是6。                                                                                                                              
他的位置是5。

篩選

//建立一個篩選Vector/List/Deque
vector<int> filtered(numbers.size());

auto it = copy_if (numbers.begin(), numbers.end(), bar.begin(), [](int element){
  return element > 5;
});
//Filtered 會變成{6,8,7,9}

遍歷Vector 元素

for(auto& number:numbers){
  cout << number<< " ";
}
cout << endl;
  • 這東西除了print vector之外
  • 在批量改動element的用途非常廣泛,例如說我要每個元素乘2
for(auto& number:numbers){
  number *= 2;
}
//我故意把他分拆,以證明他是真的改動了數字
for(auto& number:numbers){
  cout << number<< " ";
}
cout << endl;

Transform

將條件運算後重新組合並複寫到一個數量等於 vector.size的陣列

//建立一個篩選Vector/List/Deque
vector<int> multiply2(numbers.size());

auto it = transform(numbers.begin(), numbers.end(), multiply2, [](int element){
  return element*2;
});
//multiply2 會變成{2 10 8 6 10 12 6 4 6 4 8 4 2 6}

Reduce

  • 需要導入#include<execution>,#include<numeric> ,C++17以上才能用
  • 多數時候是用來尋找vector 元素的總和,但是也可以用來當JS reduce 用
  • 什麼是 JS的reduce呢,就是說,我們先將vector的 第1和第2個元素運算,把答案放在2;然後第2和第3個元素運算,把答案放在3;然後第3和第4個元素運算,把答案放在4這樣,例如這個例子
vector<int> smallNum = {1,4,2,3};
//這是總和而已
auto sum = reduce(execution::par,smallNum.begin(),smallNum.end());

auto max = reduce(execution::par,smallNum.begin(),smallNum.end(),[](auto ans, auto next){
  return max(ans,next);
});
  • execution::par代表他用parrallel方式運行,也就是多線程
  • max總共有四Steps
  • 首先,把 1 和 4 進行比較,得出4並放在第二個位置
  • 然後,把 4 和 2 進行比較,得出 4 並放在第三個位置
  • 然後,把 4 和 3 進行比較,得出 4 並放在第四個位置
  • 然後,把 4 放在max裏

Accumulate

  • 需要導入#include<numeric> ,舊版reduce(C++17以前版本的可以當這個reduce用)
  • 舊東西比較慢
vector<int> smallNum = {1,4,2,3};
//這是總和而已
auto sum = reduce(smallNum.begin(),smallNum.end(),0);

auto max = reduce(smallNum.begin(),smallNum.end(),0,[](auto ans, auto next){
  return max(ans,next);
});

在指定位置刪除變量/一群變量

//在開頭刪除一個變量
people_age.erase(people_age.begin());

//在結尾刪除一個變量
people_age.erase(people_age.end());

//刪除第五個變數
people_age.erase(people_age.begin()+4);

//刪除第三到第八個變數
people_age.erase(people_age.begin()+2, people_age.begin()+8);

調轉(reverse)

reverse(people_age.begin(), people_age.end());

Sort(順序排列)

sort(people_age.begin(), people_age.end());
is_sort()

2D 向量

vector<int> row = {1,4,3,5,23}
vector<vector<int>> 2DVec;
2DVec.emplace_back(row);
/*這時vector是:
* {
*	 {1,4,3,5,23}
* }
*/
2DVec.emplace_back(row);
2DVec[1].erase(row.end());
/*這時vector是:
* {
*	 {1,4,3,5,23},
*  {1,4,3,5}
* }
*/
  • 今天就到這吧!vector 是C++其中一個比較難的概念,大家可以到LeetCode去練問題

LeetCode

介紹:Leetcode 現在是全世界最大的程序題目網站,有很多題目可以練,不但有趣,不少面試題目都是在leetcode裏改一點考人的。

If 與 vector尋找:Find Common Characters

2D Vector 概念:Flipping An Image

明天應該談String吧我想


上一篇
C++ 30天屠龍記(第7天): Vector 與他的兄弟(一)
下一篇
C++ 30天屠龍記(第9天): 基礎語法 - String
系列文
C++ 30天屠龍記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
小瓜
iT邦新手 4 級 ‧ 2019-10-15 16:18:48

##在指定位置刪除變量/一群變量 :這裡是不是少了一個空白
//刪除第五個變數:那一行的begin 是不是少了()

alantsui iT邦新手 5 級 ‧ 2019-10-16 19:35:08 檢舉

謝謝你了

我要留言

立即登入留言