C++primer第五版 假设有一组成绩的集合,其中成绩的取值是从0到100.以10分为一个分数段,要求统计各个分数段各有多少个成绩。要求使用下标和迭代器两种方法做。

显然,从0到10总共有101种可能的成绩取值,这些成绩分布在11个分数段上:每10个分数构成一个分数段,这样的分数段有10个,额外还有一个分数段表示满分100。这样一个分数段将统计成绩在0~9之间的数量,第二个分数段统计10~19之间的数量,以此类推,最后一个分数段统计满分100分的数量。 

具体实现时,可以使用一个含有11个元素的vector对象,每个元素分别用于统计各个分数段上出现的成绩个数。对于某个成绩来说,将其除以10就能得到对应的分数段索引。

处理数据和打印的时候,可以用下标进行遍历,也可以使用迭代器进行遍历。

以下是用下标的代码:

// primer_3_4_2.cpp : Defines the entry point for the application.
// 假设有一组成绩的集合,其中成绩的取值是从0到100.以10分为一个分数段,要求统计各个分数段各有多少个成绩。
// 要求使用下标和迭代器两种方法做
// 分为11组,0~9,10~19,20~29,...,90~99,100

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main()
{
	vector<int> vec(11,0); //初始化,建立11个初始值为0的vector容器vec
	//用下标方法
	int score;
	cout << "input the scores to test Subscripting Operator: (q to over)" << endl;
	while(cin >> score)  //读入数据
	{
		if(score>=0 && score<=100)  //保证输入的是合法数据
			vec[score/10]++;  //相应分数段计数加1
		else
			cout << "input illegal number!" << endl;  //输入明显错误数据时报错
	}
	cout << "use Subscripting Operator" << endl;
	//用下标输出
	for(int i=0;i<11;i++)
		cout << "the total number of level " << i+1 << " is: " << vec[i] << endl;
	system("pause");
	return 0;
}

效果如下: 

以下是用迭代器的代码:

// primer_3_4_2.cpp : Defines the entry point for the application.
// 假设有一组成绩的集合,其中成绩的取值是从0到100.以10分为一个分数段,要求统计各个分数段各有多少个成绩。
// 要求使用下标和迭代器两种方法做
// 分为11组,0~9,10~19,20~29,...,90~99,100

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main()
{
	vector<int> vec(11,0); //初始化,建立11个初始值为0的vector容器vec
	int *it=vec.begin();  //定义指针指向vec容器第一个元素
	//用迭代器方法
	int grade;
	cout << "input the scores to test iterator: (q to over)" << endl;
	while(cin >> grade)  //读入数据
	{
		if(grade>=0 && grade<=100)  //保证输入的是合法数据
			(*(it+grade/10))++;  //相应分数段计数加1
		else
			cout << "input illegal number!" << endl;  //输入明显错误数据时报错
	}
	cout << "use iterator" << endl; //提示语
	//用迭代器输出
	for(int j=0;j<11;j++)
		cout << "the total number of level " << j+1 << " is: " << *(it+j) << endl;
	system("pause");
	return 0;
}

效果如下: 

需要注意的是,回车键并不能结束while循环,必须输入与定义不同的数据类型才能结束循环。这里,我在提示语中加入了(q to over)提示用户如果成绩输入完成,则在最后添个‘q’,即可跳出while循环进入打印语句。当然,提示输入‘q’结束只是为了给用户一个明确的引导,其实输入其它非int类型的数据都能结束循环。

另外,书上给的迭代器的用法示例如下

auto it=vec.begin();

但是编译时会报错,在VC6.0下编译遇到的问题是,auto类型符是C++11的标准,VC6.0并不支持。因此在这里我将auto替换成了int,因为我是知道vec中的元素为int类型。同时,it前还应加上指针符号 *,即

int *it=vec.begin();

最后,我最初的设想是把两种方法合在一起,在主函数中使用两个while循环来先后读取一组数据,处理后并打印。即如下程序

// primer_3_4_2.cpp : Defines the entry point for the application.
// 假设有一组成绩的集合,其中成绩的取值是从0到100.以10分为一个分数段,要求统计各个分数段各有多少个成绩。
// 要求使用下标和迭代器两种方法做
// 分为11组,0~9,10~19,20~29,...,90~99,100

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main()
{
	vector<int> vec(11,0); //初始化,建立11个初始值为0的vector容器vec
	vector<int> vec2(11,0); //初始化,建立11个初始值为0的vector容器vec2
	//用下标方法
	int score;
	cout << "input the scores to test Subscripting Operator: (q to over)" << endl;
	while(cin >> score)  //读入数据
	{
		if(score>=0 && score<=100)  //保证输入的是合法数据
			vec[score/10]++;  //相应分数段计数加1
		else
			cout << "input illegal number!" << endl;  //输入明显错误数据时报错
	}
	cout << "use Subscripting Operator" << endl;
	//用下标输出
	for(int i=0;i<11;i++)
		cout << "the total number of level " << i+1 << " is: " << vec[i] << endl;

	//用迭代器方法
	int *it=vec2.begin();  //定义指针指向vec容器第一个元素
	int grade;
	cout << "input the scores to test iterator: (q to over)" << endl;
	while(cin >> grade)  //读入数据
	{
		if(grade>=0 && grade<=100)  //保证输入的是合法数据
			(*(it+grade/10))++;  //相应分数段计数加1
		else
			cout << "input illegal number!" << endl;  //输入明显错误数据时报错
	}
	cout << "use iterator" << endl; //提示语
	//用迭代器输出
	for(int j=0;j<11;j++)
		cout << "the total number of level " << j+1 << " is: " << *(it+j) << endl;
	system("pause");
	return 0;
}

然而因为对缓冲器的知识掌握得不好,没能成功实现。设想的是先输入一组数据,用下标的方式处理,再输入一组数据,用迭代的方式处理。但是结果却是:

我输入了一组数据之后,第二个while循环就进不去了,直接跳到while循环外面执行打印语句,所以可以看到,使用迭代器这种方法打印出的结果全为0。不过这个问题先放在此处,留到以后解决。

猜你喜欢

转载自blog.csdn.net/elma_tww/article/details/82224415