第八章 非变异算法 8.3计数 8.4比较

8.3计数

8.3.1主要函数

STL主要提供了以下查询函数:

count() :在序列中统计某个值出现的次数。

template

size_t count(InIt first,InIt last,const T& val);

InIt: 输人选代器,first 表示起始元素的选代器指针,last 表示结束元素的选代器指针。T:模板参数类型,该函数返回[first,last)间的元素数目,这些元素满足* (first+i)=val;

count if() :在序列中统计与某谓词(表达式)匹配的次数

template

size_t count if(InIt first,InIt last,Pred pr);

InIt:输人迭代器,first 表示起始元素的选代器指针,last 表示结束元素的选代器指针。Pred;普通全局函数,返回值是 bool类型

8.3.2 实例

例:求数组中有多少个0

#include 

#include 

using namespace std;

int main() {

    int A[] = {2, 4, 6, 0, 3, 1, -7};

    const int N = sizeof(A) / sizeof(int);

    cout << "Number of zeros: " << count(A, A + N, 0) << endl;

    return 0;

}

例:查询有多少学生成绩为80分(次重点)

#include 

#include 

#include 

using namespace std;

class Student {

public:

    int NO; // 学号

    string strName; // 姓名

    int grade; // 成绩



    Student(int NO, string strName, int grade) {

        this->NO = NO;

        this->strName = strName;

        this->grade = grade;

    }

    bool operator==(int grade) {

        return this->grade == grade;

    }

};

int main() {

    vector v;

    Student s1(1000, "张三", 80);

    Student s2(1001, "李四", 85);

    Student s3(1002, "王五", 80);

    Student s4(1003, "赵六", 80);



    v.push_back(s1);

    v.push_back(s2);

    v.push_back(s3);

    v.push_back(s4);



    int nCount = count(v.begin(), v.end(), 80);

    cout << "成绩为80分的人数为: " << nCount << endl;



    return 0;

}

对此例主要应理解必须重载 Student 类的运算符“==”这是因为当执行 int nCount=count(v.begin(),vend(),80)时,要比较[vbegin,v.end)中各 Student 对象是否与80相等。

例:查询有多少学生成绩高于80分(次重点)

#include 

#include 

#include 

using namespace std;

class Student {

public:

    int NO; // 学号

    string strName; // 姓名

    int grade; // 成绩

    Student(int NO, string strName, int grade) {

        this->NO = NO;

        this->strName = strName;

        this->grade = grade;

    }

    bool operator==(int grade) {

        return this->grade == grade;

    }

};

class MatchExpress {

private:

    int grade;

public:

    MatchExpress(int grade) {

        this->grade = grade;

    }

    bool operator()(Student s) {

        return s.grade > grade;

    }

};

int main() {

    vector v;

    Student s1(1000, "张三", 80);

    Student s2(1001, "李四", 85);

    Student s3(1002, "王五", 80);

    Student s4(1003, "赵六", 80);

    v.push_back(s1);

    v.push_back(s2);

    v.push_back(s3);

    v.push_back(s4);



    int nCount = count_if(v.begin(), v.end(), MatchExpress(80));

    cout << "成绩高于80分的人数为: " << nCount << endl;

    return 0;

}

演示如何使用自定义的函数对象作为 count_if 算法的条件,定义了一个函数对象类 MatchExpress,重载了operator()(Student& s)函数当执行 main函数中的 count if 语句时把第三个参数 MatchExpress(80)作为函数对象先调用构造函数给 MatchExpress 的成员变量 grade 赋值为 80然后向量中的每个学生对象作为函数对象的参数调用operator()(Student& s)函数判断该学生的成绩是否大于80

8.4比较

8.4.1主要函数

equal():两个序列中的对应元素都相同时为真。注意:①比较的并不是完全的,是看谁包含谁②不可以用于集合容器map set等(其之间没有联系)可以比较,是不能用由于出错】

template

        bool equal(InItl first,InItl last,InIt2 x);

template

       bool equal(InItI first,InIt1 last,InIt2 x, Pred pr);

参数说明:

InIt1:第一个容器的迭代器,first 表示起始元素的选代器指针,last 表示结束元素的迭代器指针。

InIt2:第二个容器的迭代器。

Pred:二元全局函数或函数对象。

第一个原型含义是:对两个输人迭代器而言,若依次有  (first十0)= * (x+0),* (first+1)=*(x+1),.,* [first+(last-first-1)]=*[x+(last-first-1)],那这两个容器序列是相等的。

第二个原型与第一个类似,只不过要定义预判定函数 pr(* (firstl+N)* (first2+N))

mismatch():找出两个序列相异的第一个元素

原型:

template

pairmismatch(InItl first,InItl last,InIt2 x);

template

pairmigmateh(InItl first, InItl last, InIt2 x, Pred pr);

参数说明:

InIt:输人选代器,first 表示起始元索的选代器指针,last 表示结束元素的选代器指针·Pred:二元全局函数或函数对象。

第一个原型含义是:对两个迭代器而言,返回第一对元素不相等时的迭代器指针,保存在pair 对象中。pair 有两个成员变量:first和 second,分别表示InIt1 及It2不相等时的迭代指针。

第二个原型与第一个类似,只不过要定义预判定函数 pr(* (first1+N)* (irst2+M))

例:比较两个整型数组是否相等

#include  

#include  

using namespace std;  

int main() {  

    int A1[] = {3, 1, 4, 1, 5, 9, 3};  

    int A2[] = {3, 1, 4, 2, 8, 5, 7};  

    const int N = sizeof(A1)/sizeof(int);    

    cout << "Result of comparison:" << equal(A1, A1+N, A2) << endl;  

    return 0;  

}

例:寻找两个整型数组元素不相等时的元素值。

#include 

#include 

#include 

using namespace std;



int main() {

    int A1[] = {3, 1, 4, 1, 5, 9, 3};

    int A2[] = {3, 1, 4, 2, 8, 5, 7};

    const int N = sizeof(A1)/sizeof(int);//计算了数组的元素个数 N

    pair result = mismatch(A1, A1 + N, A2);//函数会从 A1 和 A2 中找出第一个不匹配的元素

    cout << "The first mismatch position " << result.first - A1 << endl;

    cout << "Values are: " << *result.first <<","<< *(result.second) << endl;

    return 0;

}

主要应理解 pairresult=mismatch(Al,A1+N,A2)包括

  (1)  由于A1、A2均是整型数,因此 pair 模板的两个参数类型是整型指针 int*。可分析出:pair 成员变量 first 表示A1的迭代指针second 表示A2的迭代指针。

(2)执行过程是*(A1+i)与*(A2+i)比较若相同增加1,继续比较直至不同时mismatch 返回 pair 对象。

例:查询第一对成绩不相等学生的信息

#include  #include  #include  #include 

using namespace std;

class Student {

public:

    int NO; string strName;  int grade;

    Student(int NO, string strName, int grade) {

        this->NO = NO;

        this->strName = strName;

        this->grade = grade;

    }

    bool operator==(const Student& s) const {

        return this->grade == s.grade;

    } };

int main() {

    vector v1;

    Student s1(1001, "aaa", 90);

    Student s2(1002, "bbb", 80);

    Student s3(1003, "ccc", 70);

    v1.push_back(s1),v1.push_back(s2),v1.push_back(s3);



    vector v2;

    Student s4(1004, "ddd", 90);

    Student s5(1005, "eee", 80);

    Student s6(1006, "fff", 75);

    v2.push_back(s4),v2.push_back(s5),v2.push_back(s6);

    cout << "查询第一对成绩不相等学生的信息:" << endl;

    typedef vector::iterator it;//迭代器类型 it

//调用 mismatch 函数,并将其返回值存储在名为 result 的 pair 对象中。mismatch 函数会在 v1 和 v2 的范围内进行匹配,

//并返回第一对不匹配元素的迭代器

    pair result = mismatch(v1.begin(), v1.end(), v2.begin(), v2.end());

    Student stu1 = *(result.first);//将第一对不匹配学生的迭代器 result.first 解引用,并将其指向的对象赋值给 stu1

    Student stu2 = *(result.second);

    cout << "学号:" << stu1.NO << "\t姓名:" << stu1.strName << "\t成绩:" << stu1.grade << endl;

    cout << "学号:" << stu2.NO << "\t姓名:" << stu2.strName << "\t成绩:" << stu2.grade << endl;

    return 0;

}

结果:

查询第一对成绩不相等学生的信息:学号:1001    姓名:aaa     成绩:90学号:1004    姓名:ddd     成绩:90

8.4.2例上课强调让set用上equal

若实例A1A2不同最后输出的和相同时输出的如下图

第八章 非变异算法 8.3计数 8.4比较_第1张图片

第八章 非变异算法 8.3计数 8.4比较_第2张图片

#include  #include  #include 

using namespace std;

int main() {

    int A1[] = {13, 14, 1, 20};

    int A2[] = {13, 14, 1, 20};

    const int N = sizeof(A1) / sizeof(int);

    cout << "Result of comparison: " << equal(A1, A1 + N, A2) << endl;



    set s1(A1, A1 + N);

    set > s2(A2, A2 + N);



    cout << "Result of comparison set: " << equal(s1.begin(), s1.end(), s2.begin()) << endl;



set::iterator it = s1.begin();

///这部分代码遍历了集合 s1 的元素,并通过 s2.find(*it) 来查找元素是否存在于 s2 中

    for (; it != s1.end(); ++it) {

        if (s2.find(*it) == s2.end()) {

            break;

        }

    }

    if (it == s1.end()) {

        cout << "All elements of s1 are present in s2." << endl;

    } else {

        cout << "Element " << *it << " is not present in s2." << endl;

    }



    return 0;

}

 第八章 非变异算法 8.3计数 8.4比较_第3张图片

8.5 变异算法copy函数

        (考核:  结合ostream Operator)

copy
原型:
  template
          OutIt copy(InIt first, InIt last, OutIt x);
参数说明:
模板参数 InIt 表示输人迭代器,OutIt 表示输出选代器
返回值类型是 Outlt,是输出迭代器的尾指针。该函数功能是“正向一正向”复制,把输人迭代器[first,last)间的元素依次复制到输出迭代器 x中,并返回输出迭代器的尾指针。

#include 
#include 
#include 
#include 

using namespace std;

int main() {
    vector numbers {1, 2, 3, 4, 5};

    // 将容器中的元素复制到输出流中
    copy(numbers.begin(), numbers.end(), ostream_iterator(cout, " "));

    return 0;
}

8.6 习题 

1、下面代码执行完的结果为:()

     int A1[] = {3, 1, 4, 1, 5, 9, 3};位置的差值

    int A2[] = {3, 1, 4, 2, 8, 5, 7};

    const int N = sizeof(A1)/sizeof(int);

     pair result = mismatch(A1, A1+N, A2);//int*指位置

     cout << result.first – A1 << endl;

     a) 1    b) 2    c) 3    d) 4

2、 下面代码执行完的结果为:()

    int A1[] = {3, 1, 4, 1, 5, 9, 3};

    int A2[] = {3, 1, 4, 2, 8, 5, 7};

    const int N = sizeof(A1)/sizeof(int);//equal 算法来比较两个数组 A1 和 A2 是否相等。

    cout << "Result:" << equal(A1, A1+N, A2) << endl;

    A.1    B. 0    C. 2    D.-1

在本行代码中,equal(A1, A1+N, A2) 表示对数组 A1 和 A2 进行比较,其中 A1, A1+N 表示要比较的第一个序列的首尾指针,即从 A1 开始,比较 N 个元素;A2 则表示要比较的第二个序列的首指针

3、 试图通过copy函数将list l中的内容输出到标准输出上,并后跟逗号,补全代码

   copy(l.begin(),l.end(), _ostream_iterator__(___cout___, _”,”_))。

4、  补充完整代码:要求利用copy函数将v中的元素全部显示到屏幕上,每一个元素中间用“\t”间隔。

          int main()

          {

           vector v;

           for (int i=0; i<5;i++)

              v.insert(i);

           copy(_v.begin()__,__v.end()____,_ostream_iterator(cou”\t”)___);

           return 0;

           }

5、copy使用:

copy(v.begin,v.end,ostream_iterator<类型>(cout,""))

你可能感兴趣的:(C++STL大三上,c++,算法,开发语言,数据结构)