字符串中字符的最大出现频率

4
#include<bits/stdc++.h>
#include<cstring>
#define arraySize 10

using namespace std;
char returnMaxOccur(char *str);

int main()
{
    char str[]="teet";
    cout<<"The max occuring character is"<<" "<<returnMaxOccur(str)<<endl;
    return 0;
}

char returnMaxOccur(char* str)
{
    int high=-1;
    char t;
    int counter[arraySize]={0};

    int len=strlen(str);

    for(int i=0;i<len;i++)
    {
        counter[str[i]]++;
    }


    for(int i=0;i<len;i++)
    {
        if(high<counter[str[i]])
        {
            high=counter[str[i]];
            t=str[i];
        }
    }
    return t;
}

在下面的问题中,当包含#include<bits/stdc++.h>时,输入字符串的结果如下:
1)teet: ans is t  
2)eett: ans is e  
3)ttee: ans is t  
4)ette: ans is e  

但是当我使用#include<iostream>替代#include<bits/stdc++.h>时,结果如下:

1)teet: ans is e  
2)eett: ans is t  
3)ttee: ans is t  
4)ette: ans is e  

这种行为的原因是什么,或者我做错了什么吗?

4
为什么不应该包含<bits/stdc++.h>头文件? - πάντα ῥεῖ
2
str[i]arraysize(10)大得多,这将导致未定义行为 - UnholySheep
使用std::string来表示字符串。使用std::map<char,int>来计数。 - user2672107
3个回答

6
这是一个典型的未定义行为如何表现出看似奇怪的行为的案例。
实际上,包含不同的头文件可能会影响内存中某些位置的字节,当您使用可以一直增加到255的索引 counter(大小为10)时意外观察到这些字节。
传统的方法是使用 std::map<char, int>,它可以有效地作为“稀疏数组”来使用。如果失败了,只需确保您的int []中有足够的“插槽”来容纳每个可能的输入。
(而且,在我看来,您根本不应该使用 bits/stdc++.h。)

1
第一件重要的事情是你的代码不正确。请按照以下方式进行更正:
而不是
#define arraySize 10

使用
#define arraySize 128

作为str[i]可能是任意字符(我假设是ASCII字符从0127)。
然后再更改#include语句进行测试。
第二个 - 通常更重要的 - 就像πάντα ῥεῖ在他的链接中表达的那样(为什么不应该#include?)。

str包含字母时(如OP的情况),这将帮助很少。 - Angew is no longer proud of SO
@Angew - 我不明白你的意思 - 它会将错误代码(越界索引)更改为正确的代码,尽管在 str 中使用了符号。请注意,我的替换周围有撇号 (0) 。 - MarianD
't' - '0' > 9点击此处查看实时演示。只有当str被限制为数字时,您的修复才会起作用。 - Angew is no longer proud of SO
@Angew - 哦,你说得对,谢谢!我要编辑我的答案。 - MarianD

0
i=0 时,counter[str[i]]++ 等同于 counter[116]++,但是 counter 数组大小为10。所以代码 counter[116]++ 修改了任意内存地址。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接