在下面的代码中,每当我去调试器时,段落的值被删除,或者返回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;
}
}
答案 0 :(得分:3)
总之,所有问题都是由于您滥用sizeof
。
sizeof(paragraph)
没有做你认为它正在做的事情:它返回string
类的大小,而不是字符串实例中的字符数。
您应该使用paragraph.size()
而不是假设它是std::string
类型。
sizeof(alphabet)
以幸运巧合返回数组中元素的数量:标准的sizeof(char)
定义为1.这样的&#34; ace&#34 ;代码应附加评论!
sizeof(counter)
你不是很幸运。您获得的价值是sizeof(int)
的倍数,因平台而异(2,4和8很常见)。您应该写sizeof(counter) / sizeof(int)
或sizeof(counter) / sizeof(counter[0])
。后者是一些人喜欢的,因为你不需要硬编码类型,因为C ++标准不允许零长度数组,counter[0]
定义明确。
(这里要记住的是sizeof
在编译时进行评估。
答案 1 :(得分:3)
易。循环条件中的sizeof(counter)
实际上是sizeof(int) * 26
,所以你的字母表被你的循环压缩(从迭代27开始),还有一些堆栈(特别是将返回地址设置为0,以及paragraph
参数的内部。
您的- 1
不应该在那里,因为您正在使用严格的比较。
您可能想要追踪第一个循环并观察sizeof(counter)
的值。
如果您想要counter
数组中的元素数量,那么使用它的惯用方法是sizeof(counter) / sizeof(counter[0])
。
此外,string
的长度应该由paragraph.size()
获得,因为sizeof(paragraph)
返回管理字符串的对象的大小,而不是字符串本身。
最后,sizeof(alphabet)
做了正确的事,因为sizeof(char)
被定义为1。
现在,对于某些C ++ 11魔术:
#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;
}
这会删除许多(全部)sizeof
个陷阱,同时效率很高。
答案 2 :(得分: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
中声明的标准算法<algorithm>
。例如
int ewsult = *std::max_element( counter, counter + 26 );