一、实验目的
l
进一步熟悉C++的标准输入、输出功能;
l
熟悉vector类型的使用;
l
进一步熟悉string类型的使用。
二、实验环境
P4 1.7G计算机一台,Windows XP操作系统,Microsoft
Visual C++ 2005编程环境。
三、实验内容及分析
(一)求四分位数
1. 题意描述:四分位数:将所有数值按大小顺序排列并分成四等份,处于三个分割点位置的数就是四分位数。最小的四分位数称为下四分位数,所有数值中,有四分之一小于下
四分位数,四分之三大于下四分位数。中点位置的四分位数就是中位数。最大的四分位数称为上四分位数,所有数值中,有四分之三小于上四分位数,四分之一大于
上四分位数。例如:数据
3 5 6(25%点)8 9(50%点)11 12(75%点)15 16
其中25%点的6和75%点的12分别称为下四分位数和上四分位数。
提示用户输入一系列的整数(不一定是有序的)然后输出这一系列数的上、下四分位数。
2. 问题分析与解决
因为数据并不一定是有序的,而处理数据得出这一系列数的上、下四分位数,需要保存这一系列数,所以选择使用vector容器,并用sort进行对其排序,最后求出其上、下四分位数并输出。
3. 调试、测试运行情况及结果分析
(1)
实验中碰到的问题及解决方法
不是很理解上、下四分位数的概念,解决方法:google搜索。
(2) 测试数据及运行结果
(3) 结果分析与结论
其实就是书上求中位数的套用。
(二)单词计数
1.
题意描述:练习4-5(输入以EOF标记结束)
Write a function that
reads words from an input stream and stores them in a vector. Use that function
both to write programs that count the number of words in the input, and to
count how many times each word occurred.
2.
问题分析与解决
由于题中要求用vector容器,所以不能简单运用map容器。据说string的find函数是一个简单的线性搜索,时间复杂度为O(n),我不希望每输入一个string都查找一次,因为这种算法的时间复杂度是O(n2)。
将所有的string一次读入,然后用sort函数对它进行排序,再现性扫描计算出各单词的数目。sort() runs
in O(N log(N)) time (average and worst case) which is faster than polynomial
time but slower than linear time。这种算法的时间复杂度也即是O(N log(N)),这当然不能和map的时间复杂度,以及它的空间复杂度相比。
查找第一个不同的string,用find_if,只要将要找的string赋值给全局变量,再通过全局变量传入Predicate _Pred函数,即可实现。计算个数只需要用指向第一个不同的string的const_iterator减去指向该查找的string的const_iterator即可。
3.
调试、测试运行情况及结果分析
(1)
实验中碰到的问题及解决方法
由于第一次自己写find_if函数的第三个参数Predicate _Pred,解决方法:查找MSDN临摹其中的例子。
(2) 测试数据及运行结果
(3) 结果分析与结论
用一个不恰当的数据结构会影响算法的时间复杂度和空间复杂度,要达到相同的效率,对应要付出很大的代价,一言以蔽之“程序=数据结构+算法”。
(三)最长的、最短的字符串
1.
题意描述:3-4(输入以EOF标记结束)
Write a program to report
the length of the longest and shortest string
in its input.
2.
问题分析与解决
只需要对输入的string对其长度进行排序,但要注意最长的和最短的不一定只有一个。
后来发现,这个算法的时间复杂度是O(N log(N)),但又O(N) 时间复杂度的算法,就改用类实现,好久没用类了,感觉挺“累”的。
首先,输入string(s)。及时更新当前最大长度和最小长度,判断当前输入的string有没有可能是最长的或最短的,没有可能则舍弃。
接着,就输出结果。第一步,判断是不是所有的string(s)都一样长,是则判断是不是只有一个string,是则输出;不是,则分别输出最短的string(s)和最长的string(s),同时区分它们的单复数。
3.
调试、测试运行情况及结果分析
(1)
实验中碰到的问题及解决方法
类不容易实现,解决方法:阅读书籍,并将其中一个元素全局话,虽然这样降低了类的封装,但我没有其他好方法实现。
vector<string>::reverse_iterator不容易求出其距第一个元素的距离,解决方法:调试,并分析,最后用该vector的size() - (返回的位置reverse_iterator- rBegin) - 1。
(2) 测试数据及运行结果
(3) 结果分析与结论
通过,求出最短和最长string的开始和结束位置,就可以得出,用户输入的是不是一个string,是不是所有长度都相等,最短的string是单数还是复数……
(四)多个学生的成绩
题意描述:练习4-0,练习4-6。
也就是说,首先,务必看懂4.5节的程序,弄清楚每个函数的来龙去脉,作用何在。然后,将Student_info 结构体的定义改写为:
Student_info{string name,
double finalGrade}
其中 finalGrade 代表最终成绩。根据这个变化,相应的修改4.5节的程序,完成同样的功能。
1.
问题分析与解决
就是要用指定的结构体改写程序,但仍然要实现相同的功能。
2.
调试、测试运行情况及结果分析
(1)
实验中碰到的问题及解决方法
出现error C2144: syntax error : 'double' should be preceded by ';'这个莫名其妙的问题,原因头文件的最后一个函数声明中少了’;’,解决问题:在该处加上分号。
出现error C2166: l-value specifies const object的错误,原因修改了Student_info中的finalGrade,解决方法:去掉函数声明和定义中const修饰符。
需要记录所有的
出现所有学生成绩都一致的情况,这显然不是作弊引起的。解决方法:创建 typedef vector<double>
score; vector<double> midterm, final; vector<score>homework;用于保存每个学生的期中、期末和平时作业成绩。
保存每个学生的期中、期末和平时作业成绩,造成影响:几乎无法对成绩按照学生姓名的顺序排序,因为它们是紧密结合的。总不能对sort函数说,你对学生姓名进行排序的时候顺便帮我把期中、期末和平时作业成绩顺便一起排了吧,于是对“程序=数据结构+算法”又有了一次贴身体会。解决方法:先计算所有学生的最终成绩,接着再排序,最后再输出。
但是后来又发现一个重大问题,抛出异常是在计算时,但是由于先计算在排序后输出,导致抛出的异常没人解决。解决方法:将学生姓名及计算结果在计算时存入vector<string> ret, 如出现异常就将学生姓名及异常存入ret。并用sstream中的stringstream设置精度为3将double存入string中。不过这样做的结果导致结构体的finalGrade成员没什么作用了。
(2) 测试数据及运行结果
(3) 结果分析与结论
解决问题的顺序也是关键的,改写别人的程序是不容易的,所以对面向对象的思想有了更大的期望。
文章评论(0条评论)
登录后参与讨论