我需要在C中设计一个算法来计算0到1,000,000的唯一数字组合。例如,当出现13时,31将不包括在此序列中。任何人都可以帮我找到一个算法来描述这个吗?该系列的前几个数字将是:
1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,22,23,24,25,26,27,28,29,33,etc
谢谢!
编辑 - 抱歉,忘记提及零不包括
答案 0 :(得分:6)
#include <stdio.h>
int main(void) {
int i, n;
for (n = 1; n < 1000000; n++) {
for (i = n;;) {
if (i / 10 % 10 > i % 10) break;
if ((i /= 10) == 0) { printf("%d\n", n); break; }
}
}
}
系列中的5004个数字,从0到1000000
更快的版本:
#include <stdio.h>
#include <stdlib.h>
static long long enumerate(char *p, int i, int n, int digit, int silent) {
long long count = 0;
if (i >= n) {
if (!silent) printf("%s\n", p);
return 1;
}
for (p[i] = digit; p[i] <= '9'; p[i]++)
count += enumerate(p, i + 1, n, p[i], silent);
return count;
}
int main(int argc, char **argv) {
char array[256];
int i, n;
int max = (argc > 1) ? strtol(argv[1], NULL, 0) : 6;
int silent = 0;
long long count = 0;
if (max < 0) {
max = -max;
silent = 1;
}
array[sizeof(array)-1] = '\0';
for (n = 1; n <= max; n++) {
count += enumerate(array + sizeof(array) - 1 - n, 0, n, '1', silent);
if (silent)
printf("%lld combinations between 0 and 1E%d\n", count, n);
}
}
使用正数调用以枚举组合,使用负数来计算它们。
答案 1 :(得分:2)
函数next
将数组a
更新为下一个数字,返回底部数字的值。 main
函数遍历序列,一旦高位数为10就停止(因为一旦数组用完,next
只是递增最高位数。)
算法,用单词和忽略边界检查,可以描述为&#34;找到下一个数字,在底部数字加1,如果溢出,找到忽略底部数字的下一个数字,然后复制新的底部数字。&#34;
#include <stdio.h>
int next(int *a, size_t len) {
if (*a == 9 && len > 1) {
*a = next(a-1, len-1);
} else {
*a += 1;
}
return *a;
}
#define N 6
int main(int argc, char *argv[]) {
int a[N] = {0};
while (next(a+N-1, N) != 10) {
for (int i = 0; i < N; i++) {
if (a[i] != 0) printf("%d", a[i]);
}
printf("\n");
}
return 0;
}
您可以在O(N)时间内计算解决方案(其中N是数字位数)。如果K(n,d)是正数为n位的解的个数,且其最高位为9-d,则K(0,d)= 1,K(n + 1,d)= K(n, 0)+ K(n,1)+ ... + K(n,d)。然后,具有n个或更少位的解的数量是K(1,8)+ K(2,8)+ ... + K(n,8)。这些观察结果产生了这种动态编程解决方案:
int count(int n) {
int r[9] = {1};
int t = 0;
for (int i = 0; i < n+1; i++) {
for (int j = 1; j < 9; j++) {
r[j] += r[j-1];
}
t += r[8];
}
return t - 1;
}
int main(int argc, char* argv[]) {
printf("there are %d numbers.\n", count(6));
return 0;
}
给出:
there are 5004 numbers.