C++第二次作业(Accelerated C++第四章)



(一)最长的、最短的字符串

编写一个程序用于报告它的输入中最长以及最短的字符串的长度

/*
3-4
编写一个程序用于报告它的输入中最长以及最短的字符串的长度
*/
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
using namespace std;
int main()
{
	string str;
	cout << "please input a string by the end of EOF  " << endl;
	cin >> str;
	int maxx = str.size();
	int minn = str.size();
	string str1 = str, str2 = str;
	while (cin >> str)
	{
		if (str.size() > maxx)
			maxx = str.size(), str2 = str;
		else if (str.size() < minn)
			minn = str.size(), str1 = str;
	}
	cout << "the smallest string is " << str1;
	cout << "  whose length is "<< minn << endl;
	cout << "the largest string is " << str2;
	cout << "  whose length is " << maxx << endl;

	system("pause");
	return 0;
}



(二)单词计数


P75
4-5
用一个函数读入单词放在向量中,
利用这个函数写一个程序计算输入的单词数和每个单词出现的次数

/*
P75
4-5
用一个函数读入单词放在向量中,
利用这个函数写一个程序计算输入的单词数和每个单词出现的次数
*/

#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
//http://bbs.csdn.net/topics/340078578

void getString(vector<string> &vec)
{
	string str;
	while (cin >> str)
	{
		vec.push_back(str);
	}
}

int main()
{
	string str;
	vector <string> vec;
	int cnt = 0;
	getString(vec);
	sort(vec.begin(), vec.end());
	vector<string>::iterator it = vec.begin();
	for (; it != vec.end();)
	{
		cnt = 1;
		str = *it++;
		while (str == *it)
		{
			it++;
			cnt++;
			if (it == vec.end())
				break;
		}
		cout << " 字符串为 " << str << "的次数为" << cnt << endl;
	}

	cout << endl << "最终输入个数为 " << vec.size() << endl;
	system("pause");
	return 0;
}



(三)计算平方

题意描述:

提示用户输入一个整数 I,编写一个程序来计算从1~I 的双精度浮点数(double)值的平方。程序的输出分为两列:第一列是double值,第二列是double值的平方。使用控制器来控制输出,让数值按左对齐排列起来。注意,程序应当有一定灵活性,当 I 增大时我们不需要修正setw的参数。

提示:可以先完成练习4-2,4-3以资借鉴。

 

//1-100整数值的平方 (4-2)

法一

#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <ios>
#include <iomanip>
#include <string>
using namespace std;
//1-100整数值的平方
int main()
{
	for (int i = 1; i <= 100; i++)
	{
		cout.width(4);
		cout << i;
		cout.width(8);
		cout << i*i;
		cout << endl;
		//cout << setw(4) << i << setw(8) << i*i << endl;
	}
	system("pause");
	return 0;
}

法二

int main()
{
	for (int i = 1; i <= 100; i++)
	{
		cout << setw(4) << i << setw(8) << i*i << endl;
	}
	system("pause");
	return 0;
}




//1-999整数值的平方,要求更有适应性,当改变最大值时,不用改参数 (4-3)

<div style="text-align: left;"><span style="font-family: Arial, Helvetica, sans-serif;">//1-999整数的平方,不能修改setw参数的值</span></div>#include <iostream>
#include <ios>
#include <cmath>
#include <iomanip>//setw
using namespace std;
const int maxn = 1000;
int getWidth(int n)
{
	return log10(n) + 1;
}
int main()
{
	for (int i = 1; i <= maxn; i++)
	{
		cout << setw(getWidth(maxn)) << i << setw(getWidth(maxn*maxn)+1) << i*i << endl;
	}
	system("pause");
	return 0;
}



补充:

1、setw(n)返回一个streamsize的值,如果把这个值用于输出流s,那么它的作用跟调用s.width(n)效果一样.

2、setw的头文件是<iomanip>



//最终--------计算double的平方

第二列的话,如果直接左对齐,因为中间没有分隔开,所以只能是与自己左边的数相差一个空格
所以还是要右对齐,但是他的间距要设置多少这里比较难想到。。。
getWidth(mm*mm)是最大那个的,所有数要跟他对齐,同时要结合这一行左边的数和右边的数,所以就有:
setw((getWidth(mm*mm)-getWidth(i)+getWidth(i*i) -1))


/*
输入一个数i
计算从1到i的double的平方
输出: 用控制器,左对齐
PS:   程序的灵活性,当i增大时不需修正setw的参数

可以先完成4-2   4-3作为借鉴
*/
//计算从1到I的双精度浮点数的平方
#include <iostream>
#include <ios>
#include <iomanip>
#include <string>

using namespace std;
int getWidth(double n) //求double型的长度
{
	return log10(n) + 1;
}
int main()
{
	cout << "请输入一个数i: ";
	double mm;
	cin >> mm;
	for (double i = 1; i <= mm; i++)
	{
		streamsize prec = cout.precision();//记录一开始的精度

		cout << setw(getWidth(mm)*(-1)) << i;
		//第一列直接左对齐就行了
		cout << setw((getWidth(mm*mm)-getWidth(i)+getWidth(i*i) -1)) << i*i;
		//第二列的话,如果直接左对齐,因为中间没有分隔开,所以只能是与自己左边的数相差一个空格
		//所以还是要右对齐,但是他的间距要设置多少这里比较难想到。。。
		//getWidth(mm*mm)是最大那个的,所有数要跟他对齐,同时要结合这一行左边的数和右边的数,所以就有:
		//setw((getWidth(mm*mm)-getWidth(i)+getWidth(i*i) -1))
		cout << endl;
	}
	system("pause");
	return 0;
}










(四)多个学生的成绩

题意描述:练习4-0,练习4-6。

也就是说,首先,务必看懂4.5节的程序,弄清楚每个函数的来龙去脉,作用何在。然后,将Student_info 结构体的定义改写为:

Student_info{string name, double finalGrade}

其中 finalGrade 代表最终成绩。根据这个变化,相应的修改4.5节的程序,完成同样的功能。




(这个写了好久啊、、、、一个多小时。。。。我要去吃饭了。。。2016/10/7/17:46)

第一个方案(没有改结构体前的)

引用三个头文件median.h; student_info.h; grade.h

(注意:#pragma once的作用是使得这个头文件只被编译一次,跟P69讲的那个差不多 )


//median.h

#pragma once
//median.h
/*
查找中值
不要用using namespace std;
因为在头文件中使用这个的话,引用这个头文件就默认也使用了这句话。
*/
#include <algorithm>
#include <stdexcept> //domain_error
#include <vector>
using std::sort;
using std::domain_error;
using std::vector;
//查找中值
double median(vector<double> vec)
{
	typedef vector<double>::size_type vec_sz;
	vec_sz size = vec.size();
	if (size == 0)
		throw domain_error("median of an empty vector");
	sort(vec.begin(), vec.end());
	vec_sz mid = size / 2;
	return size % 2 == 0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid];
}


//student_info.h

#pragma once
//student_info.h
#include <iostream>
#include <string>
#include <vector>
using std::vector;
using std::string;
struct student_info{
	string name;
	double midterm, final;
	vector<double>homework;
};
bool cmp(const student_info&, const student_info&);
std::istream& read(std::istream&, student_info&);
std::istream&read_hw(std::istream&, std::vector<double>&);
bool cmp(const student_info& x, const student_info& y)
{
	return x.name < y.name;
}

//从输入流将家庭作业的成绩读入到一个vector<double>中
//这里使用输入流而不直接使用cin的原因是让以后的输入流也可以用其他形式比如文本导入啊什么的...
std::istream& read(std::istream& is, student_info& s)
{
	is >> s.name >> s.midterm >> s.final;
	read_hw(is, s.homework);
	return is;
}

std::istream& read_hw(std::istream& in, vector<double>& hw)
{
	if (in)
	{
		hw.clear();
		double x;
		while (in >> x)
			hw.push_back(x);
		in.clear();//清除输入流中的错误信息
	}
	return in;
}


//grade.h

#pragma once
//grade.h
/*
编写一个头文件grade.h来声明不同的grade重载函数
注意:重载函数最好放到同一个文件里
	  而且,将这些重载函数的声明放在一起会让这些可供选择的函数更容易查找
*/
#include <vector>
#include "median.h"
#include "student_info.h"
using std::vector;
double grade(double, double, double);
double grade(double, double, const vector<double>&);
double grade(const student_info&);

//计算成绩
double grade(double midterm, double final, double homework)
{
	return 0.2*midterm + 0.4*final + 0.4*homework;
}

double grade(double midterm, double final, const vector<double>& hw)
{
	if (hw.size() == 0)
		throw domain_error("student has done no homework");
	return grade(midterm, final, median(hw));
}

double grade(const student_info& s)
{
	return grade(s.midterm, s.final, s.homework);
}


//主程序

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <istream>
#include <ios>
#include <iomanip>//setprecision,setw
#include "grade.h"
using std::cin;
using std::cout;
using std::domain_error;
using std::endl;
using std::max;
using std::setprecision;
using std::sort;
using std::streamsize;
using std::string;
using std::vector;
//using namespace std;
int main()
{
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
	vector<student_info> students;
	student_info record;
	string::size_type maxlen = 0;//最长姓名的长度

	while(read(cin,record))
	{
		maxlen = max(maxlen, record.name.size());
		students.push_back(record);
	}

	//按名字对学生进行排序
	sort(students.begin(), students.end(), cmp);

	//输出姓名和成绩
	for (vector<student_info>::size_type i = 0; i != students.size(); i++)
	{
		//输出姓名,将姓名填充至maxlen+1个字符的长度
		cout << students[i].name << string(maxlen + 1 - students.size(), ' ');
		//计算并输出成绩
		try {
			double final_grade = grade(students[i]);
			streamsize prec = cout.precision();
			cout << setprecision(3) << final_grade << setprecision(prec);
		}
		catch (domain_error e) {
			cout << e.what();//异常的话会输出刚才在median.h定义的那句话“median of an empty vector”
		}
		cout << endl;
	}

	fclose(stdin);
	fclose(stdout);
	system("pause");
	return 0;
}






(五)异常处理

题意描述:练习3-6

首先描述在你的系统在程序运行中出现除以0的情况时如何反应;然后在3.1节的程序中添加C++的异常处理,使得程序行为不依赖于系统如何对待除以0的情况,亦即你的程序不論在何種系統中運行當遇到除以0的情況都會以同樣的方式予以處理。



什么都不做,编译器显示  -nan(ind)

/*
直接除以0的反应,直接显示“被零除或对零求模”
在3.1节中添加异常处理
使得你的程序不论在何种系统中运行当遇到除以0的情况都会以同样的方式处理
*/
#include <iostream>
#include <algorithm>
#include <iomanip>//setw,setprecision
#include <ios>
#include <string>
#include <vector>
#include <stdexcept>//domain_error
using namespace std;

int main()
{
	// ask for and read the student's name
	cout << "Please enter your first name: ";
	string name;
	cin >> name;
	cout << "Hello, " << name << "!" << endl;

	// ask for and read the midterm and final grades
	cout << "Please enter your midterm and final exam grades: ";
	double midterm, final;
	cin >> midterm >> final;

	// ask for the homework grades
	cout << "Enter all your homework grades, "
		"followed by end-of-file: ";

	// the number and sum of grades read so far
	int count = 0;
	double sum = 0;

	// a variable into which to read
	double x;

	// invariant:
	//     we have read `count' grades so far, and
	//     `sum' is the sum of the first `count' grades
	while (cin >> x) {
		++count;
		sum += x;
	}

	// write the result
	try {
		streamsize prec = cout.precision();
		<span style="color:#ff6666;">if (count == 0)
			throw domain_error("错了,不能放0在分母\n");</span>
		cout << "Your final grade is " << setprecision(3)
			<< 0.2 * midterm + 0.4 * final + 0.4 * sum / count
			<< setprecision(prec) << endl;
	}
	<span style="color:#ff6666;">catch (domain_error e) {
		cout << e.what();
	}</span>
	//catch (domain_error) {
	//	cout << "除以0了,出错了" << endl;
	//}
	system("pause");
	return 0;
}


这样改,然后如果分母用0了,就是抛出异常,然后输出的话是throw domain_error("")里面写的字

<span style="color:#ff6666;">catch (domain_error e) {
		cout << e.what();
	}</span>
catch (domain_error) {
		cout << "除以0了,出错了" << endl;
	}
上面这两种用法都可以。

注意:要使用异常抛出需要添加头文件<stdexcept>



  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值