Случай переключения языка C: избегая случая после использования один раз - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь выполнить задание, в котором мне нужно получить случайное число и вывести сумму цифр внутри числа без дубликатов: например, 123 выведет 6 (1 + 2 + 3), а 32111 -то же самое (поскольку мы не добавляем дубликаты к нашей сумме, сумма этого числа аналогична сумме 123.)

В моем решении я подумал об использовании регистра переключателя для каждого числа и использованииОтметьте, что его значение равно единице, чем в каждом случае я добавляю 1 к флагу, а когда флаг равен 2, я добавляю число к сумме, но я не знаю, как избежать случая после того, как это произошло, что, если яПосмотрите правильно, чтобы избежать использования нескольких флагов для каждого числа (потому что, если бы мы могли избежать случая после того, как он произошел, я мог бы просто установить флаг на один после переключателя и повторить весь процесс)

canты мне поможешь?Большое спасибо!

#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 голосов
/ 22 ноября 2018

Попробуйте использовать битовую маску для каждого случая.Основная идея состоит в том, чтобы отслеживать каждое число (от 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;
...

Теперь вы можете увидеть шаблон в последнем случае, который я использовал, мы можем упростить этот случай переключения в один оператор 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.

0 голосов
/ 22 ноября 2018

A case -термин является постоянной времени компиляции, поэтому вы не можете «отключить» ее во время выполнения на уровне языка c.Тогда вам придется ввести отдельный флаг для каждой цифры.

Я бы сказал - и взгляну на ваш код - подход switch-case не самый лучший, поскольку вы дублируете много похожего кода.Гораздо более простым способом было бы иметь массив из 10 дюймов, каждый из которых обозначает определенную цифру, и как только встречается цифра, установите соответствующий элемент массива на 1.В конце подведите итоги цикла.

Если у вас возникли проблемы с запуском этого подхода, не стесняйтесь спрашивать снова ...

...