追求工作,我被要求解决HackerRank.com上的问题,编写一个接受字符串的函数,计算其中的字符并返回找到的最常见字符。我写了我的解决方案,修复了错别字,它适用于我的测试用例和他们的测试用例,除了它没有“测试7”。因为它是一个面试协议,HackerRank并没有告诉我失败的细节,只是它失败了。
我花了太多时间试图找出原因。我已经三重检查了一个一个错误,编写了8位字符的代码,但尝试接受16位值而不改变结果。这是我的代码。我不能给出错误,只是有错误。
可能是多字节字符吗?
如何创建一个包含2字节或3字节字符的测试用例?
我输入了一些显示转储代码,结果正是您所期望的。我的桌面上有Mac XCode IDE,欢迎任何建议!
/*
* Complete the function below.
*/
char func(string theString) {
// I wonder what I'm doing wrong. 256 doesn't work any better here.
const int CHARS_RECOGED = 65536; // ie 0...65535 - even this isn't good enough to fix test case 7.
unsigned long alphaHisto[CHARS_RECOGED];
for (int count = 0; count < CHARS_RECOGED; count++ ) {
alphaHisto[ count ] = 0;
} // for int count...
cout << "size: " << theString.size() << endl;
for (int count = 0; count < theString.size(); count++) {
// unsigned char uChar = theString.at(count); // .at() better protected than [] - and this works no differently...
unsigned int uChar = std::char_traits<char>::to_int_type(theString.at(count)); // .at() better protected than []
alphaHisto[ uChar ]++;
} // for count...
unsigned char mostCommon = -1;
unsigned long totalMostCommon = 0;
for (int count = 0; count < CHARS_RECOGED; count++ ) {
if (alphaHisto[ count ] > totalMostCommon){
mostCommon = count;
totalMostCommon = alphaHisto[ count ];
} // if alphahisto
} // for int count...
for (int count = 0; count < CHARS_RECOGED; count++ ) {
if (alphaHisto[ count ] > 0){
cout << (char)count << " " << count << " " << alphaHisto[ count ] << endl;
} // if alphaHisto...
} // for int count...
return (char) mostCommon;
}
// Please provide additional test cases:
// Input Return
// thequickbrownfoxjumpsoverthelazydog e
// the quick brown fox jumps over the lazy dog " "
// theQuickbrownFoxjumpsoverthelazydog e
// the Quick BroWn Fox JuMpS OVER THe lazy dog " "
// the_Quick_BroWn_Fox.JuMpS.OVER..THe.LAZY.DOG "."
答案 0 :(得分:3)
如果测试是严肃的,则应指定字符集。没有,假设一个字节是一个字符可能是安全的。正如旁注所示,为了支持具有多字节字符的字符集,与65536交换256远远不够,但即使没有多字节字符,您也可以与1<<CHAR_BITS
交换256,因为“字节”可能超过8位。
我看到了一个更重要的问题
unsigned int uChar = std::char_traits<char>::to_int_type(theString.at(count));
首先,它是不必要的复杂:
unsigned int uChar = theString.at(count);
应该够了。
现在请记住,std::string::at
会返回char
,而您的变量为unsigned int
。 char
意味着没有明确说明它是有符号还是无符号取决于编译器(即,如果它是signed char
或unsigned char
)。现在,保存0到127之间的char值而不更改目标变量,但这只是值范围的一半:如果char
未签名,128-255也可以正常工作,但签名字符,即。介于-128和-1之间,如果目标变量大于char ,则不会映射到无符号128-255 。使用4字节整数,您将获得一些巨大的值,这些值不是您的数组的有效索引=&gt;问题。解决方案:使用char
,而不是int
。
unsigned char uChar = theString.at(count);
另一件事:
for (int count = 0; count < theString.size(); count++)
theString.size()
会返回一个size_t
,与int
相比,它可能具有不同的大小和/或签名,因此可能存在巨大的字符串长度问题。因此,字数统计数字也可能是size_t
而不是unsigned long
...
最不可能的问题来源,但如果这在没有二补码的机器上运行,则 它可能会非常失败(尽管我没有仔细考虑过)