Несколько ошибок ...
Вы индексируете некоторые из своих массивов по pos
, что не очень помогает.
Я запустил ваш код, и он, кажется, зацикливается в течение длительного времени. Как уже упоминали другие, вы не ограничиваете свои цифры цифрой 0-9
. Кроме того, некоторые из ваших массивов получают дикие / большие значения.
Для этого вы можете использовать вложенные циклы. То есть перебираем комбинации цифр, но я думаю, что вам нужен только один массив из 4 элементов. То есть сгенерируйте строку цифр, проверьте ее и добавьте к сумме, если строка цифр действительна (т.е. сумма цифр соответствует num
).
Вы можете использовать для этого 4 вложенных цикла,
но что если число цифр было произвольным (и могло быть указано во время выполнения)?
Использование массива ndigits переменной длины и увеличение их с помощью выполнения является альтернативой вложенным массивам
Я не смог разобраться в вашем алгоритме, поэтому я создал версию с нуля. Это проще, чем, я думаю, ваша логика пыталась достичь.
Вместо того, чтобы запрашивать у пользователя значение num
, он проверяет все возможные значения num
.
Возможно, это даст вам некоторые идеи, которые помогут вам понять, что происходит с вашей собственной версией. В частности, обратите внимание, как обрабатывается перенос / опрокидывание, когда цифра достигает 10.
Во всяком случае, вот что я придумал. Он проверяет все значения num
в диапазоне 0-9999
и занимает всего 0,8 секунды.
После сбоя данного num
(т. Е. У него нет совпадающих комбинаций цифр), мы можем остановиться рано, потому что ни одна комбинация цифр больше не будет совпадать. С опцией раннего выхода -f
программа занимает 8 мс.
#include <stdio.h>
#include <stdlib.h>
int opt_f; // 1=test all numbers
int opt_r; // 1=print lowest to highest
int opt_z; // 1=exclude anything with leading 0
int opt_v; // 1=output matching numbers
int opt_N; // num value to use
int opt_W; // digit width
int
test(int num,const int *digits)
{
int sum = 0;
int digidx;
int match;
for (digidx = 0; digidx < opt_W; ++digidx)
sum += digits[digidx];
match = (sum == num);
// decide which digit is most significant
if (opt_r)
digidx = opt_W - 1;
else
digidx = 0;
// ensure number has no leading zeroes
if (opt_z) {
if (! digits[digidx])
match = 0;
}
return match;
}
int
calc(int num)
{
int digits[opt_W];
int showflg = 1;
int carry;
int tot = 0;
// reset digit string to all zeroes
for (int digidx = 0; digidx < opt_W; ++digidx)
digits[digidx] = 0;
while (1) {
// test number and print if it matches
if (test(num,digits)) {
if (tot == 0) {
printf("\n");
printf("NUM: %d\n",num);
}
tot += 1;
// output the number
if (opt_v) {
printf(" ");
if (! opt_r) {
for (int digidx = 0; digidx < opt_W; ++digidx)
printf("%d",digits[digidx]);
}
else {
for (int digidx = opt_W - 1; digidx >= 0; --digidx)
printf("%d",digits[digidx]);
}
printf("\n");
}
}
// increment to next digit string
carry = 0;
for (int digidx = 0; digidx < opt_W; ++digidx) {
// increment the current digit
digits[digidx] += 1;
// see if we get a carry out on this digit -- bug out if not
carry = (digits[digidx] > 9);
if (! carry)
break;
// reset this digit to zero
digits[digidx] = 0;
}
// carry out from most significant digit means stop
if (carry)
break;
}
if (tot)
printf("TOT: %d\n",tot);
return tot;
}
int
main(int argc,char **argv)
{
char *cp;
opt_f = 1;
opt_r = 1;
opt_z = 1;
opt_v = 0;
opt_W = 4;
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
cp = *argv;
if (*cp != '-')
break;
switch (cp[1]) {
case 'f': // flip test all numbers
opt_f = ! opt_f;
break;
case 'r': // flip low-to-high
opt_r = ! opt_r;
break;
case 'v': // flip verbosity
opt_v = ! opt_v;
break;
case 'z': // flip skip on leading zeroes
opt_z = ! opt_z;
break;
case 'N': // num value to use
opt_N = atoi(cp + 2);
break;
case 'W': // set digit width
opt_W = atoi(cp + 2);
break;
}
}
// get upper limit of number to test
int lim = 1;
for (int num = 1; num <= opt_W; ++num)
lim *= 10;
printf("WID: %d (%d)\n",opt_W,lim);
// test all numbers within the range
int num;
if (opt_z && (! opt_f))
num = 1;
else
num = 0;
if (opt_N) {
num = opt_N;
lim = num + 1;
}
for (; num < lim; ++num) {
if (calc(num))
continue;
if (! opt_f)
break;
}
return 0;
}
Вот вывод программы:
WID: 4 (10000)
NUM: 1
TOT: 1
NUM: 2
TOT: 4
NUM: 3
TOT: 10
NUM: 4
TOT: 20
NUM: 5
TOT: 35
NUM: 6
TOT: 56
NUM: 7
TOT: 84
NUM: 8
TOT: 120
NUM: 9
TOT: 165
NUM: 10
TOT: 219
NUM: 11
TOT: 279
NUM: 12
TOT: 342
NUM: 13
TOT: 405
NUM: 14
TOT: 465
NUM: 15
TOT: 519
NUM: 16
TOT: 564
NUM: 17
TOT: 597
NUM: 18
TOT: 615
NUM: 19
TOT: 615
NUM: 20
TOT: 597
NUM: 21
TOT: 564
NUM: 22
TOT: 519
NUM: 23
TOT: 465
NUM: 24
TOT: 405
NUM: 25
TOT: 342
NUM: 26
TOT: 279
NUM: 27
TOT: 219
NUM: 28
TOT: 165
NUM: 29
TOT: 120
NUM: 30
TOT: 84
NUM: 31
TOT: 56
NUM: 32
TOT: 35
NUM: 33
TOT: 20
NUM: 34
TOT: 10
NUM: 35
TOT: 4
NUM: 36
TOT: 1