【问题标题】:A tricky bug in my C++ code; How to fix it?我的 C++ 代码中有一个棘手的错误;如何解决?
【发布时间】:2015-03-13 11:00:01
【问题描述】:

我在下面为一个小程序编写了这段代码,该程序获取一个字符串(并将其放入数组中)和一个数字,然后它在数组中搜索以查找它是否有重复的字符(并计算重复的次数) , 如果是这样的话;程序将比较特定字符重复的次数以及重复次数是否等于用户给出的次数;程序将用字符“A”替换它们。例如;如果我们给程序“BBCC”和数字 2,它应该给我们结果“AAAA”。问题是我的代码适用于某些示例,不适用于上面的示例。代码如下:

#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
char str[30];
int i, j, k, l, number, counter = 0;
char ch;

cout << "Enter a string: ";
gets (str);

cout << "\nEnter a number: ";
cin >> number;

for (i =0; str[i]; i++){
    ch = str[i];
    for (j = 0; str[j]; j++){
        if (str[j] == ch){
            counter++;
        }
    }
    if (counter == number){
        for (k = 0; str[k]; k++){
            if (str[k] == ch){
                str[k] = 'A';
            }
        }
    }
}

for (l = 0; str[l]; l++){
    cout << str[l];
}
getchar ();
return 0;
}

另一个错误是,如果我们给它字符串“ABC”和数字 2;结果将是“AAC”! 我知道我的代码有点乱,因为我是初学者,所以请道歉并帮助我解决我的问题。 谢谢。

【问题讨论】:

  • 我不确定这个问题将如何帮助未来的访客? ://
  • 永远不要使用gets,而是使用std::string和普通输入运算符&gt;&gt;
  • 至于你的问题,学习如何使用调试器,除了编译器和编辑器,它应该是你工具箱中最常用的工具。使用调试器,您可以逐行单步执行代码,同时查看所有相关变量的值,这将帮助您了解代码的行为是否符合您的预期。
  • 你应该在external for开头将counter初始化为0
  • 您永远不会重置您的计数器。在外循环的第一行将其设置为 1,或者更好地在此处声明它(您不需要在其他地方使用该变量)。此外,正如其他人指出的那样,避免将 stdio 与 iostream 混合使用。

标签: c++ string if-statement for-loop counter


【解决方案1】:

您需要在循环中重置 counter 变量。

对于ABC 示例:

  1. 循环将首先计算As。有 1 个 A,所以 counter = 1
  2. 下一次迭代将计数Bs。有1个B,所以计数器增加到counter = 2
  3. 这是输入的数字,所以它会将所有Bs 替换为A => AAC

【讨论】:

    【解决方案2】:
    for (i = 0 ; str[ i ] ; i ++ )
    {
        if( str[ i ] != 'A' ) // because replacing A with A is pointless
        {
            counter = 0 ;
            ch = str[ i ] ;
    
            for ( j = 0 ; str[ j ] ; j ++ )
            {
                if ( str[ j ] == ch )
                {
                        counter ++ ;
                }
            }
    
            if (counter == number)
            {
                for ( j = 0 ; str[ j ] ; j ++ )
                {
                    if ( str[ j ] == ch )
                    {
                        str[ j ] = 'A' ;
                    }
                }
            }
        }
    }
    

    我试着把所有的cmets都放在一起修正+一些优化,如果还有什么问题,请告诉我

    编辑:

    C++11 很漂亮,因为他的简化为 ;-)

    map< char , vector< int > > counters ;
    
    for (i = 0 ; str[ i ] ; i ++ )
    {
        counters[ str[ i ] ].push_back( i ) ;
    }
    
    for( pair< char , vector< int > > liste : counters )
    {
        vector< int > vec = liste.second ;
    
        if( vec.size( ) == number )
            for( int elt : vec )
                str[ elt ] = 'A' ;
    }
    

    说明:我遍历数组,将每个索引存储在与 char 关联的索引列表中(地图的用途)

    最后,我只查看每个字符的向量的大小,如果大小等于number,我会通过这个列表将每个元素“指向”到“A”的索引

    【讨论】:

    • 这很好用,非常感谢!是否需要在 for 循环(i、j 和 k)中定义不同的变量?
    • 不适用于 j 和 k 因为它们的 for 是不相交的,我纠正了它 thx :D (顺便说一句,应该添加很多优化,因为它仍然很讨厌 :-P,想象你有 18 'a ',并且 n 不是 18,那么您将遍历整个数组 18 次,这非常糟糕,您应该能够通过使用 std::map 仅遍历数组一次来计数
    猜你喜欢
    • 1970-01-01
    • 2014-12-20
    • 1970-01-01
    • 2019-02-27
    • 2021-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多