银行家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 blue
typedef 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;
}
xxxxxxxxxx
banker 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;
}