一 目的
利用所学知识,编写出可以解决从自动售货机出购买巧克力时,已知1美元可以购得一块巧克力。如果我们有n美元,且设置m张优惠券可以兑换一块巧克力,那么最多能够得到多少块巧克力,其中包括优惠券换到的巧克力,以及还有多少张富余的优惠券这一问题,针对这个问题写一个递归解决方案,从用户那里接受购买巧克力所花的美元数,然后输出花完这些钱后所得的巧克力块数,并尽量多换优惠券。编写的递归函数将基于所得到的优惠券的数量。最后将从键盘上键入的内容和输出数据保存到outfile.txt文件夹中。
二 需求分析
1、输入数据
(1)输入你所拥有的美元金额n;
(2)输入兑换一块巧克力需要的优惠券数量;
(3)输入巧克力的单价。
2、输出数据
(1)输出总共得到的巧克力数量;
(2)输出剩余的优惠券数量。
3、程序所能达到的功能
(1)使用菜单选择操作,提示用户进行相应操作;
(2)对从键盘上接受到的数据,以及运行得到的结果,要输出保存到outfile.txt文件中。
三 概要设计
1、思路
(1)得到的总巧克力的数量=用钱购买的巧克力数+优惠券兑换的巧克力数;
(2)剩余的优惠券数量=兑换巧克力所得到的优惠券+兑换巧克力剩余的优惠券;
(3)通过switch语句实现用户选择。
2、各函数的功能及数据的含义
(1)类Shop:
私有数据成员:
int money;//拥有的钱。
int number;//兑换一块巧克力需要的优惠券。
int k;//购买到的巧克力。
int t;//剩余的优惠券。
int m;//巧克力的单价。
int n;//现在拥有的优惠券数。
公有成员函数:
Shop();/*构造函数,初始化各变量的值。*/
int buy(int m,int n);/*求只用钱买到的巧克力数,其中m为拥有的钱,n为巧克力的单价,m/n即为只用钱买到的巧克力数。*/
int chang(int m, int n);/*求优惠券兑换的巧克力,m为用户现在拥有的优惠券数量,n为兑换一块巧克力需要的优惠券数量,判断用户兑换巧克力后的优惠券(m/n+m%n)是否小于n,若小于,则返回兑换的巧克力数为m/n;若大于n,则返回(chang((m/n+m%n),n)+m/n)。*/
int remain_coupons(int m,int n);/*求剩余的券,m为用户现在拥有的优惠券数量,n为兑换一块巧克力需要的优惠券数量,判断用户兑换巧克力后的优惠券(m/n+m%n)是否小于n,若小于,则返回此时剩余的优惠券数量(m/n+m%n);若大于n,则返回(remain_coupons((m/n+m%n),n))。*/
void input();/*输入,提示用户输入数据。*/
void output();/*输出,调用chang()和remain_coupons()函数分别计算总共得到的巧克力和剩余的优惠券数量。*/
void choose();/*设置界面和购买选项。*/
/*因成员变量为私有,外部访问需要通过函数来访问。*/
int getk();/*获取总共得到的巧克力k的值。*/
int gett();/*获取剩余优惠券t的值。*/
int getmoney();/*获取用户拥有的钱money的值。*/
int getnumber();/*获取兑换一块巧克力需要的优惠券数量number的值。*/
int getm();/*获取巧克力的单价m的值。*/
(2)main函数
①定义类Shop的对象chocolate,并调用其成员函数。
②使用switch语句,实现用户的选择。
③使用文件流类,把把从键盘上接受到的数据,以及运行得到的结果等写入到文件outfile.txt中。
四 详细设计
1、流程图
2、伪代码
Begin
创建类Shop对象a;
定义整形变量money;
定义整形变量number;
调用a.choose(),输出选项界面;
定义文件流对象fout;
定义字符型变量ch;
while(输入ch的值)
switch(ch)
case'a';//用户输入a,进入购买选项
调用a.input(),输入money,number;
调用a.output();
调用change(),传入参数m,n;
if((m/n+m%n)<n);//判断优惠券是否足够
返回 m/n;
else
return change(m/n+m%n,n)+m/n;
调用remain_coupons();
if((m/n+m%n)<n);//判断优惠券是否足够
返回 m/n+m%n;
else
return remain_coupons(m/n+m%n,n);
打开输出文件,将文本信息输入文本文档;
关闭输出文件;
break;
case'b';//用户输入b,退出购买选项
输出退出提示;
打开输出文件,将文本信息输入文本文档;
关闭输出文件;
break;
default
输出提示,要求重新输入;
打开输出文件,将文本信息输入文本文档;
关闭输出文件;
break;
end;
五 调试分析
1、调试环境:系统:Window10 编译器:QT Creator4.4.1。
2、问题
(1)界面不友好。
1)错误分析:注重程序的可视化以及可操作性,使用户能方便操作,读懂屏幕输出的内容。
2)问题解决:添加空格和分割线等来设计界面。
(2)输入除a和b以外的字符出现错误。
1)错误分析:switch语句中未考虑除a和b以外的情形。
2)问题解决:在switch语句中加default,提示用户输入其他的字符时重新输入a或者b。
六 测试结果
1、操作界面
运行程序,输入c,提示重新输入;输入a,进入购买选项,输入美元数12,兑换一块巧克力需要的优惠券2,巧克力单价1,按回车显示结果;输入b,购买结束。
2、文本保存结果
打开outfile.txt文件,查看文本结果。
3、多组数据测试结果
进行7组测试,绘制表格。
拥有的美元金额 | 兑换一块巧克力需要的优惠券 | 巧克力的单价 | 总共得到的巧克力数 | 剩余的优惠券数 | |
1 | 10 | 2 | 1 | 19 | 1 |
2 | 12 | 3 | 1 | 17 | 2 |
3 | 14 | 3 | 1 | 20 | 2 |
4 | 16 | 2 | 1 | 31 | 1 |
5 | 18 | 4 | 1 | 23 | 3 |
6 | 20 | 6 | 1 | 23 | 5 |
7 | 22 | 2 | 1 | 43 | 1 |
七 用户使用说明
1
、操作步骤(1)打开程序并点击运行程序的按钮,进入购买巧克力的程序。
(2)界面出现购买规则和购买选项。
(3)输入相应的按钮进行选择。
(4)输入a,按回车键,进行购买选项,出现提示语句"请问你有多少钱:"。
(5)在后面输入数据,如12,按回车键,出现提示语句"多少优惠券兑换一块巧克力" 。
(6)在后面输入数据,如2,按回车键,出现提示语句"巧克力的单价"。
(7)在后面输入数据,如1,按回车键,显示购买结果。
(8)再次输入a,继续进行购买。
(9)输入b,提示结束购买,按回车键退出。
(10)输入b,按回车键,显示购买结束,按回车退出。
- 输入a和b以为的字符时,如1,按回车,提示"请输入a或者b"。
2.查看文本文件,打开对应文件夹里的outfile.txt进行查看。
八 源程序
shop.h文件
#ifndef SHOP_H
#define SHOP_H
class Shop
{
public:
Shop();
int buy(int m,int n);//只用钱买到的巧克力数
int chang(int m, int n);//兑换的巧克力
int remain_coupons(int m,int n);//剩余的券
void input();//输入
void output();//输出
void choose();//购买选项
int getk();//获取k的值
int gett();//获取t的值
int getmoney();//获取money的值
int getnumber();//获取number的值
int getm();//获取m的值
private:
int money;//拥有的钱
int number;//兑换一块巧克力需要的优惠券
int k;//购买到的巧克力
int t;//剩余的优惠券
int m;//巧克力的单价
int q;//只用钱买到的巧克力数
int p;//优惠券兑换的巧克力数
int n;//现在拥有的优惠券数
};
#endif // SHOP_H
shop.cpp文件
#include "shop.h"
#include<iostream>
#include<fstream>
using namespace std;
Shop::Shop()
{
money=0;
number=0;
k=0;
t=0;
m=1;
q=0;
p=0;
n=0;
}
//求只用钱买到的巧克力数量,m代表你有的美元,n代表巧克力单价
int Shop::buy(int m, int n)
{
int k;
k=m/n;
return k;
}
//运用递归函数求优惠券兑换的巧克力
int Shop::chang(int m, int n)
{
if((m/n + m%n) < n){
return m/n;
}
else{
return (chang((m/n + m%n),n) + m/n);
}
}
//运用递归函数求剩余的优惠券
int Shop::remain_coupons(int m, int n)
{
if((m/n+m%n)<n){
return (m/n+m%n);
}
else {
return (remain_coupons((m/n+m%n),n));
}
}
void Shop::input()
{
cout<<" 请问你有多少钱:";
cin>>money;
cout<<" ---------------------"<<endl;
cout<<" 多少优惠券兑换一块巧克力:";
cin>>number;
cout<<" ---------------------"<<endl;
cout<<" 巧克力的单价:";
cin>>m;
cout<<" ---------------------"<<endl;
}
void Shop::output()
{
q=buy(money,m);//只用钱买到的巧克力数
n=q;//最开始拥有的优惠券
p=chang(n,number);
k=q+p;
t=remain_coupons(n,number);
cout<<" 你总共能买到的巧克力数量是"<<k<<endl;
cout<<" 你还剩下的优惠券的数量是"<<t<<endl;
cout<<" -----------------------"<<endl;
cout<<" 继续进行购买请按a"<<endl;
cout<<" 退出请按b"<<endl;
cout<<" -----------------------"<<endl;
cout<<" ";//设置后面输入选项的位置
}
void Shop::choose()
{
cout<<endl;
cout<<endl;
cout<<" ____________________________________________"<<endl;
cout<<" |------------------商店--------------------|"<<endl;
cout<<" |------------------------------------------|"<<endl;
cout<<" |---------本店购买巧克力,一美元一块-------|"<<endl;
cout<<" |---------且可以用优惠券兑换巧克力---------|"<<endl;
cout<<" | |"<<endl;
cout<<" |请选择:----------------------------------|"<<endl;
cout<<" |----a.购买巧克力--------------------------|"<<endl;
cout<<" |----b.退出购买----------------------------|"<<endl;
cout<<" | |"<<endl;
cout<<" | 请输入相应的按键进行选择 |"<<endl;
cout<<" |__________________________________________|"<<endl;
}
int Shop::getk()
{
int m;
m=k;
return m;
}
int Shop::gett()
{
int n;
n=t;
return n;
}
int Shop::getmoney()
{
int a;
a=money;
return a;
}
int Shop::getnumber()
{
int b;
b=number;
return b;
}
int Shop::getm()
{
int c;
c=m;
return c;
}
main.cpp文件
#include <iostream>
#include<fstream>
#include "shop.h"
using namespace std;
int main()
{
Shop chocolate;
chocolate.choose();
ofstream fout;
char ch;
//设计输入选项按键位置
cout<<endl;
cout<<" ";
while(cin>>ch){
switch (ch) {
case 'a':
chocolate.input();//调用输入函数
chocolate.output();//将结果打印在屏幕
//将内容写进文档
fout.open("E:\outfile.txt",ios::app);
if(!fout){
cout << "无法打开文件!!!"<<endl;
return 1;
}
fout <<ch<<endl;
fout<<" 请问你有多少钱:"<<chocolate.getmoney()<<endl;
fout<<" ---------------------"<<endl;
fout<<" 多少优惠券兑换一块巧克力:"<<chocolate.getnumber()<<endl;
fout<<" ---------------------"<<endl;
fout<<" 巧克力单价:"<<chocolate.getm()<<endl;
fout<<" ---------------------"<<endl;
fout<<" 你总共能买到的巧克力数量是"<<chocolate.getk()<<endl;
fout<<" 你还剩下的优惠券的数量是"<<chocolate.gett()<<endl;
fout<<" -----------------------"<<endl;
fout<<" 继续进行购买请按a"<<endl;
fout<<" 退出请按b"<<endl;
fout<<" -----------------------"<<endl;
fout.close();
break;
case 'b':
cout<<" 购买结束,按回车退出"<<endl;
cout<<" -----------------------"<<endl;
cout<<" ";//设置后面输入选项的位置
fout.open("E:\outfile.txt",ios::app);
if(!fout){
cout << "无法打开文件!!!"<<endl;
return 1;
}
fout<<ch<<endl;
fout<<" 购买结束,按回车退出"<<endl;
fout<<" -----------------------"<<endl;
fout.close();
exit(0);
default:
cout<<" 请输入a或者b"<<endl;
cout<<" -----------------------"<<endl;
cout<<" ";//设置后面输入选项的位置
fout.open("E:\outfile.txt",ios::app);
if(!fout){
cout << "无法打开文件!!!"<<endl;
return 1;
}
fout<<ch<<endl;
fout<<" 请输入a或者b"<<endl;
fout<<" -----------------------"<<endl;
fout.close();
break;
}
}
return 0;
}