第一次发csdn记录下,写的有点bug不是很完美(并且写法有些许麻烦,想的有点多),请各位大神指点轻点喷
题目要求:
商品货架(特指一个商品)可以看成一个栈,栈顶商品的生产日期最早,栈底商品的生产日期最近。上货时,需要倒货架,以保证生产日期较近的商品在较下的位置。并且要记录每一次输入的数据。
我的想法是:
1.每一批货应该是同一生产日期(并且也要写入对应那批货的数量)
2.写入后,要用文件流存入该商品信息。写进的时候也要注意压栈的顺序
将要用到的方法:两个栈模拟货架以及周转空间(栈的方法有参考csdn各位大神的代码)
第一部分:就是写栈的操作
bool cmp(int x,int y ){
return x > y;
}
typedef struct StackNode {
// 数据域
int date;
// 指针域
struct StackNode *next;
}StackNode,*LinkStack;
// 链栈初始化
int InitStack(LinkStack &S){
// S为空指针
S=NULL;
return 1;
}
// 判断链栈是否为空
int Empty(LinkStack S) {
if(S==NULL)
return 1;
else
return 0;
}
// 入栈
int Push(LinkStack &S,int e) {
StackNode *p=new StackNode;
p->date=e;
p->next=S;
S=p;
return 1;
}
// 出栈
int Pop(LinkStack &S,int &e) {
if(S==NULL) return 0;
e=S->date;
StackNode *p=S;
S=S->next;
delete p;
return 1;
}
// 由栈顶到栈底遍历栈
int Traverse(LinkStack S) {
StackNode *p=S;
while(p!=NULL) {
p=p->next;
}
}
int Length(LinkStack S) {// 计算栈的长度
int num = 0;// 计数器
LinkStack q = S;
while(q) {// 遍历栈,统计元素总数
num++;
q = q->next;
}
return num;
}
第二部分:就是定义了一个商品类(虽然有点多此一举,但是想要详细一点点)
class Commodit
{
public:
int num; //商品的数量、年月日的定义
int year;
int month;
int day;
};
第三部分:就是进入正题(这一部分写的比较复杂是因为题目要求要用到倒栈,本来想直接用vector将所有数据吃进去进行排序,然后存入A中,所以最后还是进行修改了)并且用了容器vc将每一批生产日期对应的数量存入,方便以后取货的时候进行计算使用
void store() {
int i,e,l,k; // i是用来存储新输入进去商品的数量、e要用在栈的弹压、l是用来存储新输入商品的日期数据
LinkStack A,B;
InitStack(A); // 商品货架
InitStack(B); // 周转商品货架
vector<int>vec; // 创建用于存储商品日期数据
vector<int>vc; // 用于存储新输入进去的商品数量
ifstream infile; //开始读取数据
string line;
infile.open("test.txt");
if(!infile)
cout<<"打开文件失败"<<endl;
int count=0;
Commodit a;
while(getline(infile,line))
{
istringstream record(line);
record >> a.year>>a.month>>a.day>>a.num;
int t = a.year*10000+a.month*100+a.day;
count = a.num+count;
k = a.num;
vc.push_back(k);
vec.push_back(t);
}
fstream file("test.txt",ios::out); // 删除文件所有记录重新排序(因为数据已存在栈里)
int p = vec.size(); // 计算容器中元素的数量
if(!vec.empty()) // 要考虑一开始没有数据的情况
{
sort(vec.begin(),vec.end(),cmp); // 进行排序因为读取文件时顺序调转所以要重新排序放入栈中
for(int m=0;m < p;m++)
{
e = vec[m];
Push(A,e);
}
}
cout<<"现该商品有"<<count<<"个商品,还可以输入"<<100 - count<<endl;
cout<<"请输入要存入商品的数量"<<endl;
cin >> i ;
// 进行存储数据以及数据比对
while(i+count > 100)
{
cout<<"您输入的商品数目,货柜无法放下!请重新输入"<<endl;
cin >> i ;
}
cout <<"请输入商品的生产日期!"<<endl; // 要求顾客输入新的商品时间
cin >> a.year >> a.month >> a.day ;
l = a.year*10000+a.month*100+a.day;
if(!vec.empty()) // 如果里面没有数据就不用进行比对直接进行弹压栈
{
while(l < vec[p-1])
{
cout <<"请重新输入商品的生产日期(比"<<vec[p-1]<<")晚的生产日期!"<<endl; // 要求顾客输入商品时间
cin >> a.year >> a.month >> a.day ;
l = a.year*10000+a.month*100+a.day;
}
}
while(A!=NULL) // 若A中的元素不为空,将其放入B中将商品由商品货架转入周转商品货架
{
Pop(A,e);
Push(B,e);
}
Push(A,l);
while(B!=NULL) // 当A中存入元素后,再将B周转货架上由商品再放入)
{
Pop(B,e);
Push(A,e);
}
第四部分:就是展现给顾客当前货栈的情况了
cout<<"当前商品货架如下:"<<endl;
Traverse(A);
t = Length(A);
ofstream myin("test.txt",ios::app);
for(int m=0;m<t;m++) // 循环将容器中的元素输入
{
Pop(A,e);
a.year = e / 10000; //重新将日期拆开展示存入
a.month= (e - (a.year*10000))/100;
a.day =(e-(a.year*10000)-(a.month*100));
vector<int>::reverse_iterator it; // 容器的倒序输出,因为我们一开始存入的商品不同生产日期数量是一直没有进行倒转的
for (it = vc.rbegin(); it != vc.rend(); it++)
a.num = *it;
if(m<t-1) // 这里是为了将新生产日期之前的数量通过容器倒序输出存入
{
myin << a.year <<"\t\t"<<a.month<<"\t\t"<<a.day<<"\t\t"<<a.num<<"\n";
cout<< a.year <<"年"<<a.month<<"月"<<a.day<<"日"<<"该生产日期的商品数量为:"<<a.num<<endl;
}
else
{
myin << a.year <<"\t\t"<<a.month<<"\t\t"<<a.day<<"\t\t"<<i;
cout<< a.year <<"年"<<a.month<<"月"<<a.day<<"日"<<"该生产日期的商品数量为:"<<i<<endl;
}
}
cout << "总数量为"<<i+count<<endl;
myin.close();
}
第六部分:有点bug没有详细去揪他的错误,是为了给顾客展示一开始的商品信息
void read() {
ifstream infile;
string line;
Commodit c;
infile.open("test.txt");
if(!infile)
cout<<"打开文件失败"<<endl;
else
{
int count;
if(infile.eof())// 这一部分没有办法展示
{
cout<<"该货架还未存货"<<endl;
infile.close();
return;
}
else
{
cout <<"该商品的生产日期有如下:"<<endl;
while(getline(infile,line))
{
istringstream record(line);
record >> c.year>>c.month>>c.day;
cout << c.year <<"年"<<c.month<<"月"<<c.day<<"日"<<endl;
}
}
}
}
最后一部分:就是主函数了(主要用来调用)
int main() {
// 展示现有的商品
read();
// 调用存入商品函数
store();
return 0;
}
然后就是我运行出来的结果,当然还可以继续改进滴
哈哈哈,记录下,希望能给大家带来帮助,不能的话也不要骂我,我在尽力学/(ㄒoㄒ)/~~