【问题标题】:Occurrences of same alternative characters in a CString在 CString 中出现相同的替代字符
【发布时间】:2022-07-11 01:42:25
【问题描述】:

我是 C++ 编程的新手,这是我必须做的任务,但即使在尝试和尝试之后我也无法获得所需的输出。任何人都可以查看代码并让我知道应该做什么,我知道我的代码不完整,但我不知道如何从这里开始。

任务:编写一个程序,仅使用函数,具有以下特征。

  1. 程序从控制台读取段落并存储在字符串中。
  2. 程序然后计算出现在段落的任何单词中的双字母的出现次数,并输出字符及其出现次数。
  3. 如果双字母出现多次,则程序应仅显示一次以及其在段落中的总频率。
  4. 输出字母必须按顺序排列。 样本输入(文件): 双泡在牙海深处用牙与谜语相遇。 样本输出: BB 1 dd 1 EE 3 哦 1

    这是我的代码:

    #include <iostream>
    #include <conio.h>
    #include <cstring>
    #include <ctime>
    
    using namespace std;
    
    int counter = 0;
    char alphabets[26] = { 0 };
    void alternatives();
    
    int main() {
        alternatives();
        _getch();
    
        return 0;
    }
    
    void alternatives() {
        char str[] = \"Double bubble deep in the sea of tooth with teeth and meet with riddle.\";
        int count = 0;
    
        for (int j = 0; j < strlen(str); j++)
            str[j] = tolower(str[j]);
    
        for (int i = 0; i < strlen(str); i++) {
            if (str[i] == str[i + 1]) {
                counter++;
                cout << str[i] << str[i + 1] << \"\\t\" << counter << endl;
            }
    
            counter = 0;
        }
    }
    

    输出:

    贝贝 1 1 欧1 德 1 1 dd 1

  • 注意:CString,具有特定大小写表示something different but similar enough to cause confusion
  • i == strlen(str) - 1str[i + 1] 将是str[strlen(str)],这是一个越界访问。您可以从i = 1 循环并比较str[i-1] == str[i]
  • 使用alphabets。不要做counter++,而是做alphabets[str[i] - \'a\']++。并且不要在第二个for 循环中执行cout。使用第三个循环打印alphabets
  • 您将在这里需要一些额外的数据结构。也许像std::unordered_map 这样的字符从字符到该字符加倍出现在您的文本中的次数。您是否希望单个 counter 变量能够为单独的字母存储单独的值?你还需要不是打印任何内容,直到您完成整个段落的扫描,因为您不应该多次打印同一个有向图,并且您不知道给定有向图的正确计数是多少,直到您到达文本的结尾。
  • @rturrado 这不是未定义的行为/越界访问。 C 字符串以 null 结尾,因此访问 str[strlen(str)] 指的是终止 0 字符。在您描述的场景中,字符比较 str[i] == str[i + 1] 永远不会产生 true,但是读取访问不会导致未定义的行为。

标签: c++ arrays c-strings


【解决方案1】:

你有 26 个字母(我假设)所以你需要 26 个计数。一个简单的数组就可以了

int counters[26] = { 0 }; // initialise all counts to zero

现在,当您发现重复的字母时,您需要增加适当的计数,例如

for (int i = 0; i < strlen(str); i++)
{
    char letter = str[i];
    if (letter >= 'a' && letter <= 'z' && // is it a letter and
        letter == str[i + 1])             // is it repeated?
    {
        counters[letter - 'a']++;         // increment count
    }
}

注意使用letter - 'a' 来获取计数数组的偏移量

最后需要输出结果

for (char letter = 'a'; letter <= 'z'; ++letter)
{
     int count = counters[letter - 'a'];
     if (count > 0)
         cout << letter << letter << ' ' << count << ' ';
}
cout << '\n';

不完美,但希望能帮助您入门。这是未经测试的代码。

【讨论】:

  • 是的,是的,我明白了……非常感谢约翰
【解决方案2】:

您可以使用长度为 26 的 int 数组来跟踪重复的字母实例。然后,您可以遍历 C 字符串并检查是否有重复。如果你找到了,请确保向前跳转你的迭代器。

#include <iostream>
#include <cstring>

int main() {
    int repeats[26] = {0};

    char str[] = "Double bubble deep in the sea of tooth with teeth and meet with riddle.";
    for (char *ch = str; *ch; ch++)
        *ch = tolower(*ch);

    for (char *ch = str; *ch; ch++) {
        if (std::isalpha(*ch) && *ch == ch[1]) {
            repeats[*ch - 'a']++;
            ch++;
        }
    }

    for (size_t i = 0; i < 26; i++) {
        std::cout << static_cast<char>('a' + i) << ": " << repeats[i] << std::endl;
    }

    return 0;
}

结果:

a: 0
b: 1
c: 0
d: 1
e: 3
f: 0
g: 0
h: 0
i: 0
j: 0
k: 0
l: 0
m: 0
n: 0
o: 1
p: 0
q: 0
r: 0
s: 0
t: 0
u: 0
v: 0
w: 0
x: 0
y: 0
z: 0

【讨论】:

    猜你喜欢
    • 2013-06-15
    • 1970-01-01
    • 1970-01-01
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 2021-08-30
    相关资源
    最近更新 更多