【问题标题】:Why does my code say that 90 was repeated 6 times, instead of 5?为什么我的代码说 90 重复了 6 次,而不是 5 次?
【发布时间】:2020-07-15 20:25:56
【问题描述】:

我正在处理的问题是来自 HackerRank 的“生日蛋糕蜡烛”。

基本上,程序接受输入,然后输出最大输入的输入次数。

例如,如果输入可以是:

4

3 2 1 3

4 将是数组中的元素数。 3 2 1 3 将是数组中的元素。

输出将是 2,因为 3(最大)重复了 2 次。

这是我的代码:

#include <iostream>

using namespace std;

int main() {
    
    long long num;
    cin >> num;
    
    long long arr[num];
    
    for (int i = 0; i < num; i++) {
        cin >> arr[i];
    }
    
    long long qwer{};
    
    //find the largest value
    for (int i = 1; i<num; i++) {
        if (arr[0] < arr[i]) {
            arr[0] = arr[i];
            if (arr[0] == arr[i]) {
                arr[0] = arr[i];
            }
        }
        qwer = arr[0];
    }

    
    long long howmany = 0;
    
    //find how many times the largest value is repeated
    for (int i = 0; i<num; i++) {
        if (arr[i] == qwer) {
            howmany += 1;
        }
    }
    
    cout << howmany;
    
    return 0;
}

我的代码为上述测试用例提供了正确的输出。但是,对于以下测试用例,输出不正确:

10

18 90 90 13 90 75 90 8 90 43

对于这个测试用例,我的程序输出了 6,而不是 5。

10

44 53 31 27 77 60 66 77 26 36

对于这个测试用例,我的程序输出的是 3,而不是 2。

我的代码有什么问题?

提前致谢。

【问题讨论】:

  • 您的代码不是真正有效的 C++,因为 C++ 没有 variable-length arrays。请改用std::vector
  • 至于你的问题,这通常是通过比赛现场没有教授的东西(不是教学或学习资源)来解决的:调试乙>。使用调试器,您可以逐句逐句执行代码,同时监控变量并查看它们如何变化。
  • @holz 您的代码将 arr[0] 设置为最大值,并且该元素被抵消,尽管最初它不包含最大值。
  • 您不需要数组。您可以将其作为运行最大值

标签: c++ algorithm loops for-loop max


【解决方案1】:

您的代码的问题是您的“查找最大值”循环将数组的第一个元素替换为找到的最大值。当您在“查找多少次”循环中循环返回数组时,您有一个额外的高值实例,因此返回 6 而不是 5。

您输入时的数组: 18 90 90 13 90 75 90 8 90 43

“查找最大值”循环完成后您的数组: 90 90 90 13 90 75 90 8 90 43

这在您的第一个示例中起作用的原因是最高值是第一个元素。因此,您不会用任何东西替换第一个元素并在数组中创建额外的实例。如果你先尝试一个 10 的数组,其中值最高的,你会得到正确的数字输出。

另外,您可以将循环更改为:

    qwer = arr[0];

    //find the largest value
    for (int i = 1; i<num; i++) {
        if (qwer < arr[i]) {
            qwer = arr[i];
        }
    }

这将消除您所看到的示例之间不一致的问题。

【讨论】:

    【解决方案2】:

    有很多更好的方法可以做到这一点,就像这里的另一个答案一样。

    但专注于回答你的问题:

    我认为你的错误是将最大的数字存储在数组的第一个位置。

    if (arr[0] < arr[i]) {
                arr[0] = arr[i];
    

    看这个案例测试: 10

    18 90 90 13 90 75 90 8 90 43

    在这里,您将第一个项目 18 替换为 90。因此,您在最后一个循环中得到了 6 而不是 5。

    您可以尝试用下面的代码替换上面注释的代码吗?

    if (arr[0] < arr[i]) {
                qwer  = arr[i];
    

    【讨论】:

      【解决方案3】:

      这是一个不使用数组的运行最大值示例:

      int total = 0;
      std::cin >> total;
      int maxima;
      int count = 1;
      std::cin >> maxima; // Use first value as the maxima.
      --total;
      for (int i = 0; i < total; ++i)
      {
        int value;
        std::cin >> value;
        if (value == maxima)
        {
          ++count;
        }
        else
        {
          if (value > maxima)
          {
            maxima = value;
            count = 1;
          }
        }
      }
      std::cout << "Largest value: " << maxima << ", quantity: " << count << std::endl;
      

      上面的代码维护了最大值和最大值的出现次数。如果读取了新的最大值,则计数重置为 1。

      【讨论】:

        【解决方案4】:

        停止浪费内存。您不需要存储所有值。读取输入。检查它是当前的最大数量还是新的最大数量。更改count

        #include <iostream>
        #include <limits>
        
        int main() {
            
            std::int64_t num;
            std::cin >> num;
            
            std::int64_t count = 0;
            std::int64_t maxNumber = std::numeric_limits<std::int64_t>::min();
            
            for (std::int64_t i = 0; i < num; i++) {
                std::int64_t input;
                std::cin >> input;
                if (input > maxNumber) {
                    maxNumber = input;
                    count = 1;
                } else if (input == maxNumber) {
                    ++count;
                }
            }
            
            std::cout << count;
        }
        

        【讨论】:

          【解决方案5】:

          对于初学者可变长度数组

          long long num;
          cin >> num;
          
          long long arr[num];
          //...
          

          不是标准的 C++ 功能。

          其次,对于此任务,无需创建数组来存储输入的值,因为您需要计算遇到最大值的频率。此外,创建具有自动存储持续时间的大数组可能会导致堆栈溢出。

          在这个for循环中

          for (int i = 1; i<num; i++) {
              if (arr[0] < arr[i]) {
                  arr[0] = arr[i];
                  if (arr[0] == arr[i]) {
                      arr[0] = arr[i];
                  }
              }
              qwer = arr[0];
          }
          

          这个 if 语句

                  if (arr[0] == arr[i]) {
                      arr[0] = arr[i];
                  }
          

          是多余的,实际上什么也没做。

          注意元素 arr[0] 被当前最大值覆盖,尽管最初它可能不包含这样的值。

          在这个for循环中

          //find how many times the largest value is repeated
          for (int i = 0; i<num; i++) {
              if (arr[i] == qwer) {
                  howmany += 1;
              }
          }
          

          您可以再计算一个具有最大值的元素,因为元素 arr[0] 被设置为等于最大值并且被计算在内。

          只使用一个循环,程序看起来就更简单了。

          你来了。

          #include <iostream>
          
          int main() 
          {
              size_t n = 0;
              
              std::cin >> n;
              
              size_t howmany = 0;
              long long int max;
              long long int value;
              
              for ( size_t i = 0; i < n && std::cin >> value; i++ )
              {
                  
                  if ( i == 0 || max < value )
                  {
                      max = value;
                      howmany = 1;
                  }
                  else if ( not ( value  < max ) )
                  {
                      ++howmany;
                  }
              }
              
              std::cout << howmany << '\n';
              
              return 0;
          }
          

          如果进入序列

          10
          18 90 90 13 90 75 90 8 90 43
          

          那么输出将是

          5
          

          【讨论】:

            猜你喜欢
            • 2023-02-09
            • 1970-01-01
            • 2023-01-13
            • 1970-01-01
            • 1970-01-01
            • 2021-07-15
            • 2019-09-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多