0

在下面的代码中,每当我进入调试器时,段落的值都会被删除,或者返回 0,我似乎无法弄清楚为什么,想法?

void getFreqLetter(string paragraph){
    char alphabet[26] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
    int counter[26];
    //set counter values to zero
    for (int clear = 0; clear < sizeof(counter) - 1; ++clear){
        counter[clear] = 0;
    }
    cout << paragraph;
    int result = 0;
    for (int i = 0; i < sizeof(paragraph); ++i){
        //case:found
        for (int j = 0; j < sizeof(alphabet) - 1; ++j){
            if (alphabet[j] == paragraph[i]){
                counter[j]++;
            }
        }
        //go through array find largest value
        for (int k = 0; k < sizeof(counter) - 1; ++k){
            if (counter[k] > result){ result = counter[k]; }
        }
        cout << result;
    }
}
4

3 回答 3

3

In summary, all the problems are due to your misusing sizeof.

sizeof(paragraph) is not doing what you think it's doing: it is returning the size of the string class, not the number of characters in the string instance.

You should use paragraph.size() instead assuming it's a std::string type.

sizeof(alphabet) returns the number of elements in the array by a lucky coincidence: sizeof(char) is defined by the standard to be 1. Such "ace" code ought to have a comment attached to it!

You're not so lucky with sizeof(counter). The value you're getting back is a multiple of sizeof(int) which varies from platform to platform (2, 4, and 8 are common). You should write either sizeof(counter) / sizeof(int) or sizeof(counter) / sizeof(counter[0]). The latter is preferred by some folk since you don't need to hardcode the type and since zero length arrays are disallowed by the C++ standard, counter[0] is well-defined.

(Something to bear in mind here is that sizeof is evaluated at compile-time).

于 2014-09-10T07:56:30.507 回答
3

Easy. your sizeof(counter) in the loop condition is actually sizeof(int) * 26, so your alphabet is crushed by your loop (from iteration 27 on), and some of the stack also (setting the return address to 0 in particular, and the internals of the paragraph parameter).

And your - 1 should not be there, since you're using strict comparison.

You may want to trace through the first loop and observe the value of sizeof(counter).

If you want the number of elements in your counter array, an idiomatic way of having it is sizeof(counter) / sizeof(counter[0]).

Also, the length of the string should be obtained by paragraph.size(), because sizeof(paragraph) returns the size of the object managing the string, not the string itself.

Finally, the sizeof(alphabet) does the right thing, because sizeof(char) is defined as 1.

And now, for some C++11 magic:

#include <array>

const std::array<char,26u> alphabet{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 
    'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 
    's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
std::array<int, 26u> counter;
//set counter values to zero
for (int clear = 0; clear < counter.size(); ++clear){
    counter[clear] = 0;
}

This removes many (all) of the sizeof traps, while being as efficient.

于 2014-09-10T07:57:14.890 回答
0

这段代码

//set counter values to zero
for (int clear = 0; clear < sizeof(counter) - 1; ++clear){
    counter[clear] = 0;
}

无效并导致内存覆盖。

要么使用

for (int clear = 0; clear < sizeof( counter ) / sizeof( *counter ); ++clear){
    counter[clear] = 0;
}

或者

for (int clear = 0; clear < 26; ++clear){
    counter[clear] = 0;
}

或者

std::memset( counter, 0, 26 * sizeof( int ) );

或者在声明数组时简单地将数组初始化为零

int counter[26] = {};

这个循环

for (int j = 0; j < sizeof(alphabet) - 1; ++j){
    if (alphabet[j] == paragraph[i]){
        counter[j]++;
    }

也是无效的。字符数组alphabet不包含终止零。所以循环应该写成

for (int j = 0; j < sizeof(alphabet); ++j){
    if (alphabet[j] == paragraph[i]){
        counter[j]++;
    }

而且这个循环是无效的

for (int k = 0; k < sizeof(counter) - 1; ++k){
    if (counter[k] > result){ result = counter[k]; }
}

看上面。

如果您将命名常量用于幻数 26,则不会出错。

例如

const int N = 26;

char alphabet[N] = 
{ 
   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 
   'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' 
};

//...

for ( int j = 0; j < N; ++j )
{
        if (alphabet[j] == paragraph[i]){
            counter[j]++;
}

std::max_element要找到最大的数字,您可以使用在 header 中声明的标准算法<algorithm>。例如

int ewsult = *std::max_element( counter, counter + 26 );
于 2014-09-10T08:08:03.380 回答