关于 C++ Primer Exercise 1.23 的思考(包括 Exercise 2.41)

C++ Primer Exercise 1.23 (英文版P24)本来是一个简单的Sales_item小程序,但是我发现如果输入时是一行一行打进去的而非复制进入界面的(可能复制就不会出什么问题吧),就会在输入新的ISBN后立刻输出之前一个ISBN的相关信息,因而影响程序效果(例如第2个展示程序第101行)。所以我做出了一定的修改。

对于使用vector的三种方案,均以Exercise 2.41(1.5.2)为案例。

使用array(数组)

其实用数组并不好,因为我们并不知道ISBN的数量,应该使用vector。但这是还没学到后面的时候做的,以前听说有数组,于是就这样操作了。(之后提供三种用vector解决的方案)

#include <iostream>
#include "Sales_item.h"
using namespace std;

int main()
{
	Sales_item item, init; //'init' refers to 'initial'
	int s = 1;
	int t = 0;
	int sum[1000] ;
	string name[1000];
	//This means there should be no more than 1000 ISBN numbers.
	for (int i = 0; i <= 999; i++)
		sum[i] = 0;
	cout << "Please enter control-z when finishing inputting information." << endl;
	cin >> init;
	while (cin >> item)
	{
		if (item.isbn() == init.isbn())
			s++;
		else
		{
			sum[t] = s; //store occurring times in sum[1000]
			name[t] = init.isbn(); //store ISBN in name[1000]
			s = 1;
			t++;
			init = item;
		}
	}
	for (int j = 0; j < t; j++)
	{
		if (sum[j] != 1)
			cout << name[j] << " occurs " << sum[j] << " times" << endl;
		else cout << name[j] << " occurs 1 time" << endl;
	}
	if (s != 1)
		cout << init.isbn() << " occurs " << s << " times" << endl;
	else cout << init.isbn() << " occurs 1 time" << endl;
	cout << "@Teddy van Jerry" << endl;
	return 0;
}

/*
USED FOR TEST:
Example 1:
0-201-78345-1 2 3
0-201-78345-1 2 4
0-201-78345-1 3 4
0-201-78345-2 3 4
0-201-78345-2 4 3
0-201-78345-3 3 4
0-201-78345-3 4 5
0-201-78345-4 1 3
0-201-78345-5 1 2
Result:
0-201-78345-1 occurs 3 times
0-201-78345-2 occurs 2 times
0-201-78345-3 occurs 2 times
0-201-78345-4 occurs 1 time
0-201-78345-5 occurs 1 time
@Teddy van Jerry

Example 2:
0-201-78345-1 2 3
Result:
0-201-78345-1 occurs 1 time
@Teddy van Jerry

Example 3:
0-201-78345-1 2 3
0-201-78345-2 3 4
Result:
0-201-78345-1 occurs 1 time
0-201-78345-2 occurs 1 time
@Teddy van Jerry

Example 4:
0-201-78345-1 2 3
0-201-78345-1 2 4
0-201-78345-1 3 4
0-201-78345-2 3 4
0-201-78345-2 4 3
0-201-78345-3 3 4
0-201-78345-3 4 5
0-201-78345-4 1 3
0-201-78345-5 1 2
0-201-78345-5 1 2
Result:
0-201-78345-1 occurs 3 times
0-201-78345-2 occurs 2 times
0-201-78345-3 occurs 2 times
0-201-78345-4 occurs 1 time
0-201-78345-5 occurs 2 times
@Teddy van Jerry

ALL RIGHTS RESERVED 2020(C)Teddy van Jerry

*/

此处用了数组暂时存储信息,最后再输出。(默认ISBN数应该不会超过1000)
此外还有次数time是否要复数s,要对init.isbn()的值是否为1判断。这也是一个小细节。

在Exercise 2.41(1.5.2)中同样有类似的问题,这次确定复制进去仍然会出现一下程序101行的情况。

#include <iostream>
#include <string>
using namespace std;

int main()
{
	//define class Sales_data
	struct Sales_data {
		string bookNo;
		unsigned units_sold = 0;
		double revenue = 0.0;
	}data, init;
	string name[1000];
	unsigned sum[1000];
	double price = 0.0;
	int s = 1;
	int t = 0;
	for (int i = 0; i <= 999; i++)
		sum[i] = 0;
	cout << "Please enter control-z when finishing inputting information." << endl;
	//input
	cin >> init.bookNo >> init.units_sold >> price;
	while (cin >> data.bookNo >> data.units_sold >> price)
	{
		if (data.bookNo != init.bookNo)
		{
			name[t] = init.bookNo; //store ISBN(i.e. bookNo) in string[1000]
			sum[t] = s; //store occurring times in sum[1000]
			++t;
			s = 1;
			init = data;
		}
		else ++s; //count
	}
	//output
	for (int i = 0; (i <= 999) && sum[i] != 0; i++)
	{
        if (sum[i] == 1) cout << name[i] << " occurs 1 time" << endl;
	    else cout << name[i] << " occurs " << sum[i] << " times" << endl;
	}
	//Don't forget the last bookNo!
	if (s == 1) cout << data.bookNo << " occurs 1 time" << endl;
	else cout << data.bookNo << " occurs " << s << " times" << endl;
	cout<< "@Teddy van Jerry" << endl;
	return 0;
}

/*
USED FOR TEST:
Example 1:
0-201-78345-1 2 3
0-201-78345-1 2 4
0-201-78345-1 3 4
0-201-78345-2 3 4
0-201-78345-2 4 3
0-201-78345-3 3 4
0-201-78345-3 4 5
0-201-78345-4 1 3
0-201-78345-5 1 2
Result:
0-201-78345-1 occurs 3 times
0-201-78345-2 occurs 2 times
0-201-78345-3 occurs 2 times
0-201-78345-4 occurs 1 time
0-201-78345-5 occurs 1 time
@Teddy van Jerry

Example 2:
0-201-78345-1 2 3
Result:
0-201-78345-1 occurs 1 time
@Teddy van Jerry

Example 3:
0-201-78345-1 2 3
0-201-78345-2 3 4
Result:
0-201-78345-1 occurs 1 time
0-201-78345-2 occurs 1 time
@Teddy van Jerry

Example 4:
0-201-78345-1 2 3
0-201-78345-1 2 4
0-201-78345-1 3 4
0-201-78345-2 3 4
0-201-78345-2 4 3
0-201-78345-3 3 4
0-201-78345-3 4 5
0-201-78345-4 1 3
0-201-78345-5 1 2
0-201-78345-5 1 2
Result:
0-201-78345-1 occurs 3 times
0-201-78345-2 occurs 2 times
0-201-78345-3 occurs 2 times
0-201-78345-4 occurs 1 time
0-201-78345-5 occurs 2 times
@Teddy van Jerry

Unpleasant mixture of input and output of Example 4:
Please enter control-z when finishing inputting information.
0-201-78345-1 2 3
0-201-78345-1 2 4
0-201-78345-1 3 4
0-201-78345-2 3 4
0-201-78345-1 occurs 3 times
0-201-78345-2 4 3
0-201-78345-3 3 4
0-201-78345-2 occurs 2 times
0-201-78345-3 4 5
0-201-78345-4 1 3
0-201-78345-3 occurs 2 times
0-201-78345-5 1 2
0-201-78345-4 occurs 1 time
0-201-78345-5 1 2
^Z
0-201-78345-5 occurs 2 times
@Teddy van Jerry

ALL RIGHTS RESERVED 2020(C)Teddy van Jerry

*/

在Exercise 2.41(1.6)中可以这样修改:

#include <iostream>
#include <string>
using namespace std;

int main()
{
	//define class Sales_data
	struct Sales_data {
		string bookNo;
		unsigned units_sold = 0;
		double revenue = 0.0;
	}total, trans;
	double price;
	unsigned t = 0;
	double revenue_print[1000];
	unsigned units_sold_print[1000];
	string bookNo_print[1000];
	for (int i = 0; i <= 999; i++)
		units_sold_print[i] = 0;
	cout << "Please enter control-z when finishing inputting information." << endl;
	//input
	if (cin >> total.bookNo >> total.units_sold >> price)
	{
		total.revenue = price * total.units_sold;
		while (cin >> trans.bookNo >> trans.units_sold >> price)
		{
			if (total.bookNo == trans.bookNo)
			{
				total.units_sold += trans.units_sold;
				total.revenue += price * trans.units_sold;
			}
			else
			{
				//store information
				bookNo_print[t] = total.bookNo;
				units_sold_print[t] = total.units_sold;
				revenue_print[t] = total.revenue;
				//reset for next ISBN
				total.bookNo = trans.bookNo;
				total.units_sold = trans.units_sold;
				total.revenue = price * trans.units_sold;
				t++;
			}
		}
		//output
		for (int i = 0; (i <= 999) && units_sold_print[i] != 0; i++)
			cout << bookNo_print[i] << " " << units_sold_print[i] << " " << revenue_print[i] << " " << revenue_print[i] / units_sold_print[i] << endl;
		//Don't forget the last book!
		cout << trans.bookNo << " " << total.units_sold << " " << total.revenue << " " << total.revenue / total.units_sold << endl;
	}
	else
	{
		cerr << "no data?!" << endl;
		return -1;
	}
	cout << "@Teddy van Jerry" << endl;
	return 0;
}

/*
USED FOR TEST:
Example 1:
0-201-78345-X 3 20.00
0-201-78345-X 2 25.00
Result:
0-201-78345-X 5 110 22
@Teddy van Jerry

Example 2:
0-201-78345-X 3 20.00
0-201-78345-X 2 25.00
0-201-78345-Y 3 20.00
0-201-78345-Y 2 25.00
Result:
0-201-78345-X 5 110 22
0-201-78345-Y 5 110 22
@Teddy van Jerry

ALL RIGHTS RESERVED 2020(C)Teddy van Jerry

*/

使用vector和[ ]operator

这样和数组的方法比较接近:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
	//define class Sales_data
	struct Sales_data {
		string bookNo;
		unsigned units_sold = 0;
		double revenue = 0.0;
	}data, init;
	vector<string> name;
	vector<unsigned> sum;
	double price = 0.0;
	int s = 1;
	int t = 0;
	cout << "Please enter control-z when finishing inputting information." << endl;
	//input
	cin >> init.bookNo >> init.units_sold >> price;
	while (cin >> data.bookNo >> data.units_sold >> price)
	{
		if (data.bookNo != init.bookNo)
		{
			name.push_back(init.bookNo); //store ISBN(i.e. bookNo) in name
			sum.push_back(s); //store occurring times in sum
			++t;
			s = 1;
			init = data;
		}
		else ++s; //count
	}
	//output
	for (int i = 0; i!=sum.size(); i++)
	{
		if (sum[i] == 1) cout << name[i] << " occurs 1 time" << endl;
		else cout << name[i] << " occurs " << sum[i] << " times" << endl;
	}
	//Don't forget the last bookNo!
	if (s == 1) cout << data.bookNo << " occurs 1 time" << endl;
	else cout << data.bookNo << " occurs " << s << " times" << endl;
	cout << "@Teddy van Jerry" << endl;
	return 0;
}

使用vector和range for

这个有些失败,好像 range for 中不得不使用 iterator。但 range for 在有些场合还是非常简洁的。

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
	//define class Sales_data
	struct Sales_data {
		string bookNo;
		unsigned units_sold = 0;
		double revenue = 0.0;
	}data, init;
	vector<string> name;
	vector<unsigned> sum;
	double price = 0.0;
	int s = 1;
	int t = 0;
	cout << "Please enter control-z when finishing inputting information." << endl;
	//input
	cin >> init.bookNo >> init.units_sold >> price;
	while (cin >> data.bookNo >> data.units_sold >> price)
	{
		if (data.bookNo != init.bookNo)
		{
			name.push_back(init.bookNo); //store ISBN(i.e. bookNo) in name
			sum.push_back(s); //store occurring times in sum
			++t;
			s = 1;
			init = data;
		}
		else ++s; //count
	}
	//Don't forget the last bookNo!
	name.push_back(data.bookNo);
	sum.push_back(s);
	//output
	auto name_print = name.begin();
	for (auto c:sum)
	{
		if (c == 1) cout << *name_print << " occurs 1 time" << endl;
		else cout << *name_print << " occurs " << c << " times" << endl;
		++name_print;
	}
	return 0;
}

使用vector和iterator

这个使用起来就比前面那个自然很多:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
	//define class Sales_data
	struct Sales_data {
		string bookNo;
		unsigned units_sold = 0;
		double revenue = 0.0;
	}data, init;
	vector<string> name;
	vector<unsigned> sum;
	double price = 0.0;
	int s = 1;
	int t = 0;
	cout << "Please enter control-z when finishing inputting information." << endl;
	//input
	cin >> init.bookNo >> init.units_sold >> price;
	while (cin >> data.bookNo >> data.units_sold >> price)
	{
		if (data.bookNo != init.bookNo)
		{
			name.push_back(init.bookNo); //store ISBN(i.e. bookNo) in name
			sum.push_back(s); //store occurring times in sum
			++t;
			s = 1;
			init = data;
		}
		else ++s; //count
	}
	//Don't forget the last bookNo!
	name.push_back(data.bookNo);
	sum.push_back(s);
	//output
	auto name_print = name.begin();
	auto sum_print = sum.begin();
	while(name_print != name.end())
	{
		if (*sum_print == 1) cout << *name_print << " occurs 1 time" << endl;
		else cout << *name_print << " occurs " << *sum_print << " times" << endl;
		++name_print;
		++sum_print;
	}
	return 0;
}

See also

Teddy van Jerry 的导航页
【C++ Primer(5th Edition) Exercise】练习程序 - Chapter1(第一章)
【C++ Primer(5th Edition) Exercise】练习程序 - Chapter2(第二章)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值