您的位置:首页 > 其它

(iterator遍历并删除erase,函数指针)购物结算系统

2015-01-20 13:41 260 查看
描述: 1 总体说明

考生需要模拟实现一个简单的购物结算系统,实现挑选和删除商品、按照最佳优惠方案进行结算、查询购物车订单信息及购物卡余额和积分的功能。

系统初始化时购物卡中有3000元余额和150积分,可以输入命令来初始化系统。

1.1 购物活动细则

只要购物卡余额足够,可以进行多次购买,每次购买活动可以包含如下活动:

1、多次挑选商品,每次挑选形成购物车中的一条商品订单;

2、多次删除商品订单,每次只能删除一条订单;

结算的是当前购物车中所有订单,结算完成即本次购买活动结束,同时清空购物车并更新购物卡余额和积分;



1.2 商品优惠细则

购买商品时优惠方案分为单项优惠方案和总价优惠方案,在享受单项优惠的同时如满足一定条件可以再享受总价优惠。



各种商品的单项优惠方案列表:



商品序号
商品种类
单价(元)
单项优惠方案
积分积累方式
0
食品
10
无优惠
结算时消费金额每10元积1分,不足10元不积分
9折
每满100直减18
1
服装
120
无优惠
每满200直减40
2
书籍
30
无优惠
5折
单项优惠方案序号:

单项优惠方案序号
单项优惠方案
0
无优惠
1
打折
2
直减
1、在一次购买活动中,同种商品只能有一种单项优惠方案;总价优惠方案:在一次购买活动结算时,所有商品单项优惠后总消费金额大于等于500时,可以再使用“积分抵现”或“折上折”优惠:

(1) 积分抵现:1个积分抵1元现金,购物卡积分大于等于120只能使用120个积分,不足120,全部使用;

(2) 折上折:在单项商品优惠后总金额基础上,再打8折;

1.3 约束

* 商品价格最小单位到元,所有涉及价格计算中不足1元,向下取整,舍掉余数部分。例如:计算出的实际价格为563.9,则取整为563;

* 本次购买活动新增的积分不能在当次购买中使用;

* 购物卡余额和积分不能透支;

2 操作说明

命令字与第一个参数间使用一个空格分隔,多个参数间使用半角“-”分隔,参数间没有空格。考试系统会对输入命令格式进行处理,考生不需要关注输入命令格式的合法性,只需要实现命令处理函数。对于涉及多个参数的命令,多个参数同时出错的情况不作为考察点。

2.1 系统初始化

命令格式:r

功能说明:将购物卡金额和积分分别初始化为3000、150;

约束说明:系统在任意阶段均可执行r初始化系统;

输出说明:输出操作成功提示(执行完r命令后系统会自动输出操作结果,考生不需要再次调用输出函数),例:



命令
输出
r
S001
2.2 挑选商品

命令格式:o 商品序号-商品数量

功能说明:

(1) 每次挑选只能指定一种商品,且商品数量不超过100(0<每次挑选商品数量<=100),同一种商品可以多次挑选;

(2) 挑选成功则生成购物车中的一条商品订单,输出:“S002”;

(3) 如果输入的“商品序号”或“商品数量”参数不合法,输出“E002”。参数错误直接返回不再进行其他处理;

(4) 购物车中最多容纳5条商品订单,挑选时如果购物车已满,则挑选失败,输出“E003”;

(5) 在挑选商品阶段不校验购物卡余额是否足够;



约束说明:

(1) 系统在任意阶段都可以挑选商品;

(2) 购物车中的同一种商品的订单记录不合并;



输出说明:如果挑选成功,输出操作提示。例,挑选6本书籍:



命令
输出
o 2-6
S002
2.3 删除商品订单记录

命令格式:c 商品序号-商品数量

功能说明:

(1) 在结账前可以删除购物车中的订单以取消挑选,商品数量不超过100(0<每次删除商品数量<=100),每次只能删除一条,可以执行多次删除操作;

(2) 只能删除购物车中与删除命令输入的“商品序号”、“商品数量”完全匹配的订单记录;

(3) 如果输入的“商品序号”或“商品数量”参数不在系统允许的范围内,输出“E002”。参数错误直接返回不再进行其他处理;

(4) 如果购物车为空,输出“E005”;

(5) 如果购物车中不存在待删除订单,输出“E004”;

(6) 如果购物车中存在多条相同(“商品序号”和“商品数量”都相同)的订单记录,则只删除购物车中的一条记录;



输出说明:如果删除成功,输出操作提示。例,从购物车中删除6本书籍的订单记录:



命令
输出
c 2-6
S003
2.4 结算

命令格式:b

功能说明:

(1) 系统根据“商品优惠细则”自动调整商品的单项和总价优惠方案,使得用户消费金额最少。当两种总价优惠方案花费金额相同时,优选“折上折”。

(2) 如果购物车为空,输出“E005”;

(3) 如果购物卡余额或积分不足以购买购物车商品时,输出“E006”;



输出说明:如果结算成功,输出结果中包含本次购买所需的消费金额和消费积分以及新增的积分。例:



命令
输出
说明
b
800

0

80
消费金额

消费积分

新增积分
2.5 查询

命令格式:l 查询类别

功能说明:

(1) 查询购物卡信息(余额、积分)和购物车中的订单信息;

(2) 查询类别:0表示购物卡信息查询,1表示购物车订单查询;如果“查询类别参数错误,输出“E002”。“查询类别”参数错误时,不进行下面的处理。



输出说明:

(1) “查询类别”为0时,输出购物卡余额和积分,例:



命令
输出
说明
l 0
3000

150
余额

积分
(2) “查询类别”为1时,输出购物车中的订单数以及每种商品的总数,例:



命令
输出
说明
l 1
4

2

1

10
订单数

食品

服装

书籍
2.6结束

命令格式:e 系统结束 功能说明:一次购物完成,系统结束。


输入:依照说明中的命令码格式输入命令


输出:输出执行结果

输出:输出执行结果


样例输入:
r
o 1-100
e

样例输出:
S001
S002

答案提示:3 附录:

3.1 命令汇总

命令
命令格式
示例
说明
r
r
r
Reset,初始化购物卡金额和积分
o
o 商品序号-商品数量
o 0-2
Order,挑选一种商品
c
c 商品序号-商品数量
c 2-1
Cancel,删除购物车中的单条商品订单记录
b
b
b
Buy,按照系统生成的最佳优惠方案扣除购物卡金额并更新购物卡积分
l
l 查询类别
l 0
List,购物卡信息查询或购物车订单查询
e
e
e
系统结束
3.2 返回码汇总

返回码描述
含义
说明
E001
非法命令
考试系统使用,考生不用关注
E002
参数错误
“商品序号”参数不合法;

“商品数量”参数不合法;

“查询类别”参数不合法;
E003
购物车已满
购物车中订单数量已经达到5条,不能再挑选商品
E004
待删除的订单不存在
在购物车中没有找到要删除的商品订单
E005
购物车中没有商品订单
删除商品订单或结算时,购物车中没有订单
E006
购物卡余额或积分不足
购物卡余额或积分不足
S001
初始化成功
初始化操作成功,考试系统使用,考生不用关注
S002
订单已经加入到购物车
挑选商品操作成功
S003
订单已从购物车中删除
从购物车中删除商品订单成功
3.3 基本用例

编号
测试步骤
预期输出
1
r

o 1-100

o 2-50

o 0-1

o 1-100

o 2-50

e
S001

S002

S002

S002

S002

S002
2
r

o 0-101

e
S001

E002
3
r

o 1-100

o 2-50

o 0-1

o 1-100

o 2-50

o 2-50

e
S001

S002

S002

S002

S002

S002

E003


4
r

o 0-1

o 2-10

o 1-5

l 1

c 2-10

c 1-5

c 0-1

l 1

e
S001

S002

S002

S002

3

1

5

10

S003

S003

S003

0

0

0

0
5
r

o 2-50

o 0-1

c 1-200

e
S001

S002

S002

E002
6
r

c 0-50

e
S001

E005
7
r

o 0-1

c 0-2

c 0-1

l 1

e
S001

S002

E004

S003

0

0

0

0
8
r

o 2-1

o 1-1

o 2-10

o 2-10

c 2-10

l 1

e
S001

S002

S002

S002

S002

S003

3

0

1

11
9
r

o 1-7

b

l 0

e
S001

S002

544

0

54

2456

204
10
r

o 1-5

o 0-10

b

l 0

e
S001

S002

S002

442

120

44

2558

74
11
r

o 1-2

o 0-10

o 2-3

b

e
S001

S002

S002

S002

327

0

32
12
r

o 1-5

o 0-2

b

e
S001

S002

S002

380

120

38
13
r

o 0-1

c 0-1

o 2-30

b

e
S001

S002

S003

S002

450

0

45
14
r

o 1-3

c 1-3

b

l 0

b

e
S001

S002

S003

E005

3000

150

E005
15
r

o 2-100

o 2-100

o 2-12

o 2-50

b

c 2-12

b

l 0

e
S001

S002

S002

S002

S002

E006

S003

3000

0

300

0

450
16
r

o 0-9

o 1-1

b

o 0-15

o 1-2

b

o 0-19

o 1-4

b

o 0-20

o 1-5

b

e
S001

S002

S002

201

0

20

S002

S002

332

0

33

S002

S002

451

120

45

S002

S002

515

0

51
/**自测用例

r

o 0-2

o 1-4

b

e

输出:

S001

S002

S002

380

120

38

*/

#include <iostream>

#include <string>

#include <list>

#include <cstdio>

#define MAX ( 0xffffffff >> 1 ) //32位机子的int型(4字节,第一位为符号位)最大值为0xffffffff>>1 ,题目不可能取到这个值(最多为60000元)

using namespace std ;

typedef struct Goods

{

int goodsID;//商品序号

int goodsNum;//商品数量

} Goods;

//购物车信息,方便查询(不必每次都计算)

typedef struct

{

int orderNum;//订单数

int datas[3];

//datas[0]//食物类别的商品数

// datas[1];//服装类别的商品数

//datas[2];//书籍的商品数

}GoodsCarInfo;

//重载操作符,方便在删除操作中操作

bool operator == (Goods goods1 ,Goods goods2)

{

return ( (goods1.goodsID==goods2.goodsID) && (goods1.goodsNum==goods2.goodsNum) ) ;

}

int g_money = 3000 ;//卡余额

int g_credit = 150 ;//卡积分

list<Goods> g_goods_car ;//购物车

GoodsCarInfo goodsCarInfo ;//购物车信息

typedef int (*getMoneyFunc)(int);//函数指针

//1.r指令:重置(初始化)

void init ()

{

if(!g_goods_car.empty())

g_goods_car.clear();

g_money = 3000 ;

g_credit = 150 ;

memset(&goodsCarInfo,0,sizeof(GoodsCarInfo));

cout<<"S001\n";

}

//2.挑选商品 命令格式:o 商品序号-商品数量

void selectGoods (int goodsID , int goodsNum)

{

// 如果输入的“商品序号”或“商品数量”参数不合法,输出“E002”。参数错误直接返回不再进行其他处理;

if (goodsID < 0 || goodsID > 2 || goodsNum <= 0 || goodsNum > 100)

{

cout<<"E002\n";

}// 购物车中最多容纳5条商品订单,挑选时如果购物车已满,则挑选失败,输出“E003”;

else if (!g_goods_car.empty() && g_goods_car.size()>=5)

{

cout<<"E003\n";

}

else

{

//挑选成功则生成购物车中的一条商品订单,输出:“S002”;

Goods newGoods;

newGoods.goodsID = goodsID ;

newGoods.goodsNum = goodsNum ;

g_goods_car.push_back(newGoods);

goodsCarInfo.orderNum++;

goodsCarInfo.datas[goodsID]+=goodsNum;

cout<<"S002\n";

}

}

//3.删除购物车中的订单 c 商品序号-商品数量

void deleteOrder ( int goodsID , int goodsNum )

{

//商品数量不超过100(0<每次删除商品数量<=100)

if (goodsID < 0 || goodsID > 2 || goodsNum <= 0 || goodsNum > 100)

{

cout<<"E002\n";

}//如果购物车为空,输出“E005”;

else if ( g_goods_car.empty())

{

cout<<"E005\n";

}

else

{

//找购物车中查找

list<Goods>::iterator it ;

list<Goods>::iterator end = g_goods_car.end();

int findFlag = false ;

Goods searchGoods ;

searchGoods.goodsID = goodsID ;

searchGoods.goodsNum = goodsNum ;

for ( it = g_goods_car.begin() ; it!=end ;)

{

if( (*it) == searchGoods )

{

goodsCarInfo.orderNum--;

goodsCarInfo.datas[it->goodsID]-=it->goodsNum;

g_goods_car.erase(it++);

findFlag = true ;

break ;

}

else

{

it++;

}

}

if (!findFlag)//如果购物车中不存在待删除订单,输出“E004”;

{

cout<<"E004\n";

}

else //成功删除

{

cout<<"S003\n";

}



}

}

//3.查询 命令格式:l 查询类别

void query(int queryType)

{//0表示购物卡信息查询,1表示购物车订单查询

if ( queryType == 0)

{

cout<<g_money<<endl;

cout<<g_credit<<endl;

}

else if ( queryType == 1 )

{

cout<<goodsCarInfo.orderNum<<endl;

cout<<goodsCarInfo.datas[0]<<endl;

cout<<goodsCarInfo.datas[1]<<endl;

cout<<goodsCarInfo.datas[2]<<endl;

}

else {

//查询类别参数错误,输出“E002”

cout<<"E002\n";

}

}

//食品的第一中优惠方案

int foodPay1(int goodsNum)

{

return goodsNum*10 ;

}

//食品的第二中优惠方案

int foodPay2(int goodsNum)

{

return goodsNum*9 ;

}

//食品的第三中优惠方案

int foodPay3(int goodsNum)

{

int cost = goodsNum*10;

int discount = (cost/100)*18;

cost -= discount ;

return cost ;

}

//衣服的第一种优惠方案

int dressPay1(int goodsNum)

{

return goodsNum*120 ;

}

//衣服的第二种优惠方案

int dressPay2(int goodsNum)

{

int cost = goodsNum*120;

int discount = (cost/200)*40;

cost -= discount ;

return cost ;

}

//书籍的第一种优惠方案

int bookPay1(int goodsNum)

{

return goodsNum*30 ;

}

//书籍的第二种优惠方案

int bookPay2(int goodsNum)

{

return goodsNum*15 ;

}

getMoneyFunc payFood[3]={foodPay1,foodPay2,foodPay3};

getMoneyFunc payDress[2]={dressPay1,dressPay2};

getMoneyFunc payBook[2]={bookPay1,bookPay2};

//4.结算 命令格式:b

void pay()

{

if(g_goods_car.empty())

{

cout<<"E005\n";

//购物车为空

return ;

}

int foodCost[3]=

{

payFood[0](goodsCarInfo.datas[0]),

payFood[1](goodsCarInfo.datas[0]),

payFood[2](goodsCarInfo.datas[0])

};

int dressCost[2]=

{

payDress[0](goodsCarInfo.datas[1]),

payDress[1](goodsCarInfo.datas[1]),

};

int bookCost[3]=

{

payBook[0](goodsCarInfo.datas[2]),

payBook[1](goodsCarInfo.datas[2]),

};

int cost = MAX ;

bool credit=false ;

for ( int i = 0 ; i< 3 ; i++)

{

for(int j = 0 ; j < 2 ;j++)

{

for(int k = 0 ;k < 2 ;k++)

{

int now = foodCost[i] + dressCost[j] + bookCost[k] ;

bool useCredit = false ;

//大于等于500才有总优惠

if(now>=500)

{

int payFinal1 = now * 0.8 <= g_money ? now * 0.8 : MAX ; //打八折

int payFinal2 = MAX ;//扣积分

int tempPay;

if(g_credit >= 120)

{

tempPay = now - 120 ;

}

else

{

tempPay = now - g_credit ;

}

payFinal2 = tempPay <= g_money ? tempPay : MAX ;

//比较两种总优惠方式

if(payFinal1 <= payFinal2)

{

now = payFinal1 ;

useCredit = false ;

}

else

{

now = payFinal2 ;

useCredit = true ;

}

}

else//now < 500

{

if (now > g_money)

{

now = MAX ;

}

else

useCredit = false ;

}

if(now < cost)

{

cost = now ;

credit = useCredit ;

}

}//end for (k)

}//end for (j)

} //end for ( i)

if (cost < MAX )

{

cout<<cost<<endl;

if(credit)//使用了积分

{

if( g_credit>120 )

{

g_credit-=120;

cout<<"120\n";

}

else

{

cout<<g_credit<<endl;

g_credit = 0 ;

}

}

else

{

cout<<"0\n";//没有使用积分

}

int creditAdd = cost/10 ;

cout<<creditAdd<<endl;//新增积分

g_credit += creditAdd ;

g_money -= cost ;

g_goods_car.clear();

memset(&goodsCarInfo,0,sizeof(GoodsCarInfo));

}

else

{

cout<<"E006\n";

}

}

int main()

{

char inputStr[81] ;

while(gets(inputStr))

{

int startPos=0;

int len=strlen(inputStr);

while(startPos<len&&inputStr[startPos++]==' ');

startPos--;

switch(inputStr[startPos])

{

case 'r' :

init();

break ;

case 'o' :

{

int goodID,goodNums;

sscanf(&inputStr[startPos+2],"%d",&goodID);

sscanf(&inputStr[startPos+4],"%d",&goodNums);

selectGoods(goodID,goodNums);

}

break ;

case 'c' :

{

int goodID,goodNums;

sscanf(&inputStr[startPos+2],"%d",&goodID);

sscanf(&inputStr[startPos+4],"%d",&goodNums);

deleteOrder(goodID,goodNums);

}

break ;

case 'b' :

pay();

break ;

case 'l' :

{

int queryType;

sscanf(&inputStr[startPos+2],"%d",&queryType);

query(queryType);

}

break ;

case 'e' :

return 0;

break ;

default :

cout<<"E001\n";

break ;

}

}

return 0 ;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: