- The contestant tries to solve to puzzle by guessing one letter at a time.//参赛者每次猜一个字母
- Every time a guess is correct, all the characters in the word that match the guess will be``turned over.'' For example, if your guess is ``o'' and the word is ``book'', then both ``o''s in thesolution will be counted as ``solved.''//像电视娱乐节目中演示的那样,一个单词的每一个字母都是一块牌子,当参赛者猜对一个字母时,答案中词汇的所有该字母都会被翻过来,胜利应该是能够得到所有的字母都被翻过来,但是胜利又不仅仅是无限的猜,一直到猜对为止的。
- Every time a wrong guess is made, a stroke will be added to the drawing of a hangman, whichneeds 7 strokes to complete. Each unique wrong guess only counts against the contestant once.//看看图画中的小人,一共由7笔组成,每猜错一个字母,就在这个绞刑架上的小人的位置画一笔,直到七笔完成这个小人,也就是hangman完成
//注意红色字体部分是关键:每一个错误猜测,如果它不唯一,则,都计算为参赛者的同一次错误,即如果猜错了,但是之前他有过一模一样的错误,则不重新记为新错误。
______ | | | O | /|\ | | | / \ __|_ | |______ |_________|
- If the drawing of the hangman is completed before the contestant has successfully guessed allthe characters of the word, the contestant loses.//如果猜错的次数首先达到了7次,然而答案中的字母还是没有全部猜出来时,失败。
- If the contestant has guessed all the characters of the word before the drawing is complete, thecontestant wins the game.//如果字母全部被猜中,此时,错误次数未达到7次,则胜利。
- If the contestant does not guess enough letters to either win or lose, the contestant chickens out.//字母也没有全部猜中,失败次数也没有达到7次的时候,说明他中途逃跑了。
这道题目是比较有歧义的一道典型问题,字符串处理是常规问题,你会发现很容易编出一段代码,能够实现实例的运行,但是你同样会发现像歌词说的:WA没有那么容易。本题WA的原因,有很多。在你能够有思路很快编完一段代码却怎么也不是AC的时候,有以下几点细节部分需要注意:
1、关于成功失败的判定的看法。
由4、5、6点可知还有一个问题:如果while完毕之后,win也达到了全部猜对,fail也达到了7,那此时你该判定他是赢还是输。所以这不是简单的计数器累加,到最后判定比较的问题。需要在判定胜负的过程中,从答案的第一个字母开始向后处理,猜对win++,猜错fail++,就有一个“是win先达到全部猜对,还是fail先打到hangman完成”的问题。也就是说并不是先全部计算完win有多少,fail有多少再去比较成功或是失败,而是一种只要达到一个条件就不用继续向下比较的问题。
如果在比较过程中,是win首先达到了全部猜对,就不往下面继续比较了,虽然继续比较你会发现fail也可能会到7;
或者fail首先达到了7,也不用继续比较了,因为人已经死了,即使后面你会发现他的win再往后猜也会全部匹配,但都没用了。
这里显然是一个随循环判定,达到某一条件,就break,不再比较,直接输出结果。
2、如何判定胜出。在循环体完成之后就要判定输出信息。胜出,失败,逃跑,他们本身是一种互斥的关系,所以用if-else。
3、如果像我一样用到了字符串的find函数。关于find函数:string的find函数的调用是C++风格的,要用stringName.find(char ,startIndex),既可以查找字符在字符串中的位置,又可以查找字符串在字符串中的位置。但是都注意的是,如果在自符串中定位寻找未成功,即查找失败,返回值并不是经常用到的0或是-1,而是一个超过字符串长度域的一个值,在C++中用stringName.npos 来表示查找失败的返回值。
int find(char c, int pos = 0) const;//从pos开始查找字符c在当前字符串的位置
int find(const char *s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
int find(const char *s, int pos, int n) const;//从pos开始查找字符串s中前n个字符在当前串中的位置
int find(const string &s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
//查找成功时返回所在位置,失败返回string::npos的值
int rfind(char c, int pos = npos) const;//从pos开始从后向前查找字符c在当前串中的位置
int rfind(const char *s, int pos = npos) const;
int rfind(const char *s, int pos, int n = npos) const;
int rfind(const string &s,int pos = npos) const;
//从pos开始从后向前查找字符串s中前n个字符组成的字符串在当前串中的位置,成功返回所在位置,失败时返回string::npos的值
int find_first_of(char c, int pos = 0) const;//从pos开始查找字符c第一次出现的位置
int find_first_of(const char *s, int pos = 0) const;
int find_first_of(const char *s, int pos, int n) const;
int find_first_of(const string &s,int pos = 0) const;
//从pos开始查找当前串中第一个在s的前n个字符组成的数组里的字符的位置。查找失败返回
string::npos int find_first_not_of(char c, int pos = 0) const;
int find_first_not_of(const char *s, int pos = 0) const;
int find_first_not_of(const char *s, int pos,int n) const;
int find_first_not_of(const string &s,int pos = 0) const;
//从当前串中查找第一个不在串s中的字符出现的位置,失败返回
string::npos int find_last_of(char c, int pos = npos) const;
int find_last_of(const char *s, int pos = npos) const;
int find_last_of(const char *s, int pos, int n = npos) const;
int find_last_of(const string &s,int pos = npos) const;
int find_last_not_of(char c, int pos = npos) const;
int find_last_not_of(const char *s, int pos = npos) const;
int find_last_not_of(const char *s, int pos, int n) const;
int find_last_not_of(const string &s,int pos = npos) const;
//find_last_of和find_last_not_of与find_first_of和find_first_not_of相似,只不过是从后向前查找
AC代码如下://虽然这段代码可以AC通过,但是我认为自己的程序还是有漏洞的:因为本来判定字符匹配的过程中是从前往后匹配的,但是,在自己写的去重函数中显然,对于重复的字母,是选取最后一个来保存的,所以去重之后的顺序有所改变,如:cheese去重之后是chse,那么如何进行改进呢?
#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;
string simplify(string str)//string类型字符串去出其中重复的部分;
{
char uniq[500];
int i,j=0;
for(i=0;i<str.length();i++)
{
if(str.find(str[i],i+1)!=str.npos)
continue;
else
{
uniq[j]=str[i];
j++;
}
}
uniq[j]='\0';
return str.assign(uniq);
}
int main()
{
int i;
int win=0,fail=0,num;
int round;
string solution,answer;
string solution2,answer2;
scanf("%d",&round);
while(round!=-1)
{
cin>>solution;
cin>>answer;
solution2=simplify(solution);
answer2=simplify(answer);
num=solution2.length();
for(i=0;i<answer2.length();i++)
{
if(solution2.find(answer2[i],0)!=solution2.npos)
{
win++;
if(win==num) break;
}
else
{
fail++;
if(fail>6) break;
}
}
// for(i=0;i<answer.length();i++)
// if(solution2.find(answer[i],0)=solution2.npos)
//这是错误代码部分,注意:无论判定猜测正确还是判定猜测错误,都是不重复累计的。
// fail++;
printf("Round %d\n",round);
if(win==num)
printf("You win.\n");
else if(fail>6)
printf("You lose.\n");
else
printf("You chickened out.\n");
scanf("%d",&round);
win=0;
fail=0;
}
return 0;
}
//这是自己改进之后的去重函数,这就没有担心的漏洞问题了,同样AC:
string simplify(string str)//string类型字符串去出其中重复的部分;固化函数
{
char uniq[500];
int i,j=1;
uniq[0]=str[0];
for(i=1;i<str.length();i++)
{
if(str.rfind(str[i],i-1)!=str.npos)
continue;
else
{
uniq[j]=str[i];
j++;
}
}
uniq[j]='\0';
return str.assign(uniq);
}