leecode 解题总结:299. Bulls and Cows

#include 
#include 
#include 
#include 
#include 
using namespace std;
/*
问题:
You are playing the following Bulls and Cows game with your friend: You write down a number and ask your friend to guess what the number is. Each time your friend makes a guess, you provide a hint that indicates how many digits in said guess match your secret number exactly in both digit and position (called "bulls") and how many digits match the secret number but locate in the wrong position (called "cows"). Your friend will use successive guesses and hints to eventually derive the secret number.

For example:

Secret number:  "1807"
Friend's guess: "7810"
Hint: 1 bull and 3 cows. (The bull is 8, the cows are 0, 1 and 7.)
Write a function to return a hint according to the secret number and friend's guess, use A to indicate the bulls and B to indicate the cows.
In the above example, your function should return "1A3B".

Please note that both secret number and friend's guess may contain duplicate digits, for example:

Secret number:  "1123"
Friend's guess: "0111"
In this case, the 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a cow, and your function should return "1A1B".
You may assume that the secret number and your friend's guess only contain digits, and their lengths are always equal.

分析:
公牛:有多少位是正确的同时位置也是正确的。
母牛:有多少位在所猜的数中,但是位置是错误的
注意:母牛=所有匹配的个数-公牛个数
      公牛=位置上相等的元素个数
	  用A表示公牛,B表示母牛,形成
	  xxAxxB这种形式作为提示
此题本质上就是一个字符串查找的问题。
难点在于母牛的个数寻找,即有多少个匹配的个数。
这个可以通过哈希map来确定。
map1来扫描一遍正确答案,得到每个字符出现次数。
map2扫描一遍猜的答案,遍历该答案中每个字符,如果
遍历map2每个元素,如果能够在map1中找到,则取两者值中的
较小的作为真正匹配的个数,不断累加即可。
通过位置比较是否相等确定公牛个数

输入:
1807 7810
1123 0111
0000 1111
0000 0000
输出:
1A3B
1A1B
0A0B
4A0B
*/

class Solution {
public:
    string getHint(string secret, string guess) {
		//如果正确答案为空,则此题无法给出答案,返回为空
		if(secret.empty())
		{
			return "";
		}
		//如果正确答案存在,但是猜的答案为空,需要给出提示是0A0B
		else if(guess.empty())
		{
			return "0A0B";
		}
		//计算公牛
		int secretLen = secret.length();
		int guessLen = guess.length();
		int minLen = min(secretLen , guessLen);
		int bull = 0;
		for(int i = 0 ; i < minLen ; i++)
		{
			if(secret.at(i) == guess.at(i))
			{
				bull++;
			}
		}
		
		//统计母牛
        unordered_map correctCharToTimes;
		char ch;
		for(int i = 0 ; i < secretLen ; i++)
		{
			ch = secret.at(i);
			//如果找到,累加
			if(correctCharToTimes.find(ch) != correctCharToTimes.end() )
			{
				correctCharToTimes[ch]++;
			}
			else
			{
				correctCharToTimes[ch] = 1;
			}
		}
		unordered_map charToTimes;
		for(int i = 0 ; i < guessLen ; i++)
		{
			ch = guess.at(i);
			//如果找到,累加
			if(charToTimes.find(ch) != charToTimes.end() )
			{
				charToTimes[ch]++;
			}
			else
			{
				charToTimes[ch] = 1;
			}
		}		
		//统计两个map。对于每个键,选取两个值中较小的
		int cow = 0;
		for(unordered_map::iterator it = charToTimes.begin() ; it != charToTimes.end() ; it++)
		{
			ch = it->first;
			if(correctCharToTimes.find(ch) != correctCharToTimes.end() )
			{
				cow += min(it->second , correctCharToTimes[ch]);
			}
		}
		
		//真正的母牛个数需要减去公牛个数
		cow -= bull;
		string result = to_string(bull) + "A" + to_string(cow) + "B";
		return result;
    }
};

void process()
{
	 Solution solution;
	 string secret;
	 string guess;
	 string result;
	 while(cin >> secret >> guess )
	 {
		 result = solution.getHint(secret , guess);
		 cout << result << endl;
	 }
}

int main(int argc , char* argv[])
{
	process();
	getchar();
	return 0;
}


你可能感兴趣的:(leecode)