泛型算法基础习题

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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章