C ++函数中的错误,它返回字符串中最常见的字符。多字节字符?

时间:2015-06-13 00:11:45

标签: c++ string count char

追求工作,我被要求解决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 "."

1 个答案:

答案 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 intchar意味着没有明确说明它是有符号还是无符号取决于编译器(即,如果它是signed charunsigned 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 ...

最不可能的问题来源,但如果这在没有二补码的机器上运行,则 它可能会非常失败(尽管我没有仔细考虑过)