C语言switch-case : avoiding a case after used once

标签 c switch-statement

我正在尝试一个挑战,我需要获得一个随机数,并在没有重复的情况下打印数字内的数字总和: 例如,123 将打印 6 ( 1 + 2 + 3 ),而 32111 将做同样的事情(因为我们没有在我们的总和中添加重复项,这个数字的总和类似于 123 的总和。)

在我的解决方案中,我考虑过对每个数字使用 switch case,并使用一个其值为 1 的标志,而不是在每种情况下我将 1 添加到标志中,当标志为 2 时,我将数字添加到总和中,但我不知道如何在它发生后避免这种情况,如果我正确地看到它会避免我为每个数字使用多个标志(因为如果我们可以在它发生后避免这种情况,我就可以将标志设置回去切换到一个并再次执行所有过程)

你能帮帮我吗?非常感谢!

#include <stdio.h>

#define TEN 10
#define NINE 9
#define EIGHT 8
#define SEVEN 7
#define SIX 6
#define FIVE 5
#define FOUR 4
#define THREE 3
#define TWO 2
#define ONE 1

int main(void)
{
    int answer = 0, i = 0, remain = 0, sum = 0, flag = 1;
    printf("Enter a number: ");
    scanf("%d", &answer);
    while(answer >= ONE)
    {
        remain = answer % TEN;
        answer /= TEN;
        printf("%d\n", remain);  
        switch (remain)
        {
        case ONE:
        {
            flag++;
            if (flag == TWO)
            {
                sum = sum + ONE;
            }
            break;
        }
        case TWO:
        {
            flag++;
            if (flag == TWO)
            {
                sum = sum + TWO;
            }
            break;
        }
        case THREE:
        {
            flag++;
            if (flag == TWO)
            {
                sum = sum + THREE;
            }
            break;
        }
        case FOUR:
        {
            flag++;
            if (flag == TWO)
            {
                sum = sum + FOUR;
            }
            break;
        }
        case FIVE:
        {
            flag++;
            if (flag == TWO)
            {
                sum = sum + FIVE;
            }
            break;
        }
        case SIX:
        {
            flag++;
            if (flag == TWO)
            {
                sum = sum + SIX;
            }
            break;
        }
        case SEVEN:
        {
            flag++;
            if (flag == TWO)
            {
                sum = sum + SEVEN;
            }
            break;
        }
        case EIGHT:
        {
            flag++;
            if (flag == TWO)
            {
                sum = sum + EIGHT;
            }
            break;
        }
        case NINE:
        {
            flag++;
            if (flag == TWO)
            {
                sum = sum + NINE;
            }
            break;
        }
        default:
        {

        }

    }

}
printf("The sum of the number is: %d", sum);
return 0;

最佳答案

尝试使用代表每种情况的位掩码。主要思想是仅使用一个整数来跟踪每个数字(从 0 到 9)。这个单个整数的一些位可以用来查找这个数字是否以前见过。如果该位为 0,则第一次看到相应的数字(我们现在将该位设置为 1),如果我们看到该位已经为 1,则不将其添加到我们的最终总和中。

int mask = 0;

switch (remain) {
case 1: // 001
    if ((mask & 1) == 0) { // 1 = 1 << 0
        sum += 1;
        mask |= 1;
    }
    break;
...
case 3: // 100
    if ((mask & 4) == 0) { // 4 = 1 << 2
        sum += 3;
        mask |= 4;
    }
    break;
...
case n:
    if ((mask & k) == 0) { // k = 1 << (n-1)
        sum += n;
        mask |= k;
    }
    break;
...

现在您可以看到我使用的最后一个 case 中的模式,我们可以将这个 switch-case 简化为单个 if 语句。

int mask = 0;
int sum = 0;
while (answer) {
    remain = answer % 10;
    answer /= 10;
    int offset = remain;
    int flag = 1 << offset;
    if ((mask & flag) == 0) {
        sum += remain;
        mask |= flag;
    }
 }
 // sum contains the required answer

每一位代表一种情况,因为你只有 10 种情况,这是跟踪标志的最有效方法,因为你有超过 10 位的整数,并且为 0 设置一个单独的 bool 标志是浪费到 9。

关于C语言switch-case : avoiding a case after used once,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53437210/

相关文章:

c - 在 C Issue 中打开和创建文件?

c - 位操作,不必要的掩码?

c - 是否可以从头文件输出变量?

java - Switch 在第二次尝试之前不接受输入

c# - 如何在 case 语句中使用范围 C#

javascript - 在 JavaScript 中使用 switch 语句编写 if..else 语句

可以期望 C 数组具有与结构相同的性能吗?

git - 在 git 中切换分支

c# - 为什么我不能在 int 的 switch 语句中使用条件作为 case?

c - 如何解析用户的输入以确定在 C 中打印结果的位置?