C语言切换案例:一次使用后避免出现案例

时间:2018-11-22 19:40:50

标签: c switch-statement

我正在尝试一个挑战,我需要获得一个随机数,并打印数字内的数字总和,不要重复: 例如,123将打印6(1 + 2 + 3),而32111将执行相同的操作(因为我们不将重复项添加到我们的总和中,所以这个数字的总和类似于123的总和。)

在我的解决方案中,我考虑过为每个数字使用切换大小写,并使用一个其值是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;

}

2 个答案:

答案 0 :(得分:1)

尝试使用表示每种情况的位掩码。主要思想是仅使用一个整数来跟踪每个数字(从0到9)。该单个整数的一些位可用于查找此数字是否曾经出现过。如果该位为0,则将首次看到相应的数字(现在将其设置为1),如果看到该位已为1,则无需将其加到最终的总和中。 / p>

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;
...

现在您可以在我使用的最后一种情况下看到一个模式,我们可以将此切换情况简化为单个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设置一个单独的布尔标志将很浪费到9。

答案 1 :(得分:0)

case项是编译时常数,因此您不能在c语言级别的运行时“禁用”它。然后,您必须为每个数字引入一个单独的标志。

我想说-看一下您的代码-switch-case方法不是最好的,因为您重复了很多类似的代码。一种更简单的方法是有一个10个整数的数组,每个整数代表一个特定的数字,一旦遇到一个数字,就将相应的数组元素设置为1。最后总结一个循环。

如果您在运行此方法时遇到麻烦,请随时询问...