【问题标题】:C++ - Counting digits of a range of numbersC ++ - 计算一系列数字的位数
【发布时间】:2019-03-09 22:53:19
【问题描述】:

我需要做什么:

用户输入从 SK 的一系列数字的程序。它应该计算在数字中找到一个数字的次数,最后按以下顺序打印出来:0 1 2 3 4 5 6 7 8 9。

我的代码:

OBS:它不适用于 10 位以上的数字。

#include <iostream>

using namespace std;

int main()
{
int S, K;
cin >> S >> K;
int digits = 0;
int dig0 = 0;
int dig1 = 0;
int dig2 = 0;
int dig3 = 0;
int dig4 = 0;
int dig5 = 0;
int dig6 = 0;
int dig7 = 0;
int dig8 = 0;
int dig9 = 0;
int remainder = 0;

for (int i = S; i <= K; i++) {
    if (i < 10) {
        switch(i) {
        case 0:
            dig0++;
            break;
        case 1:
            dig1++;
            break;
        case 2:
            dig2++;
            break;
        case 3:
            dig3++;
            break;
        case 4:
            dig4++;
            break;
        case 5:
            dig5++;
            break;
        case 6:
            dig6++;
            break;
        case 7:
            dig7++;
            break;
        case 8:
            dig8++;
            break;
        case 9:
            dig9++;
            break;
        }
    } else if (i >= 10) {
        while (i > 0) {
            remainder = i % 10;
            switch(remainder) {
            case 0:
                dig0++;
                break;
            case 1:
                dig1++;
                break;
            case 2:
                dig2++;
                break;
            case 3:
                dig3++;
                break;
            case 4:
                dig4++;
                break;
            case 5:
                dig5++;
                break;
            case 6:
                dig6++;
                break;
            case 7:
                dig7++;
                break;
            case 8:
                dig8++;
                break;
            case 9:
                dig9++;
                break;
            }
            i /= 10;
        }
    }
}

cout << dig0 << ' ' << dig1 << ' ' << dig2 
<< ' ' << dig3 << ' ' << dig4 << ' ' << dig5 
<< ' ' << dig6 << ' ' << dig7 << ' ' << dig8 << ' ' << dig9;

return 0;
}

期望的行为:

测试用例 01

输入:1 到 9

输出:0 1 1 1 1 1 1 1 1 1(因为有0位 0,从 1 到 9 每个数字的 1 位)

测试用例 02

输入:767 772

输出:1 1 1 0 0 0 3 10 1 1

【问题讨论】:

  • 你的外部for循环应该被用作你的算法的值;它不应该被修改。 IE。 while (i &gt; 0) 循环逻辑实际上是在修改外循环的控制变量; i。不要那样做。获取i 的值,将其放入临时变量中,然后通过您的while 循环逻辑运行that。 Fwiw,调试器 会逐行显示,问题会立即显而易见。学会使用一个。
  • @WhozCraig 我使用 CodeBlocks,我能够完全正常地运行该程序。那么,我应该创建一个新变量并将 i 存储在其中,然后...?
  • 我从来没有说过你不能运行它;我说过在那个循环中修改i 的逻辑是broken。查看 bruno 的回答并注意他如何使用 v 进行模数/div 更改,而 i 只是序列计数器。
  • @bruno 我还没有机会在电脑上查看答案。不过我会的。
  • @N.T.我编辑了我的建议以允许 S 和 K 的任何 int

标签: c++ numbers digits


【解决方案1】:

(编辑以允许 S 和 K 的任何值,包括负数)

可以

#include <iostream>
using namespace std;

int main()
{
  int S, K;
  int dig[10] = { 0 };

  if (!(cin >> S >> K))
    return -1;

  if (S > K)
    swap(S, K);

  for (auto i = S; i <= K; ++i) {
    auto v = i;

    do {
      dig[abs(v % 10)] += 1;
      v /= 10;
    } while (v != 0);
  }

  for (auto v : dig)
    cout << v << ' ';
  cout << endl;

  return 0;
}

我对你的提议做了一些改变

  • 修正是让i在内部不变使用其他变量。
  • 我检查是否输入了两个有效值 (if (!(cin &gt;&gt; S &gt;&gt; K)) ...)
  • 如果需要,我将 S 和 K 交换为 S for 中的假设
  • 我使用数组而不是 dig0 dig1 ... dig9,使用数组更简单
  • 我管理负值。请注意,我使用 int v = i; ... dig[abs(v % 10)] += 1; 而不是 int v = abs(i); ... dig[v % 10] += 1; 来管理 v 为 INT_MIN 的情况(-INT_MIN 等于 INT_MIN 所以在使用 2 的补码时仍然是负数)

编译和执行:

pi@raspberrypi:/tmp $ g++ -pedantic -Wextra m.cc
pi@raspberrypi:/tmp $ ./a.out
1 9
0 1 1 1 1 1 1 1 1 1 
pi@raspberrypi:/tmp $ ./a.out
767 772
1 1 1 0 0 0 3 10 1 1 
pi@raspberrypi:/tmp $ ./a.out
-1 1
1 2 0 0 0 0 0 0 0 0 
pi@raspberrypi:/tmp $ ./a.out
-767 -772
1 1 1 0 0 0 3 10 1 1 

附加说明:如果 auto 打扰您将它们替换为 int,将 for (auto v : dig) cout &lt;&lt; v &lt;&lt; ' '; 替换为 for (int i = 0; i != 10; ++i) cout &lt;&lt; dig[i] &lt;&lt; ' ';

【讨论】:

    【解决方案2】:

    switch语句的使用很尴尬,多个int变量可以合并到一个数组中。

    #include <array>
    #include <iostream>
    
    int main() {
    
        std::array<int, 10> digits = {0};
    
        int s, k;
        std::cin >> s >> k;
    
        int temp;
        if(s > k) {//swap s and k, if s > k
            temp = s;
            s = k;
            k = temp;
        }
    
        for(s; s <= k; s++) {
            temp = s;
            do {
                digits[temp%10]++;
                temp /= 10;
            }while(temp != 0);
        }
    
        for(int j : digits) {
            std::cout << ' ' << j;
        }
    
        return 0;
    }
    

    【讨论】:

    • 为什么会出现奇怪的交换?为什么不使用std::swap
    • std::swap 不需要变量。
    猜你喜欢
    • 2013-08-25
    • 2021-03-10
    • 1970-01-01
    • 2018-07-16
    • 1970-01-01
    • 2020-08-07
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多