AcceleratedCpp第三章程序实现与学习记录

2021.10.25 想了想还是重新编辑一下,每一个大章节写一篇记录好了。

1.第三章的实例程序

第三章的程序主要是要实现一个自动计算学生总成绩的小程序。难点重点在于使用while循环计算平均值和使用vector 向量存储多个数值并且用成员函数vector<>::size_type得知长度来寻找中值的位置。

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

int main()
{
	cout << "请输入你的姓名" << endl;
	string name;
	cin >> name;

	cout << "请输入你的期中、期末成绩" << endl;
	double midterm, endterm;
	cin >> midterm >> endterm;

	cout << "请输入你的作业成绩" << endl;
	//因为要取作业成绩的中值,就需要储存每一个输入的作业成绩。使用vector来做这件事。

	vector<double> homework;
	double x;

	while (cin >> x && x != 101)//输入101,则循环结束
		homework.push_back(x);//读入x,并将x置于容器homework的末尾

	//为了防止程序报错,在这里增加一个检测homework总长度的环节
	typedef vector<double>::size_type vcsize;//将vcsize定义为vector<double>;;size_type这个类型的替代名
	vcsize size = homework.size();//定义size为计量homework这一容器长度的变量。类型是vector类型以表示长度的成员函数vector<double>;;size_type

	if (size == 0) {
		cout << "请输入你的平时作业成绩,再试一次吧" << endl;
		return 1;//返回1表示程序终止。
	}

	//要开始确定homework中一系列数的中值
	sort(homework.begin(), homework.end());//从homework的第一个到最后一个数进行非递减排列
	vcsize mid = size / 2;
	double middle = 0;//因为报错:不能使用未初始化的变量,因此要对middle进行初始化
	if (size % 2 == 0)
		middle += (homework[mid] + homework[mid - 1]) / 2;//因为要改变middle的值,所以不能用double middle,用+=改变middle的值。
	else
		middle += homework[mid];
	cout << "你的作业成绩的中值是:"<<middle << endl;

	//输出最后的总成绩
	streamsize prec = cout.precision();
	cout << "你的最终成绩是" << setprecision(3) << 0.4*midterm + 0.4*endterm + 0.2*middle << "。" << setprecision(prec) << endl;
	return 0;
}

(1).若要计算作业成绩的平均值,只需要如下:


double sum=0;
int count=0;
double x;
while(cin>>x&&x!=101){
sum+=x;
count++}//当x输入101时跳出循环。作业成绩的平均值为sum/count.

(2).计算中值时,使用的向量函数vector

vector<double> homework,意为创建一个名为homework的向量,用来存储double类型的数值。

homework.push_back(x)意为将x加进这个容器的末位。

typedef a b,意为用名称b替代名称a。因为代码中vector<double>::type_size太长了,所以用vcsize替代。

sort(homework.begin(),homework.end())意为对homework容器中的数从头到尾进行非递减排序。sort是algorithm库中的函数,意为排列。

2.作业完成情况。

本章作业,3-1没有太理解题目的意思。完成了3-2到3-5的编写。

其中3-2从思路上一开始想复杂了,只需要一个向量,找出三个位置(即三段长度),把向量分成长度相等的四段,用sort排序后依次输出就好了。

3-3是一个难题,没能独立完成。借鉴(copy)了别人的代码。其中对输入的单词进行分类与计数的嵌套循环写的尤其好。具有学习价值。特此贴出代码。

//3-3 编写一个程序来报告它的输入中每个不同单词出现的次数
#include<algorithm>
#include<iostream>
#include<vector>
#include<string>

int p33() {
	using namespace std;
	vector<string> words;
	vector<int> counts;//生成容器counts以
	typedef vector<string>::size_type vec_sz;

	cout << "enter the words: ";
	string str;

	while (cin >> str)
	{
		if (str == "end")
			break;//当输入end时跳出循环。

		//以下循环的思路是:
		//将输入的单词按类区分,每一个单词为一类,每输入一个单词,就与已存入向量中的每一类进行比对.
		//如果是新词就开始新的计数,如果是出现过的词就在那一类词的计数上加1.
		
		bool found = false;//bool类型,false意为 没有找到新词!

		for (vec_sz i = 0; i < words.size(); ++i) {
			if (str == words[i]/*此条件为真时,代表没有输入新的词。*/) {
				++counts[i];
				found = true;
				cout <<"i is "<< i << ".";
				cout << "wordsize is " << words.size()<<".";//让found=true,这样!found 就是假,就是没有找到新词,就不会把输入的词压进向量里了。
			}
		}//为什么第二次循环后i还是0??





		//第一次输入str时,因为words中不存在内容,因此for循环条件不满足,不会执行循环。当第一个str被存入words,使words.size()=1,此时才会执行循环。

		if (!found/*意为 找到新词了!*/) {
			words.push_back(str);
			counts.push_back(1);
			cout << "压进新词" << str << ".";
		}//bool类型在这里的作用:判断是否找到了新词。
		/*这一段写的真是绝妙!周密,完美的实现了单词之间的比较!并对出现次数进行了计数!*/

	}
	for (vec_sz i = 0; i < words.size(); ++i) {
		cout << words[i] << " appears " << counts[i] << " times" << endl;
	}

	return 0;
}

首先这里采用了嵌套循环,一个大的while循环中,嵌套了一个循环跳出条件、两个for循环和一个if循环。当输入第一个str时,通过定义bool类型变量found,表示是否找到新的单词。如found值为false,则没有找到新词;如为true,则找到了新词。

通过if(!found)循环,在!found为真时,意为找到新词,执行语句块,将新词压进向量words中,并在向量counts中进行一次从1开始的新的计数。

这个bool的用法第一次接触,整体循环的构建思路也很不错,他是将输入单词按是否相同分为n类,比如输入a b c,则words中就会出现3类数,a b c。而每输入一次都会通过for(vc_sz i=0;i<words.size;i++)来与之前的每一个数进行对比。这里需要注意的点是,每当一个新的str被输入进来,for循环中的i都会进行一次初始化,从而实现了让新输入的str与words中已有的每一个单词进行比对。

3-4 编写一个程序来报告它的输入中最长以及最短的字符串的长度

做这道题时,首先我要定义4个东西,“最长的单词”、“最短的单词”、“最长单词的长度”、“最短单词的长度”。这里体现出编写程序与我们正常思考的一个不同点,在程序编写时,通常要先把概念定义出来,再将值赋予他。

这道题的程序中还有一个点,在对输入的词进行x.size的判断,如果输入词>=最长单词的长度,那么就让他成为新的最长单词,让他的长度成为新的最长长度。但进行最短词的判断时,需要多加一个条件shortest==0||x.size()<=shortest_size。shortest==0这个条件是为了给shortest_size也存入一个值。因为shortest_size的初始值为0,而x.size()是不可能小于0的。只有再加上这个条件之后,才可以让shortest_size的值等于第一个输入字符串的长度。从而开始比较。

3-5 编写一个程序来同时跟踪n个同学的成绩,要求程序能够保持两个向量的同步:
//第一个应保存学生的姓名;第二个保存总成绩,这个总成绩能根据读到的输入来计算。
//读者应当假定家庭作业成绩的个数是固定的。

这道题可能是本章作业里面思路最简单的一道题。但在写程序时仍有一些问题。

我需要创建两个向量namelist和gradelist来分别存储学生的姓名和他们的总成绩,做到两个向量中的值对应输出并不难。只需要用数组就可以做到。但编写程序时,需要注意哪些东西在循环体内,哪些在循环体外。报错就是因为我一开始将创建向量的语句写在了循环体里,导致每次循环都要重新创建一个向量。。

for (int i = 1; i < n; i++) {
	cout << n << "位同学你们好,请第" << i << "位同学输入姓名:";

	cin >> name;
	namelist.push_back(name);//写什么循环呀,直接进就完事了。因为这里不需要while来进行多个name的读入,一次for循环里只读入一次就ok

	cout << "你好!" << namelist[i - 1] << "同学。" << endl;

同时还要注意,计数这里i是从1开始计数的,所以在使用数组时要用[i-1]。

3.总结

本章的新的点主要在于向量的概念,bool值的使用,以及对for、while、if循环的进一步理解。需要注意编程时的思路和编写细节,不要钻牛角尖。

继续加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值