泛型算法基礎習題

10.1頭文件algorithm中定義一個名爲count函數,它類似find,接受一對迭代器和一個值爲參數,count返回定值在序列中出現的次數.編寫程序,讀取int序列存入vector中,打印有多少個元素等於給定值.

請輸入若干個字符串
abc code hello world 
請輸入要查找的字符串
hello
hello出現的次數爲1

#include <iostream>
#include <vector>
#include <list> 
#include <algorithm>
using namespace std;

int main1()  // 統計單個數
{
    cout << "請輸入一組數,以回車結束" << endl;
    int i;
    vector<int> vec; //={1, 2, 3, 4, 5, 6, 6};
    while(cin >> i )
    {
        vec.push_back(i);

        if (cin.get()== '\n') // 判斷是否輸入結束  很重要
            break;
    }

    int temp;
    cout << "請輸入你要查詢的數"<<endl;
    cin >> temp;
    auto coun = count(vec.cbegin(), vec.cend(), temp);
    cout << temp << "出現的次數爲:"<< coun << endl;
    return 0;
}

int main() // 統計字符串
{
    cout << "請輸入若干個字符串以空格隔開"<< endl;
    string str;
    list<string> list1;
    while (cin >> str)
    {
        list1.push_back(str);
        if (cin.get() == '\n')
            break;
    }

    cout << "請輸入要查找的字符串" << endl;
    cin >> str;
    cout <<str<<"出現的次數爲" <<count(list1.cbegin(),list1.cend(), str);
//  cout << str << "出現的次數爲: " << coun << endl;
    return 0;
}
/*
   count返回的統計所給的值的次數
   find返回的是所給的值在容器的迭代器(沒有的話返回end())
 */

//謂詞的使用
10.13

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;

bool compare(const string &s1) // 謂詞就是一個可調用的表達式
{
    if (s1.size() >= 5)
        return true;
    else
        return false;
}
int main()
{
    vector<string> vec = {"ab", "abc", "hello", "world", "c++primer"};
    vector<string>:: iterator it = partition(vec.begin(), vec.end(), compare);

    cout << "排序後字符串大於等於5的爲:" << endl;
    auto i = vec.begin();
    for (; i != it; i++)
    {
        cout << *i << " ";
    }
    cout << endl;
    return 0;
}
排序後字符串大於等於5的爲:
c++primer world hello 

一個vector中保存1到9,將其拷貝到其他三個容器中.分別使用inserter,back_inserter, front_inserter將遠元素添加到三個容器中

#include <iostream>
#include <vector>
#include <algorithm>
#include <list>
using namespace std;

int main()
{
    vector<int> vec ={1, 2, 3, 4, 5, 6, 7, 8, 9};
    list<int> list1, list2, list3;
    //三種插入方法
    copy(vec.begin(), vec.end(), inserter(list1, list1.begin()));
    copy(vec.begin(), vec.end(), back_inserter(list2));
    copy(vec.begin(), vec.end(), front_inserter(list3));

    cout << "inserter插入結果 ";
    for (auto i : list1)
        cout << i << " ";
    cout << endl;

    cout << "back_inserter插入結果 ";
    for (auto i : list2)
        cout << i << " ";
    cout << endl;

    cout << "front_inserter插入結果 ";
    for (auto i : list3)
        cout << i << " ";
    cout << endl;
    return 0;
}
//inserter插入結果 1 2 3 4 5 6 7 8 9 
//back_inserter插入結果 1 2 3 4 5 6 7 8 9 
//front_inserter插入結果 9 8 7 6 5 4 3 2 1
//注意front_inserter的插入方式

// 重寫統計長度小於等於6的單詞數量的程序,使用函數代替lambda

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
using namespace std;

bool fun(const string &s)
{
    return s.size() <= 5;
}
int main()
{
    vector<string>vec = {"abc", "hello", "c++Primer","world", "g++gcc"};
    auto i = count_if (vec.begin(), vec.end(), fun);
    cout << "長度小於等於5的有" << i << "個" << endl;
    return 0;
}

使用list調用函數去重排序

#include <iostream>
#include <list>
#include <numeric>
#include <algorithm>
using namespace std;

int main1()
{
    list <string> lst = {"turtle","the","the","red","quick","over","fox","jumpsl","red", "quick"};

    lst.sort(); // 排序

    lst.unique(); // 去重
    for (auto i : lst)
        cout << i << " ";
    cout << endl;
    return 0;
}
//特定容器算法
//對於list和forward_list應優先使用成員函數版本,而不是通用版本(sort() 就是通用版本 lst.sort()就是成員函數) 因爲成員函數比較快是通過數據結構來實現的
bool comp(const int &i, const int &j)
{
    return i > j;
}
int main()
{
    list<int>lst;
    int i;
    while (cin >> i) // 輸入
    {
        lst.push_back(i);
        if (cin.get() == '\n')
            break;
    }

//  lst.sort(); // 排序 默認從小到大排序 
    lst.sort(comp); // 從大到小排序  //也叫做謂詞
    lst.unique(); // 去重

    for (auto it : lst)
        cout << it << " ";
    cout << endl;

    return 0;
}

反向迭代器:
364圖可以作爲參考
10.34:使用reverse_iterator逆序打印一個vector
10.35:使用普通迭代器逆序打印一個vector
10.36使用find在一個int的list中查找最後一個值爲0的元素
10.37:給定一個包含10個元素的vector,將位置3到7之間的元素按逆序拷貝到一個list中

#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <algorithm>
using namespace std;

// 10.34
int main1()
{
//  list<string>vec = {"hello", "world", "c++primer"};
    list <string> vec = {"hello"};
    for (auto it = vec.crbegin(); it != vec.crend(); it++)
        cout << *it << " " ;
    cout << endl;   // 輸入結果:c++primer world hello

    auto reverse = find(vec.crbegin(), vec.crend(), "hello");
//  cout << *reverse;
    for (auto it = vec.crbegin(); it != reverse; it++)
        cout << *it << " ";  // c++primer world
    cout << endl;

    return 0;
}
// 參考364c++primer 圖

// 35
int main2()
{
    vector<int> vec = {1, 2, 3, 4, 5, 6};
    for (auto it = vec.cend(); it != vec.begin();)
        cout << *--it << " "; // 注意這裏要先減去一個
    cout << endl;
    return 0;
}

//找到值爲0的元素
int main3()
{
    list<int> vec = {1, 2, 3, 4, 0 ,5};
    auto found = find(vec.crbegin(), vec.crend(), 0);
    cout << *found << "is front of " << *found.base() << endl;

    return 0;
}
//37 逆序拷貝
int main()
{
    vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    list<int>list1;

    copy(vec.rbegin()+3, vec.rend() -2, back_inserter(list1));
    for (auto i : list1)
        cout << i << " ";
    cout << endl;
    return 0;
}

求和函數:

#include <iostream>
#include <vector>
#include <numeric>
using namespace std;

int main()
{
    int i;
    cout <<"請輸入一列數" << endl;
    vector<int>vec;
    while (cin >> i)
    {
        vec.push_back(i);
        if (cin.get() == '\n')
            break;
    }
    int sum = accumulate(vec.cbegin(), vec.cend(), 0);

    cout << "這一列之和爲:";
    cout << "sum = " << sum << endl;
    return 0;
}
/* accumulate接受三個參數前兩個是迭代器範圍 後面是表示使用哪個"+"
   如果用來連接兩個字符串注意最後一個參數是string("")
 */

部分知識點

位置返回類型:在函數形參表後面加上-> 
auto fun(int i) -> int (*)[10];
表示返回的是一個指針,並且該指針指向含有10個整數的數組

lambda表達式 可以理解爲一個未命名的內聯函數,lambda和普通函數的區別就是必須使用尾置返回類型    
10.26:集中特殊的迭代器:實際上相當於一個泛型算法,接受一個容器作爲參數,產生一個迭代器將元素插入容器中;
插入迭代器:這些迭代器綁定到容器上,可以用來想容器插入元素;
流迭代器:綁定到輸入輸出流上,用來遍歷所有關聯的io流
反向迭代器:向後移動而不是向前移動,除了forward_list其他容器都有
移動迭代器:移動容器中的元素
插入迭代器分三種:back_inserter()創建一個使用push_back的迭代器, front_inserter()
創建一個push_front的迭代器,inserter()創建一個使用insert迭代器,接受兩個參數.插入到指定迭代器之前,前提是容器必須支持push_back()的操作


反向迭代器:
反向迭代器與迭代器的轉換 

    reverse_iterator與iterator都繼承自_Iterator_base,它們是可以相互轉換的。 

調用reverse_iterator的base()方法可以獲取"對應的"iterator。 
可以用iterator構造一個"對應的"reverse_iterator。 
   下面的兩個例子展示了它們之間的轉換: 

list<int> test_list; 
for (size_t i = 1; i < 8; i++) 
{ 
    test_list.push_back( i*2 ); 
} 
list<int>::reverse_iterator rit = find(test_list.rbegin(), test_list.rend(), 8); 
list<int>::iterator it(rit.base()); 
cout << *rit << endl; 
cout << *it << endl;


   上面的代碼是先查找到一個指向8的reverse_iterator,並reverse_iterator的base()方法得到一個iterator。但是從輸出上看,iterator指向的元素的值並不是8,而是10list<int> test_list; 
for (size_t i = 1; i < 8; i++) 
{ 
    test_list.push_back( i*2 ); 
} 
list<int>::iterator it = find(test_list.begin(), test_list.end(), 8); 
list<int>::reverse_iterator rit(it); 
cout << *it << endl; 
cout << *rit << endl; 
   上面的代碼是先查找一個指向8的iterator,然後用該iterator構造一個reverse_iterator。但是從輸出上看,reverse_iterator指向的元素並不是8,而是6。 
http://www.cnblogs.com/fnlingnzb-learner/p/6842298.html

前向迭代器:單向,支持輸入輸出,
雙向迭代器:雙向,支持讀寫,還支持遞增遞減運算符.
隨機訪問迭代器:基本支持所有功能

10.41:
// 找到old_val 就用new_val替換
replace(beg, end, old_val, new_val);
// 找到滿足條件pred的就用new_cal替換
replace_if(beg, end, pred, old_val, new_val);
//找到old_val就用new_val替換 並拷貝到dest中(dest表示一個目的迭代器)
replace_copy(beg, end, dest, old_val, new_val);
//找到滿足pred條件的就用new_val替換old_val,並拷貝到dest中
replace_copy_if(beg, end, dest, perd, old_val, new_val)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章