银行家banker(操作系统OS)手中拥有一些资源,客户needer(进程)已经占有了一些资源。needer要完成自己的任务总共需要的资源已知,并且完成任务后会立刻释放所有的资源返还给banker(进程运行完成,释放所有的资源)。但是needer在获得全部所需资源之前不会释放任何资源。
作为banker,为了保证不出现所有needer都无法获得所有所需资源的时刻出现,在每次有needer提出新的申请时,你需要判断是否允许此次申请。
以终端交互为主要形式,可以添加银行家资源、客户及其信息、客户的申请。
支持中英文切换
-set -lang English切换语言为英文-set -lang Chinese切换语言为中文
使用帮助
- 在任何时刻,输入
-help获取所有的帮助- 在任何时刻,输入
-help -this获取这一步的帮助
随时退出
- 在任何时刻,输入
-exit即可直接退出程序
一共包含个步骤:添加银行家资源、添加客户(名称)、设置客户具体资源信息、客户提出申请与处理。
添加银行家资源
程序初始状态提示符为
LetMeFly banker>。这时应该添加银行家资源。因只有一个银行家(OS),故银行家没有特殊的名字,就叫“banker”。这时候每次应该输入两个参数,分别是一个字符串和一个数字。字符串代表银行家的某资源的名称,数字代表银行家手里有多少个这样的资源。
直到你不再想添加新的资源,输入
continue进入第步。
添加客户
程序状态提示符变成
LetMeFly needer>客户(进程)不只一个,故每个客户拥有独一无二的不含有空格的名字,作为用户的id。因此这时候你需要输入一个参数,是一个字符串,代表客户的名字。之后会自动进入第步。第三步完成后又会自动回到第二步,以便于你继续添加新的客户。
直到你不想再添加新的客户,输入
continue进入第步。
设置客户资源信息
这时候状态提示符会变成
LetMeFly needer [A] [B]>,其中[A]是你刚刚添加的客户的名字,[B]是你这一步需要为客户[A]添加的资源名。如果你第步设置了银行家具有种资源,那么你需要对此客户在这一步设置次,每次是这位客户的一种资源的信息。这时候你需要输入两个参数,是两个数字,分别代表客户
[A]总共需要多少个[B]资源、客户[A]已经有了多少个[B]资源。其中客户已有的资源必须客户的总需求量。这一步你无法跳过,因为你必须让银行家知道这位客户有关所有资源的所有信息。直到你设置了次,程序会自动进入第步。
开始申请资源
在步骤输入
continue进入这一步后,状态提示符会变成LetMeFly apply>,说明这一步是客户申请资源的时间。假设银行家有种资源。这时候你需要输入个参数,第一个参数为一个字符串,是此次资源申请者(客户)的名字;后面个参数是个数字,按顺序依次是这种资源的申请量。
这一步你也无法跳过,除非你不想继续模拟下去,请输入
exit直接退出程序而不是continue跳过。如果银行家不能满足此次申请,申请会被拒绝,否则申请直接生效,直到银行家满足了所有的用户需求,程序自动结束。
保留了版本0.0.1的内容
使用帮助
- 在任何时刻,输入
-help -show可查看当前资源情况。
显示顺序
- 客户的显示顺序修改为了客户的添加顺序,而不再是默认的按客户名字排序。
视觉体验
- 设置了彩色字符,提示视觉体验,便于迅速找到帮助的重点内容。
xxxxxxxxxx/* * @Author: LetMeFly * @Date: 2021-06-04 19:17:50 * @LastEditors: LetMeFly * @LastEditTime: 2021-06-05 01:56:19 *//* 所有名称不能包含空格 *//* 整数默认是int *//* 单个客户需求量可大于银行家总持有量 *//* 资源已有量需小于等于资源总需求总量 */using namespace std;// Light bluetypedef vector<string> ToReturn; // 要返回的东西,包含数个字符串typedef vector<string> Resources; // 所有的资源名称typedef map<string, int> Banker; // 银行家<资源名,资源数>typedef map<string, pair<int,int> > Needer; // 客户<资源名,<共需资源,已获资源> >typedef map<string, Needer>Needers; // 客户集:<客户名称,客户实体>Resources resources; // 资源名集,存所有的资源名称Banker banker; // 银行家,存有银行家所有的资源Needers needers; // 客户集,里面是各个客户HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE); // 输出句柄int lang=0; // 语言,默认为英语 0-英|1-汉int step=0; // 程序进行到了哪一步 0-添加银行家资源|1-添加客户|2-对客户添加资源|3-客户申请处理string temp[2]; // 用来存放要打印的东西int locResource; // 正在处理第几个资源void SetColor(unsigned short forwardColor,unsigned short backgroundColor){ SetConsoleTextAttribute(hCon, forwardColor|(backgroundColor<<4)); }void help() // 整体的帮助{ if(lang==0) printf("\ banker algorithm, written by LetMeFly[https://LetMeFly666.github.io/various/]\n\ +------------------------+----------------------------------------------+\n\ | order | function |\n\ +------------------------+----------------------------------------------+\n\ | -help | show how to use and show this menu |\n\ +------------------------+----------------------------------------------+\n\ | -help -this | show what should you do at this step |\n\ +------------------------+----------------------------------------------+\n\ | -set -lang Chinese | show language in Chinese |\n\ +------------------------+----------------------------------------------+\n\ | -set -lang English | show language in English |\n\ +------------------------+----------------------------------------------+\n\ | exit | exit the program |\n\ +------------------------+----------------------------------------------+\n\ You will see `LetMeFly banker>` first.\n\ Then you should input one string[a] and a num[b] representing that\n\ the banker have source[a] at a num of [b].\n\ You can add many times each source a time.\n\ After finished that you should input `continue` to continue.\n\ \n\ Then you will see `LetMeFly needer>` after that.\n\ Then you should input one string [a] representing that there is\n\ a needer named[a], and you will see `LetMeFly needer [a] [b]>`.\n\ \n\ Then you should input two nums[c]&[d] representing\n\ that needer[a] total [c] source[b] and already have a num of [d].\n\ After finishing all of that, you will see `LetMeFly needer>` again\n\ untill you input `continue` to continue.\n\ \n\ Then you will see `LetMeFly apply>`.\n\ each time input a string[a] and some nums representing the\n\ needer is applying sources at a num of that for each.\n\ \n\ If you can't understand what am I saying, it doesn't matter.\n\ Just input `-help -this` whenever you are puzzled.\n\"); else if(lang==1) printf("\ 银行家算法,笔者LetMeFly[https://LetMeFly666.github.io/various/]\n\ +------------------------+----------------------------------------------+\n\ | 指令 | 功能 |\n\ +------------------------+----------------------------------------------+\n\ | -help | 打印如何使用此程序并用英文打印此菜单 |\n\ +------------------------+----------------------------------------------+\n\ | -help -this | 打印这一步应该干什么 |\n\ +------------------------+----------------------------------------------+\n\ | -set -lang Chinese | 设置语言为中文 |\n\ +------------------------+----------------------------------------------+\n\ | -set -lang English | 设置语言为英文 |\n\ +------------------------+----------------------------------------------+\n\ | exit | 退出系统,结束程序 |\n\ +------------------------+----------------------------------------------+\n\ 最初你会看到`LetMeFly banker`,这时候你只需要输入一个字符串[a]和一个数字[b]\n\ 代表银行家手里有[b]个资源[a]。你可以添加很多种资源,输入`continue`继续。\n\ \n\ 之后将会看到`LetMeFly needer>`,这时候你需要输入一个字符串[a],\n\ 代表有客户[a]。之后会变成`LetMeFly needer [a] [b]>`。\n\ \n\ 这时输入两个数字[c]和[d],代表客户[a]共需要[c]的资源[b]且已有了[d]个。\n\ 输入完次客户后,提示符将会继续变成`LetMeFly needer>`。\n\ 你可以继续添加新的客户,直到你输入`continue`继续。\n\ \n\ 提示符将会变成`LetMeFly apply>`,每次输入一个字符串[a]和一些数字[*b]\n\ 代表客户[a]尝试申请资源个数分别为[*b]。\n\ \n\ 如果你看不懂我在说什么,就在你不知道该怎么做的时候输入`-help -this`。\n\");}string stripSpace(string ori) // 去除指令中多余的空格{ string ans; int length=ori.size(); int loc=0,loc2=length-1; while(loc<ori.size()&&ori[loc]==' ')loc++; // 去除开头的空格 while(loc2>=0&&ori[loc2]==' ')loc2--; // 去除结尾的空格 for(;loc<=loc2;loc++) { if(ori[loc]==' '&&ori[loc-1]==' '); // 相邻的两个空格 else ans+=ori[loc]; } return ans;}void testForStripSpace() // 测试函数stripSpace(){ string s; while(getline(cin,s)) { cout<<"'"<<stripSpace(s)<<"'"<<endl; }}int Stoi(string s) // string->int, 不合法返回-1{ int ans=0; for(int i=0;i<s.size();i++) { if(s[i]>='0'&&s[i]<='9') { ans*=10; ans+=s[i]-'0'; } else // 不是数字 return -1; } return ans;}int len(string s) // 返回一个字符串的长度,实为为了int的重载{ return s.size();}int len(int n) // 返回一个数字的十进制的长度{ int ans=0; if(n==0)return 1; else if(n<0){ans++;n=-n;} while(n) { ans++; n/=10; } return ans;}void prt(int n, char c) // 打印n个c{ for(int i=0;i<n;i++) putchar(c);}void prt(int M0, int M1) // 打印一行 +--M0个--+--M1个--+{ printf(" +"); prt(M0,'-'); putchar('+'); prt(M1,'-'); puts("+");}void prt(Banker banker){ int M0=0,M1=0; for(Banker::iterator it=banker.begin();it!=banker.end();it++) { M0=max(M0,len(it->first)); M1=max(M1,len(it->second)); } M0+=2,M1+=2; prt(M0,M1); // for(Banker::iterator it=banker.begin();it!=banker.end();it++) for(int i=0;i<resources.size();i++) { printf(" | "); int l=len(resources[i]); cout<<resources[i]; prt(M0-1-l,' '); printf("| "); l=len(banker[resources[i]]); cout<<banker[resources[i]]; prt(M1-1-l,' '); puts("|"); prt(M0,M1); }}void prt(Needers needers) // 打印所有客户的信息{ for(Needers::iterator it=needers.begin();it!=needers.end();it++) { cout<<" * "<<it->first<<": "; Needer thisNeeder=it->second; for(Needer::iterator it2=thisNeeder.begin();it2!=thisNeeder.end();it2++) { if(it2!=thisNeeder.begin())printf(", "); putchar('['); pair<int,int> thisSourceNum=it2->second; cout<<it2->first<<" "<<thisSourceNum.first<<" "<<thisSourceNum.second; putchar(']'); } puts(""); }}void prt(string s, int n) // 将字符串s每n个字符一行输出{ int sum=0; for(int i=0;i<s.size();i++) { if(sum>=n) { sum=0; printf("\n "); } cout<<s[i]; sum++; }}void prt(Banker banker, Needers needers){ if(lang==0) puts(" Banker:"); else if(lang==1) puts(" 银行家:"); prt(banker); if(lang==0) puts(" Needers:"); else if(lang==1) puts(" 客户们:"); prt(needers);}void showThis() // 显示`LetMeFly *>`{ printf(" LetMeFly "); switch (step) { case 0: printf("banker");break; // 添加银行家资源 case 1: printf("needer");break; // 添加客户(名) case 2: cout<<"needer "<<temp[0]<<" "<<resources[locResource];break; // 为客户添加资源 case 3: printf("apply");break; // 客户申请资源 default: /*An error occured*/ break; } printf("> ");}void help(int step) // 这一步的帮助{ switch (step) { case 0: // 添加银行家资源 if(lang==1) // 汉语 { printf(" · 添加资源:输入字符串[a]和数字[b],代表银行家手里有[b]个名字为[a]的资源\n"); printf(" · 停止添加:输入continue,银行家资源设置结束\n"); } else if(lang==0) // 英语 { printf(" * Add resource: input a string[a] and a num[b] represents banker have\n"); printf(" Source [a] with a num of [b].\n"); printf(" * Continue: Just input `continue` to end setting banker's resource\n"); } break; case 1: // 给客户起名 if(lang==1) // 汉语 { printf(" · 添加客户:输入一个不包含空格的字符串,代表客户名称\n"); printf(" · 停止添加:输入continue,客户添加结束\n"); } else if(lang==0) // 英语 { printf(" * Add needer: Just input a string without a space in it\n"); printf(" which repersents the needer's name.\n"); printf(" * Continue: Just input `continue` to end adding needers\n"); } break; case 2: // 给客户添加资源 if(lang==1) // 汉语 { string toPrt=" · 设置资源:两个整数,代表用户`"+temp[0]+"`的资源`"+resources[locResource]+"`的总需求量和已获得量\n"; prt(toPrt,40); // 可能会出现汉字一半的问题 } else if(lang==0) // 英语 { string toPrt=" * Set source: Input two nums which repersents needer`"+temp[0]+"`'s source `"+resources[locResource]+"`'s total and already num\n"; prt(toPrt,40); } break; case 3: // 客户申请资源 if(lang==1) // 汉语 { printf(" · 申请资源:输入一些空格隔开的数字(个数必须和资源总数相同)\n"); printf(" 代表各个资源的申请量。\n"); } else if(lang==0) // 英语 { printf(" * Apply resource: Enter some numbers separated by spaces (the number must\n"); printf(" be the same as the total number of resources)\n"); } break; default: /*An error occured*/ break; }}ToReturn split(string toSplit, char c) // 将字符串以字符c为间隔分开{ ToReturn ans; toSplit+=c; int left=0; for(int right=0;right<toSplit.size();right++) { if(toSplit[right]==c) //left->right-1 { ans.push_back(toSplit.substr(left,right-left)); left=right+1; } } return ans;}void testForSplit(){ string s; char c=' '; while(1) { getline(cin,s); ToReturn ans=split(s,c); putchar('['); for(int i=0;i<ans.size();i++) { if(i)putchar(','); cout<<ans[i]; } puts("]"); }}bool isSafe(Banker banker, Needers needers) //真正的银行家算法 之 是否安全 不引用是为了保护原有数据{ while(needers.size()) { for(Needers::iterator it=needers.begin();it!=needers.end();it++) { for(int i=0;i<resources.size();i++) { if(banker[resources[i]]<(it->second)[resources[i]].first-(it->second)[resources[i]].second) // 不能全部满足这个 { goto cannot; } } for(int i=0;i<resources.size();i++) // 可以全部贷给他 { banker[resources[i]]+=(it->second)[resources[i]].first; } needers.erase(it); goto could; // 重新从头开始遍历 cannot:; } return false;// 没有跳到could,全部找了一遍也不行 could:; } return true;}int main(){ help(); showThis(); while(1) { string s; getline(cin,s); s=stripSpace(s); if(s==""){showThis();continue;} // 只按了回车 if(s=="exit"){puts("Bye~");break;} // exit-退出程序 else if(s=="-help")help(); // -help 打印帮助 else if(s=="-help -this")help(step); else if(s=="-set -lang Chinese"){lang=1;puts(" 已设置为中文。");} // 设置语言为中文 else if(s=="-set -lang English"){lang=0;puts(" Now in English.");} // 设置语言为英文 else if(s=="continue") // 完成此步骤 { if(step==0) // 不再添加银行家资源 { if(resources.empty()) // 还未添加任何资源 { if(lang==0)puts(" You should add the source first."); else if(lang==1)puts(" 你需要先添加资源再继续"); help(step); } else { step++; if(lang==1)puts(" 银行家资源添加完毕!银行家手中所拥有的资源有:"); else if(lang==0)puts(" Adding banker finished! What the banker have is:"); prt(banker); // 打印已有资源-表格形式 if(lang==1)puts(" 开始添加客户"); else if(lang==0)puts(" Begin to add the needer"); } } else if(step==1) // 正在输入客户名 { if(needers.empty()) // 还没有添加客户 { if(lang==0)puts(" Do you want a needer named `continue`?"),puts(" Just change it!"); else if(lang==1)puts(" 你想让一位客户叫`continue`吗?\n换一个名字吧。"); help(step); } else { step+=2; // 到申请资源那里 if(lang==1)puts(" 客户添加完毕!所有的客户情况为:"); else if(lang==0)puts(" Adding needer finished! All needers are:"); prt(needers); // 打印已有资源-表格形式 if(lang==1)puts(" 开始添加申请资源"); else if(lang==0)puts(" Begin to apply the source"); } } else if(step==2) // 正在为客户设置资源数量 { if(lang==0)puts(" You must set the source num of the needer\n You couldn't skip it!"); else if(lang==1)puts(" 客户资源数量必须设置,不能跳过"); help(step); } else if(step==3) // 申请资源 { if(lang==0)puts(" Already last step which cannot skip."); else if(lang==1)puts(" 已经是最后一步,不能跳过"); help(step); } } else { ToReturn input; string name; int num1,num2; int num[resources.size()]; Needer needer; bool couldRelease=true; switch (step) { case 0: // 添加银行家资源 input=split(s,' '); // [name] [num] if(input.size()!=2)goto error00; name=input[0]; num1=Stoi(input[1]); if(num1==-1)goto error00; for(int i=0;i<resources.size();i++) if(resources[i]==name) goto error01; // 此资源名已存在 resources.push_back(name); banker[name]=num1; goto success0; error00: // 参数错误 if(lang==0)puts(" Parameter Error! You should input two Parameters"); else if(lang==1)puts(" 参数错误!请输入两个参数"); help(step); goto success0; error01: // 资源名重复 if(lang==1)puts(" 此资源名已存在!"); else if(lang==0)puts(" This resource name already exists"); help(step); goto success0; success0: break; case 1: // 添加客户,只需要输入客户名 locResource=0; input=split(s,' '); // [name] if(input.size()!=1)goto error10; name=input[0]; if(needers.count(name)) goto error11; // 此客户名已存在 needers[name]=needer; temp[0]=name; goto success1; error10: // 名字中出现空格 if(lang==1) { cout<<" 您的意思是`"<<s<<"`吗?"<<endl; puts(" 很抱歉,认为规定名字不支持空格"); } else if(lang==0) { cout<<" Do you mean`"<<s<<"`?"<<endl; puts(" The name cannot include space"); } help(step); goto fail1; error11: // 此客户已存在 if(lang==1)puts(" 此客户名已存在!"); else if(lang==0)puts(" This needer already exists"); help(step); goto fail1; success1: step++;break; fail1:break; case 2: // 为此客户设置资源数量 input=split(s,' '); // [num1, num2] if(input.size()!=2)goto error20; num1=Stoi(input[0]); num2=Stoi(input[1]); if(num2>num1)goto error21; // 已有量>总需求量 // if(num1>banker[resources[locResource]])goto error22; // 总需求量≥银行家总资源 needers[temp[0]][resources[locResource]]=pair<int,int>(num1,num2); goto success2; error20: // 参数不为2 if(lang==0)puts(" Parameter Error! You should input two Parameters"); else if(lang==1)puts(" 参数错误!请输入两个参数"); help(step); goto fail2; error21: // 已有量≥总需求量 if(lang==0)puts(" What you have should less than or equal to what you need"); else if(lang==1)puts(" 已有量应小于等于总需求量"); help(step); goto fail2; // error22: // 总需求量≥银行家总资源 // if(lang==0)puts(" what you want is already more than the what the banker have"); // else if(lang==1)puts(" 你的需求量大于了银行家的资源总量"); // help(step); // goto fail2; success2: if(locResource>=resources.size()-1) step=1,locResource=0; // 此客户设置完毕 else locResource++; break; fail2:break; case 3: // 申请资源 input=split(s,' '); // [*num] if(input.size()!=resources.size()+1)goto error30; // 申请资源种数≠资源总数 name=input[0]; if(needers.count(name)==0)goto error31; // 无此needer needer=needers[name]; for(int i=0;i<resources.size();i++) { num[i]=Stoi(input[i+1]); if(num[i]>needer[resources[i]].first) // 申请大于总需,用num1来存错误下标 { num1=i; goto error32; } if(num[i]>needer[resources[i]].first-needer[resources[i]].second) // 申请大于还需,同样用num1存下来 { num1=i; goto error33; } if(num[i]>banker[resources[i]]) // 申请大于银行家资源,无法满足 { num1=i; goto cannot34; } } couldRelease=true; for(int i=0;i<resources.size();i++) { banker[resources[i]]-=num[i]; needers[name][resources[i]].second+=num[i]; if(needers[name][resources[i]].second!=needers[name][resources[i]].first)couldRelease=false; } if(couldRelease) // 这个needer满足了,可以必可以满足他,释放他 { for(int i=0;i<resources.size();i++) { banker[resources[i]]+=needers[name][resources[i]].first; // 还给银行 } needers.erase(name); // 删除此人 if(needers.empty()) // 全部还完 { goto success31; } goto success32; // 此人还完 } if(isSafe(banker,needers)) // 贷给此人 { goto success33; } else // 不给 { for(int i=0;i<resources.size();i++) // 收回 { banker[resources[i]]+=num[i]; needers[name][resources[i]].second-=num[i]; } goto fail34; } goto success0; error30: // 申请资源种数≠资源总数 if(lang==0)printf(" Parameter Error! You should input %d Parameters\n",resources.size()+1); else if(lang==1)printf(" 参数错误!请输入%d个参数\n",resources.size()+1); help(step); goto fail3; error31: // 无此needer if(lang==0)printf(" We don't have a user named `%s`\n",name.c_str()); else if(lang==1)printf(" 没有客户`%s`\n",name.c_str()); help(step); goto fail3; error32: // 申请大于总需 if(lang==0)printf(" the %d-th apply %d is more than the total need %d\n",num1+1,num[num1],needer[resources[num1]].first); else if(lang==1)printf(" 第%d个申请%d大于客户总需求量%d\n",num1+1,num[num1],needer[resources[num1]].first); help(step); prt(banker,needers); goto fail3; error33: // 申请大于还需 if(lang==0)printf(" the %d-th apply %d is more than the still need %d\n",num1+1,num[num1],needer[resources[num1]].first-needer[resources[num1]].second); else if(lang==1)printf(" 第%d个申请%d大于客户还需求的量%d\n",num1+1,num[num1],needer[resources[num1]].first-needer[resources[num1]].second); help(step); prt(banker,needers); goto fail3; cannot34: // 申请大于还需 if(lang==0)printf(" The apply is denied, because the %d-th apply %d is more than\n banker's total source %d\n",num1+1,num[num1],banker[resources[num1]]); else if(lang==1)printf(" 申请被拒绝,因为第%d个申请%d大于银行家总资源数%d\n",num1+1,num[num1],banker[resources[num1]]); help(step); prt(banker,needers); goto fail3; success31: // 完全贷完 if(lang==0)printf(" Success! you have satisfied all the needers! Goodbye~\n"); else if(lang==1)printf(" 祝贺!你满足了所有的客户! 后会有期~\n"); system("pause"); return 0; goto success3; success32: // 此用户全部满足 if(lang==0)printf(" Permit! after that the needer is satisfied\n"); else if(lang==1)printf(" 满足!之后就满足了这位用的户的所有需求\n"); prt(banker,needers); goto success3; success33: // 满足此用户此次需求 if(lang==0)printf(" Permit!\n"); else if(lang==1)printf(" 满足!\n"); prt(banker,needers); goto success3; fail34: // 不满足此用户此次需求 if(lang==0)printf(" Denied!\n"); else if(lang==1)printf(" 不满足!\n"); prt(banker,needers); goto fail3; success3: break; fail3:break; default: break; } } // else {puts("Error! unknown order!"); help(step);} // 错误命令 showThis(); } return 0;}xxxxxxxxxxbanker algorithm, written by LetMeFly[https://LetMeFly666.github.io/various/] +------------------------+----------------------------------------------+ | order | function | +------------------------+----------------------------------------------+ | -help | show how to use and show this menu | +------------------------+----------------------------------------------+ | -help -this | show what should you do at this step | +------------------------+----------------------------------------------+ | -set -lang Chinese | show language in Chinese | +------------------------+----------------------------------------------+ | -set -lang English | show language in English | +------------------------+----------------------------------------------+ | exit | exit the program | +------------------------+----------------------------------------------+ You will see `LetMeFly banker>` first. Then you should input one string[a] and a num[b] representing that the banker have source[a] at a num of [b]. You can add many times each source a time. After finished that you should input `continue` to continue. Then you will see `LetMeFly needer>` after that. Then you should input one string [a] representing that there is a needer named[a], and you will see `LetMeFly needer [a] [b]>`. Then you should input two nums[c]&[d] representing that needer[a] total [c] source[b] and already have a num of [d]. After finishing all of that, you will see `LetMeFly needer>` again untill you input `continue` to continue. Then you will see `LetMeFly apply>`. each time input a string[a] and some nums representing the needer is applying sources at a num of that for each. If you can't understand what am I saying, it doesn't matter. Just input `-help -this` whenever you are puzzled. LetMeFly banker> A 3 LetMeFly banker> B 3 LetMeFly banker> C 2 LetMeFly banker> continue Adding banker finished! What the banker have is: +---+---+ | A | 3 | +---+---+ | B | 3 | +---+---+ | C | 2 | +---+---+ Begin to add the needer LetMeFly needer> P0 LetMeFly needer P0 A> 7 0 LetMeFly needer P0 B> 5 1 LetMeFly needer P0 C> 3 0 LetMeFly needer> P1 LetMeFly needer P1 A> 3 2 LetMeFly needer P1 B> 2 0 LetMeFly needer P1 C> 2 0 LetMeFly needer> P2 LetMeFly needer P2 A> 9 3 LetMeFly needer P2 B> 0 0 LetMeFly needer P2 C> 2 2 LetMeFly needer> P3 LetMeFly needer P3 A> 2 2 LetMeFly needer P3 B> 2 1 LetMeFly needer P3 C> 2 1 LetMeFly needer> P4 LetMeFly needer P4 A> 4 0 LetMeFly needer P4 B> 3 0 LetMeFly needer P4 C> 3 2 LetMeFly needer> continue Adding needer finished! All needers are: * P0: [A 7 0], [B 5 1], [C 3 0] * P1: [A 3 2], [B 2 0], [C 2 0] * P2: [A 9 3], [B 0 0], [C 2 2] * P3: [A 2 2], [B 2 1], [C 2 1] * P4: [A 4 0], [B 3 0], [C 3 2] Begin to apply the source LetMeFly apply> -help -this * Apply resource: Enter some numbers separated by spaces (the number must be the same as the total number of resources) LetMeFly apply> P1 1 0 2 Permit! Banker: +---+---+ | A | 2 | +---+---+ | B | 3 | +---+---+ | C | 0 | +---+---+ Needers: * P0: [A 7 0], [B 5 1], [C 3 0] * P1: [A 3 3], [B 2 0], [C 2 2] * P2: [A 9 3], [B 0 0], [C 2 2] * P3: [A 2 2], [B 2 1], [C 2 1] * P4: [A 4 0], [B 3 0], [C 3 2] LetMeFly apply> P1 0 2 0 Permit! after that the needer is satisfied Banker: +---+---+ | A | 5 | +---+---+ | B | 3 | +---+---+ | C | 2 | +---+---+ Needers: * P0: [A 7 0], [B 5 1], [C 3 0] * P2: [A 9 3], [B 0 0], [C 2 2] * P3: [A 2 2], [B 2 1], [C 2 1] * P4: [A 4 0], [B 3 0], [C 3 2] LetMeFly apply> P3 0 1 1 Permit! after that the needer is satisfied Banker: +---+---+ | A | 7 | +---+---+ | B | 4 | +---+---+ | C | 3 | +---+---+ Needers: * P0: [A 7 0], [B 5 1], [C 3 0] * P2: [A 9 3], [B 0 0], [C 2 2] * P4: [A 4 0], [B 3 0], [C 3 2] LetMeFly apply> P2 6 0 0 Permit! after that the needer is satisfied Banker: +---+----+ | A | 10 | +---+----+ | B | 4 | +---+----+ | C | 5 | +---+----+ Needers: * P0: [A 7 0], [B 5 1], [C 3 0] * P4: [A 4 0], [B 3 0], [C 3 2] LetMeFly apply> P0 7 4 3 Permit! after that the needer is satisfied Banker: +---+----+ | A | 10 | +---+----+ | B | 5 | +---+----+ | C | 5 | +---+----+ Needers: * P4: [A 4 0], [B 3 0], [C 3 2] LetMeFly apply> P4 5 6 6 the 1-th apply 5 is more than the total need 4 * Apply resource: Enter some numbers separated by spaces (the number must be the same as the total number of resources) Banker: +---+----+ | A | 10 | +---+----+ | B | 5 | +---+----+ | C | 5 | +---+----+ Needers: * P4: [A 4 0], [B 3 0], [C 3 2] LetMeFly apply> P4 4 3 1 Success! you have satisfied all the needers! Goodbye~请按任意键继续. . .xxxxxxxxxx/* * @Author: LetMeFly * @Date: 2021-06-05 13:37:59 * @LastEditors: LetMeFly * @LastEditTime: 2021-06-05 21:21:04 *//* 所有名称不能包含空格 *//* 整数默认是int *//* 单个客户需求量可大于银行家总持有量 *//* 资源已有量需小于等于资源总需求总量 *//* 如果输入一个本来就已经全部满足的客户,那么他必须再申请一次0 0...才能释放资源 *//* 括号:暗蓝 *//* LetMeFly:浅蓝 *//* 连接:蓝字白底 */using namespace std;// 黑色// 暗蓝 DarkBlue// 暗绿// 暗浅蓝// 暗红// 暗紫// 暗黄// 暗白// 灰色// 蓝色// 绿色// 浅蓝Light blue// 红色// 紫色// 黄色// 白色// 恢复控制台本来的颜色// LetMeFly的颜色// 括号// 链接// 表格typedef vector<string> ToReturn; // 要返回的东西,包含数个字符串typedef vector<string> Resources; // 所有的资源名称typedef vector<string> NeederLog; // 客户的名称登记记录,如果只使用map的话客户的打印顺序会不同于添加顺序typedef map<string, int> Banker; // 银行家<资源名,资源数>typedef map<string, pair<int,int> > Needer; // 客户<资源名,<共需资源,已获资源> >typedef map<string, Needer>Needers; // 客户集:<客户名称,客户实体>Resources resources; // 资源名集,存所有的资源名称NeederLog neederLog; // 客户名集,按顺序存放所有客户Banker banker; // 银行家,存有银行家所有的资源Needers needers; // 客户集,里面是各个客户HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE); // 输出句柄int lang=0; // 语言,默认为英语 0-英|1-汉int step=0; // 程序进行到了哪一步 0-添加银行家资源|1-添加客户|2-对客户添加资源|3-客户申请处理string temp[2]; // 用来存放要打印的东西int locResource; // 正在处理第几个资源WORD originalColor;unsigned short originalBackcolor;void SetColor(unsigned short forwardColor,unsigned short backgroundColor){ SetConsoleTextAttribute(hCon, forwardColor|(backgroundColor<<4)); }void SetColor(WORD color){ SetConsoleTextAttribute(hCon, color);}void help() // 整体的帮助{ if(lang==0){ printf("\ banker algorithm, written by ");cLetMeFly;printf("LetMeFly");BRACKETS;printf("[");LINK;printf("https://LetMeFly666.github.io/various/");BRACKETS;printf("]");ORI;printf("\n\ ");TABLE;printf("+------------------------+----------------------------------------------+\n\ |");YELLOW;printf(" order ");TABLE;printf("|");RED;printf(" function ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+\n\ | ");GRAY;printf("-help ");TABLE;printf("|");ORI;printf(" show how to use and show this menu ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+\n\ | ");GRAY;printf("-help -this ");TABLE;printf("|");ORI;printf(" show what should you do at this step ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+\n\ | ");GRAY;printf("-help -show ");TABLE;printf("|");ORI;printf(" show the data now ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+\n\ | ");GRAY;printf("-set -lang Chinese ");TABLE;printf("| ");ORI;printf("show language in Chinese ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+\n\ | ");GRAY;printf("-set -lang English ");TABLE;printf("|");ORI;printf(" show language in English ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+\n\ | ");GRAY;printf("exit ");TABLE;printf("|");ORI;printf(" exit the program ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+");ORI;printf("\n\ You will see `");cLetMeFly;printf("LetMeFly ");RED;printf("banker");ORI;printf(">` first.\n\ Then you should input ");RED;printf("one string");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf(" and ");RED;printf("a num");BRACKETS;printf("[");YELLOW;printf("b");BRACKETS;printf("]");ORI;printf(" representing that\n\ the banker have source");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf(" at a num of ");BRACKETS;printf("[");YELLOW;printf("b");BRACKETS;printf("]");ORI;printf(".\n\ You can add many times each source a time.\n\ After finished that you should input `");GREEN;printf("continue");ORI;printf("` to continue.\n\ \n\ Then you will see `");cLetMeFly;printf("LetMeFly");RED;printf(" needer");ORI;printf(">` after that.\n\ Then you should input ");RED;printf("one string ");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf(" representing that there is\n\ a needer named");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf(", and you will see `");cLetMeFly;printf("LetMeFly needer ");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf(" ");BRACKETS;printf("[");YELLOW;printf("b");BRACKETS;printf("]");ORI;printf(">`.\n\ \n\ Then you should input ");RED;printf("two nums");BRACKETS;printf("[");YELLOW;printf("c");BRACKETS;printf("]");ORI;printf("&");BRACKETS;printf("[");YELLOW;printf("d");BRACKETS;printf("]");ORI;printf(" representing\n\ that needer");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf(" total ");BRACKETS;printf("[");YELLOW;printf("c");BRACKETS;printf("]");ORI;printf(" source");BRACKETS;printf("[");YELLOW;printf("b");BRACKETS;printf("]");ORI;printf(" and already have a num of ");BRACKETS;printf("[");YELLOW;printf("d");BRACKETS;printf("]");ORI;printf(".\n\ After finishing all of that, you will see `");cLetMeFly;printf("LetMeFly ");RED;printf("needer");ORI;printf(">` again\n\ untill you input `");GREEN;printf("continue");ORI;printf("` to continue.\n\ \n\ Then you will see `");cLetMeFly;printf("LetMeFly ");RED;printf("apply");ORI;printf(">`.\n\ each time input a string");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf(" and some nums representing the\n\ needer is applying sources at a num of that for each.\n\ \n\ If you can't understand what am I saying, it doesn't matter.\n\ ");RED;printf("Just input `");YELLOW;printf("-help -this");RED;printf("` whenever you are puzzled.");ORI;printf("\n\");} else if(lang==1){ printf("\银行家算法,笔者");cLetMeFly;printf("LetMeFly");BRACKETS;printf("[");LINK;printf("https://LetMeFly666.github.io/various/");BRACKETS;printf("]");TABLE;printf("\n\ +------------------------+----------------------------------------------+\n\ | ");YELLOW;printf("指令 ");TABLE;printf("| ");RED;printf("功能");TABLE;printf(" |\n\ +------------------------+----------------------------------------------+\n\ | ");GRAY;printf("-help ");TABLE;printf("|");ORI;printf(" 打印如何使用此程序并用英文打印此菜单 ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+\n\ | ");GRAY;printf("-help -this ");TABLE;printf("|");ORI;printf(" 打印这一步应该干什么 ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+\n\ | ");GRAY;printf("-help -show ");TABLE;printf("|");ORI;printf(" 打印目前的资源信息 ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+\n\ | ");GRAY;printf("-set -lang Chinese ");TABLE;printf("|");ORI;printf(" 设置语言为中文 ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+\n\ | ");GRAY;printf("-set -lang English ");TABLE;printf("|");ORI;printf(" 设置语言为英文 ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+\n\ | ");GRAY;printf("exit ");TABLE;printf("|");ORI;printf(" 退出系统,结束程序 ");TABLE;printf("|\n\ +------------------------+----------------------------------------------+");ORI;printf("\n\ 最初你会看到`");cLetMeFly;printf("LetMeFly ");RED;printf("banker");ORI;printf(">`,这时候你只需要输入一个字符串");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf("和一个数字");BRACKETS;printf("[");YELLOW;printf("b");BRACKETS;printf("]");ORI;printf("\n\ 代表银行家手里有");BRACKETS;printf("[");YELLOW;printf("b");BRACKETS;printf("]");ORI;printf("个资源");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf("。你可以添加很多种资源,输入`");GREEN;printf("continue");ORI;printf("`继续。\n\ \n\ 之后将会看到`");cLetMeFly;printf("LetMeFly ");RED;printf("needer");ORI;printf(">`,这时候你需要输入一个字符串");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf(",\n\ 代表有客户");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf("。之后会变成`");cLetMeFly;printf("LetMeFly needer ");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf(" ");BRACKETS;printf("[");YELLOW;printf("b");BRACKETS;printf("]");ORI;printf(">`。\n\ \n\ 这时输入两个数字");BRACKETS;printf("[");YELLOW;printf("c");BRACKETS;printf("]");ORI;printf("和");BRACKETS;printf("[");YELLOW;printf("d");BRACKETS;printf("]");ORI;printf(",代表客户");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf("共需要");BRACKETS;printf("[");YELLOW;printf("c");BRACKETS;printf("]");ORI;printf("的资源");BRACKETS;printf("[");YELLOW;printf("b");BRACKETS;printf("]");ORI;printf("且已有了");BRACKETS;printf("[");YELLOW;printf("d");BRACKETS;printf("]");ORI;printf("个。\n\ 输入完次客户后,提示符将会继续变成`");cLetMeFly;printf("LetMeFly ");RED;printf("needer");ORI;printf(">`。\n\ 你可以继续添加新的客户,直到你输入`");cLetMeFly;printf("continue");ORI;printf("`继续。\n\ \n\ 提示符将会变成`");cLetMeFly;printf("LetMeFly ");RED;printf("apply");ORI;printf(">`,每次输入一个字符串");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf("和一些数字");BRACKETS;printf("[");YELLOW;printf("*b");BRACKETS;printf("]");ORI;printf("\n\ 代表客户");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf("尝试申请资源个数分别为");BRACKETS;printf("[");YELLOW;printf("*b");BRACKETS;printf("]");ORI;printf("。\n\ \n\ ");RED;printf("如果你看不懂我在说什么,就在你不知道该怎么做的时候输入`");YELLOW;printf("-help -this");RED;printf("`。");ORI;printf("\n\");}}string stripSpace(string ori) // 去除指令中多余的空格{ string ans; int length=ori.size(); int loc=0,loc2=length-1; while(loc<ori.size()&&ori[loc]==' ')loc++; // 去除开头的空格 while(loc2>=0&&ori[loc2]==' ')loc2--; // 去除结尾的空格 for(;loc<=loc2;loc++) { if(ori[loc]==' '&&ori[loc-1]==' '); // 相邻的两个空格 else ans+=ori[loc]; } return ans;}void testForStripSpace() // 测试函数stripSpace(){ string s; while(getline(cin,s)) { cout<<"'"<<stripSpace(s)<<"'"<<endl; }}int Stoi(string s) // string->int, 不合法返回-1{ int ans=0; for(int i=0;i<s.size();i++) { if(s[i]>='0'&&s[i]<='9') { ans*=10; ans+=s[i]-'0'; } else // 不是数字 return -1; } return ans;}int len(string s) // 返回一个字符串的长度,实为为了int的重载{ return s.size();}int len(int n) // 返回一个数字的十进制的长度{ int ans=0; if(n==0)return 1; else if(n<0){ans++;n=-n;} while(n) { ans++; n/=10; } return ans;}void prt(int n, char c) // 打印n个c{ for(int i=0;i<n;i++) putchar(c);}void prt(int M0, int M1) // 打印一行 +--M0个--+--M1个--+{ TABLE; printf(" +"); prt(M0,'-'); putchar('+'); prt(M1,'-'); puts("+"); ORI;}void prt(Banker banker){ if(resources.empty()) // 无资源可打印 { if(lang==0)puts(" No data!"); else if(lang==1)puts(" 空"); return ; } int M0=0,M1=0; for(Banker::iterator it=banker.begin();it!=banker.end();it++) { M0=max(M0,len(it->first)); M1=max(M1,len(it->second)); } M0+=2,M1+=2; prt(M0,M1); // for(Banker::iterator it=banker.begin();it!=banker.end();it++) for(int i=0;i<resources.size();i++) { TABLE; printf(" | "); ORI; int l=len(resources[i]); cout<<resources[i]; prt(M0-1-l,' '); TABLE; printf("| "); ORI; l=len(banker[resources[i]]); cout<<banker[resources[i]]; prt(M1-1-l,' '); TABLE; puts("|"); ORI; prt(M0,M1); }}void prt(Needers needers) // 打印所有客户的信息{ if(needers.empty()) // 无资源可打印 { if(lang==0)puts(" No data!"); else if(lang==1)puts(" 空"); return ; } // for(Needers::iterator it=needers.begin();it!=needers.end();it++) for(int i=0;i<neederLog.size();i++) { RED; cout<<" * "; ORI; cout<<neederLog[i]<<": "; Needer thisNeeder=needers[neederLog[i]]; // for(Needer::iterator it2=thisNeeder.begin();it2!=thisNeeder.end();it2++) for(int i=0;i<resources.size();i++) { if(thisNeeder.count(resources[i])) // 兼容了中途打印,故需检测是否拥有此资源 { if(i)printf(", "); BRACKETS; putchar('['); ORI; pair<int,int> thisSourceNum=thisNeeder[resources[i]]; cout<<resources[i]<<" "<<thisSourceNum.first<<" "<<thisSourceNum.second; BRACKETS; putchar(']'); ORI; } } puts(""); }}void prt(string s, int n, int already) // 将字符串s每n个字符一行输出{ int sum=already; for(int i=0;i<s.size();i++) { if(sum>=n) { sum=0; printf("\n "); } cout<<s[i]; sum++; }}void prt(Banker banker, Needers needers){ if(lang==0) puts(" Banker:"); else if(lang==1) puts(" 银行家:"); prt(banker); if(lang==0) puts(" Needers:"); else if(lang==1) puts(" 客户们:"); prt(needers);}void showThis() // 显示`LetMeFly *>`{ cLetMeFly; printf(" LetMeFly "); switch (step) { case 0: RED;printf("banker");ORI;break; // 添加银行家资源 case 1: RED;printf("needer");ORI;break; // 添加客户(名) case 2: cout<<"needer ";DLB;cout<<temp[0]<<" ";RED;cout<<resources[locResource];ORI;break; // 为客户添加资源 case 3: RED;printf("apply");ORI;break; // 客户申请资源 default: /*An error occured*/ break; } printf("> ");}void help(int step) // 这一步的帮助{ switch (step) { case 0: // 添加银行家资源 if(lang==1) // 汉语 { printf(" ");RED;printf("· ");ORI;printf("添加资源:输入字符串");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf("和数字");BRACKETS;printf("[");YELLOW;printf("b");BRACKETS;printf("]");ORI;printf(",代表银行家手里有");BRACKETS;printf("[");YELLOW;printf("b");BRACKETS;printf("]");ORI;printf("个名字为");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf("的资源\n"); printf(" ");RED;printf("· ");ORI;printf("停止添加:输入continue,银行家资源设置结束\n"); } else if(lang==0) // 英语 { printf(" ");RED;printf("* ");ORI;printf("Add resource: input a string");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf(" and a num");BRACKETS;printf("[");YELLOW;printf("b");BRACKETS;printf("]");ORI;printf(" represents banker have\n"); printf(" Source ");BRACKETS;printf("[");YELLOW;printf("a");BRACKETS;printf("]");ORI;printf(" with a num of ");BRACKETS;printf("[");YELLOW;printf("b");BRACKETS;printf("]");ORI;printf(".\n"); printf(" ");RED;printf("* ");ORI;printf("Continue: Just input `");GREEN;printf("continue");ORI;printf("` to end setting banker's resource\n"); } break; case 1: // 给客户起名 if(lang==1) // 汉语 { printf(" ");RED;printf("·");ORI;printf(" 添加客户:输入一个不包含空格的字符串,代表客户名称\n"); printf(" ");RED;printf("·");ORI;printf(" 停止添加:输入");GREEN;printf("continue");ORI;printf(",客户添加结束\n"); } else if(lang==0) // 英语 { printf(" ");RED;printf("*");ORI;printf(" Add needer: Just input a string without a space in it\n"); printf(" which repersents the needer's name.\n"); printf(" ");RED;printf("*");ORI;printf(" Continue: Just input `");GREEN;printf("continue");ORI;printf("` to end adding needers\n"); } break; case 2: // 给客户添加资源 if(lang==1) // 汉语 { RED;printf(" · ");ORI; string toPrt="设置资源:两个整数,代表用户`"+temp[0]+"`的资源`"+resources[locResource]+"`的总需求量和已获得量\n"; prt(toPrt,40,3); // 可能会出现汉字一半的问题 } else if(lang==0) // 英语 { RED;printf(" * ");ORI; string toPrt="Set source: Input two nums which repersents needer`"+temp[0]+"`'s source `"+resources[locResource]+"`'s total and already num\n"; prt(toPrt,40,3); } break; case 3: // 客户申请资源 if(lang==1) // 汉语 { printf(" ");RED;printf("·");ORI;printf(" 申请资源:输入一些空格隔开的数字(个数必须和资源总数相同)\n"); printf(" 代表各个资源的申请量。\n"); } else if(lang==0) // 英语 { printf(" ");RED;printf("*");ORI;printf(" Apply resource: Enter some numbers separated by spaces (the number must\n"); printf(" be the same as the total number of resources)\n"); } break; default: /*An error occured*/ break; }}ToReturn split(string toSplit, char c) // 将字符串以字符c为间隔分开{ ToReturn ans; toSplit+=c; int left=0; for(int right=0;right<toSplit.size();right++) { if(toSplit[right]==c) //left->right-1 { ans.push_back(toSplit.substr(left,right-left)); left=right+1; } } return ans;}void testForSplit(){ string s; char c=' '; while(1) { getline(cin,s); ToReturn ans=split(s,c); BRACKETS; putchar('['); ORI; for(int i=0;i<ans.size();i++) { if(i)putchar(','); cout<<ans[i]; } BRACKETS; puts("]"); ORI; }}bool isSafe(Banker banker, Needers needers) //真正的银行家算法 之 是否安全 不引用是为了保护原有数据{ while(needers.size()) { for(Needers::iterator it=needers.begin();it!=needers.end();it++) { for(int i=0;i<resources.size();i++) { if(banker[resources[i]]<(it->second)[resources[i]].first-(it->second)[resources[i]].second) // 不能全部满足这个 { goto cannot; } } for(int i=0;i<resources.size();i++) // 可以全部贷给他 { banker[resources[i]]+=(it->second)[resources[i]].first; } needers.erase(it); goto could; // 重新从头开始遍历 cannot:; } return false;// 没有跳到could,全部找了一遍也不行 could:; } return true;}void init(){ CONSOLE_SCREEN_BUFFER_INFO CSBI; GetConsoleScreenBufferInfo(hCon,&CSBI); originalColor=CSBI.wAttributes; originalBackcolor=originalColor>>4; help(); showThis();}int main(){ init(); while(1) { string s; getline(cin,s); s=stripSpace(s); if(s==""){showThis();continue;} // 只按了回车 if(s=="exit"){puts("Bye~");break;} // exit-退出程序 else if(s=="-help")help(); // -help 打印帮助 else if(s=="-help -this")help(step); else if(s=="-set -lang Chinese"){lang=1;puts(" 已设置为中文。");} // 设置语言为中文 else if(s=="-set -lang English"){lang=0;puts(" Now in English.");} // 设置语言为英文 else if(s=="continue") // 完成此步骤 { if(step==0) // 不再添加银行家资源 { if(resources.empty()) // 还未添加任何资源 { if(lang==0)puts(" You should add the source first."); else if(lang==1)puts(" 你需要先添加资源再继续"); help(step); } else { step++; if(lang==1)puts(" 银行家资源添加完毕!银行家手中所拥有的资源有:"); else if(lang==0)puts(" Adding banker finished! What the banker have is:"); prt(banker); // 打印已有资源-表格形式 if(lang==1)puts(" 开始添加客户"); else if(lang==0)puts(" Begin to add the needer"); } } else if(step==1) // 正在输入客户名 { if(needers.empty()) // 还没有添加客户 { if(lang==0)puts(" Do you want a needer named `continue`?"),puts(" Just change it!"); else if(lang==1)puts(" 你想让一位客户叫`continue`吗?\n换一个名字吧。"); help(step); } else { step+=2; // 到申请资源那里 if(lang==1)puts(" 客户添加完毕!所有的客户情况为:"); else if(lang==0)puts(" Adding needer finished! All needers are:"); prt(needers); // 打印已有资源-表格形式 if(lang==1)puts(" 开始添加申请资源"); else if(lang==0)puts(" Begin to apply the source"); } } else if(step==2) // 正在为客户设置资源数量 { if(lang==0)puts(" You must set the source num of the needer\n You couldn't skip it!"); else if(lang==1)puts(" 客户资源数量必须设置,不能跳过"); help(step); } else if(step==3) // 申请资源 { if(lang==0)puts(" Already last step which cannot skip."); else if(lang==1)puts(" 已经是最后一步,不能跳过"); help(step); } } else if(s=="-help -show") // 显示目前资源情况 { if(step==0) // 正在添加银行家资源 { if(lang==0)puts(" What than banker have is:"); else if(lang==1)puts(" 银行家的资源有:"); prt(banker); } else if(step==1||step==3||step==2) // 正在添加客户名 或 正在执行资源申请 或 正在设置客户资源 { prt(banker,needers); } } else { ToReturn input; string name; int num1,num2; int num[resources.size()]; Needer needer; bool couldRelease=true; switch (step) { case 0: // 添加银行家资源 input=split(s,' '); // [name] [num] if(input.size()!=2)goto error00; name=input[0]; num1=Stoi(input[1]); if(num1==-1)goto error00; for(int i=0;i<resources.size();i++) if(resources[i]==name) goto error01; // 此资源名已存在 resources.push_back(name); banker[name]=num1; goto success0; error00: // 参数错误 if(lang==0)puts(" Parameter Error! You should input two Parameters"); else if(lang==1)puts(" 参数错误!请输入两个参数"); help(step); goto success0; error01: // 资源名重复 if(lang==1)puts(" 此资源名已存在!"); else if(lang==0)puts(" This resource name already exists"); help(step); goto success0; success0: break; case 1: // 添加客户,只需要输入客户名 locResource=0; input=split(s,' '); // [name] if(input.size()!=1)goto error10; name=input[0]; if(needers.count(name)) goto error11; // 此客户名已存在 needers[name]=needer; temp[0]=name; neederLog.push_back(name); goto success1; error10: // 名字中出现空格 if(lang==1) { cout<<" 您的意思是`"<<s<<"`吗?"<<endl; puts(" 很抱歉,认为规定名字不支持空格"); } else if(lang==0) { cout<<" Do you mean`"<<s<<"`?"<<endl; puts(" The name cannot include space"); } help(step); goto fail1; error11: // 此客户已存在 if(lang==1)puts(" 此客户名已存在!"); else if(lang==0)puts(" This needer already exists"); help(step); goto fail1; success1: step++;break; fail1:break; case 2: // 为此客户设置资源数量 input=split(s,' '); // [num1, num2] if(input.size()!=2)goto error20; num1=Stoi(input[0]); num2=Stoi(input[1]); if(num2>num1)goto error21; // 已有量>总需求量 // if(num1>banker[resources[locResource]])goto error22; // 总需求量≥银行家总资源 needers[temp[0]][resources[locResource]]=pair<int,int>(num1,num2); goto success2; error20: // 参数不为2 if(lang==0)puts(" Parameter Error! You should input two Parameters"); else if(lang==1)puts(" 参数错误!请输入两个参数"); help(step); goto fail2; error21: // 已有量≥总需求量 if(lang==0)puts(" What you have should less than or equal to what you need"); else if(lang==1)puts(" 已有量应小于等于总需求量"); help(step); goto fail2; // error22: // 总需求量≥银行家总资源 // if(lang==0)puts(" what you want is already more than the what the banker have"); // else if(lang==1)puts(" 你的需求量大于了银行家的资源总量"); // help(step); // goto fail2; success2: if(locResource>=resources.size()-1) step=1,locResource=0; // 此客户设置完毕 else locResource++; break; fail2:break; case 3: // 申请资源 input=split(s,' '); // [*num] if(input.size()!=resources.size()+1)goto error30; // 申请资源种数≠资源总数 name=input[0]; if(needers.count(name)==0)goto error31; // 无此needer needer=needers[name]; for(int i=0;i<resources.size();i++) { num[i]=Stoi(input[i+1]); if(num[i]>needer[resources[i]].first) // 申请大于总需,用num1来存错误下标 { num1=i; goto error32; } if(num[i]>needer[resources[i]].first-needer[resources[i]].second) // 申请大于还需,同样用num1存下来 { num1=i; goto error33; } if(num[i]>banker[resources[i]]) // 申请大于银行家资源,无法满足 { num1=i; goto cannot34; } } couldRelease=true; for(int i=0;i<resources.size();i++) { banker[resources[i]]-=num[i]; needers[name][resources[i]].second+=num[i]; if(needers[name][resources[i]].second!=needers[name][resources[i]].first)couldRelease=false; } if(couldRelease) // 这个needer满足了,可以必可以满足他,释放他 { for(int i=0;i<resources.size();i++) { banker[resources[i]]+=needers[name][resources[i]].first; // 还给银行 } needers.erase(name); // 删除此人 for(NeederLog::iterator it=neederLog.begin();it!=neederLog.end();it++) { if(*it==name) { neederLog.erase(it); break; } } if(needers.empty()) // 全部还完 { goto success31; } goto success32; // 此人还完 } if(isSafe(banker,needers)) // 贷给此人 { goto success33; } else // 不给 { for(int i=0;i<resources.size();i++) // 收回 { banker[resources[i]]+=num[i]; needers[name][resources[i]].second-=num[i]; } goto fail34; } goto success0; error30: // 申请资源种数≠资源总数 if(lang==0)printf(" Parameter Error! You should input %d Parameters\n",resources.size()+1); else if(lang==1)printf(" 参数错误!请输入%d个参数\n",resources.size()+1); help(step); goto fail3; error31: // 无此needer if(lang==0)printf(" We don't have a user named `%s`\n",name.c_str()); else if(lang==1)printf(" 没有客户`%s`\n",name.c_str()); help(step); goto fail3; error32: // 申请大于总需 if(lang==0)printf(" the %d-th apply %d is more than the total need %d\n",num1+1,num[num1],needer[resources[num1]].first); else if(lang==1)printf(" 第%d个申请%d大于客户总需求量%d\n",num1+1,num[num1],needer[resources[num1]].first); help(step); prt(banker,needers); goto fail3; error33: // 申请大于还需 if(lang==0)printf(" the %d-th apply %d is more than the still need %d\n",num1+1,num[num1],needer[resources[num1]].first-needer[resources[num1]].second); else if(lang==1)printf(" 第%d个申请%d大于客户还需求的量%d\n",num1+1,num[num1],needer[resources[num1]].first-needer[resources[num1]].second); help(step); prt(banker,needers); goto fail3; cannot34: // 申请大于还需 if(lang==0){printf(" The apply is ");PURPER;printf("denied");ORI;printf(", because the %d-th apply %d is more than\n banker's total source %d\n",num1+1,num[num1],banker[resources[num1]]);} else if(lang==1){printf(" 申请被");PURPER;printf("拒绝");ORI;printf(",因为第%d个申请%d大于银行家总资源数%d\n",num1+1,num[num1],banker[resources[num1]]);} help(step); prt(banker,needers); goto fail3; success31: // 完全贷完 if(lang==0){RED;printf(" Success! you have satisfied all the needers! Goodbye~\n");ORI;} else if(lang==1){RED;printf(" 祝贺!你满足了所有的客户! 后会有期~\n");ORI;} system("pause"); return 0; goto success3; success32: // 此用户全部满足 if(lang==0){GREEN;printf(" Permit");ORI;printf("! after that the needer is satisfied\n");} else if(lang==1){GREEN;printf(" 满足");ORI;printf("!之后就满足了这位用的户的所有需求\n");} prt(banker,needers); goto success3; success33: // 满足此用户此次需求 if(lang==0){GREEN;printf(" Permit!\n");ORI;} else if(lang==1){GREEN;printf(" 满足!\n");ORI;} prt(banker,needers); goto success3; fail34: // 不满足此用户此次需求 if(lang==0){PURPER;printf(" Denied!\n");ORI;} else if(lang==1){PURPER;printf(" 不满足!\n");ORI;} prt(banker,needers); goto fail3; success3: break; fail3:break; default: break; } } // else {puts("Error! unknown order!"); help(step);} // 错误命令 showThis(); } return 0;}
