Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中数字的唯一组合_C_Algorithm_Digits - Fatal编程技术网

C语言中数字的唯一组合

C语言中数字的唯一组合,c,algorithm,digits,C,Algorithm,Digits,我需要用C设计一个算法来计算0到1000000的唯一数字组合。例如,当出现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 谢谢 编辑-抱歉,忘记提到零不包括在内\include #include <stdio.h> int main(void) { int i, n; f

我需要用C设计一个算法来计算0到1000000的唯一数字组合。例如,当出现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
谢谢

编辑-抱歉,忘记提到零不包括在内

\include
#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; }
        }
    }
}
内部主(空){ inti,n; 对于(n=1;n<1000000;n++){ 对于(i=n;;){ 如果(i/10%10>i%10)中断; 如果((i/=10)==0){printf(“%d\n”,n);break;} } } }
从0到1000000的系列中有5004个数字

更快的版本:

#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);
    }
}
#包括
#包括
静态长-长枚举(字符*p、整数i、整数n、整数位数、整数静默){
长计数=0;
如果(i>=n){
如果(!silent)printf(“%s\n”,p);
返回1;
}
对于(p[i]=数字;p[i]1)?strtol(argv[1],NULL,0):6;
int=0;
长计数=0;
如果(最大值<0){
max=-max;
沉默=1;
}
数组[sizeof(数组)-1]='\0';

对于(n=1;n函数
next
将数组
a
更新为下一个数字,返回底部数字的值。
main
函数遍历序列,在顶部数字为10时停止(因为一旦数组用完,
next
只会不断增加最重要的数字)

该算法,用文字和忽略边界检查,可以描述为“要找到下一个数字,在底部数字上加一个,如果溢出,找到忽略底部数字的下一个数字,然后复制新的底部数字。”


本系列中的前几个数字是,0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,22,23,24等等。您可能应该解释为什么10没有出现在列表中。
10也不在系列中。是否假定它与
01
相同?前面带有隐式零的6位组合在列表中只出现一次列表?如果所有数字的顺序都是递增的,我猜列表中有一个数字。@DanielKleinstein 132不应该在列表中,因为123的组合只有
24309
高达1亿和
48619
低于10亿。序列长度似乎像对数(N)一样增长。找到N=10^N的分析公式是你的新任务!我知道我应该做你的家庭作业,我就是忍不住。我测试1和上限之间的每一个数字。我检查最后一个数字是否至少与前一个数字一样大,然后对前一对数字再做一次,将数字除以10,直到它为0。如果t达到0时,数字可以打印出来。此方法快速且脏。对于1000000来说,它足够快,但是对于更高的边界来说,它变得非常慢。找到一个更快的方法,使用一个字符数组在线性时间内查找所有组合。它对您来说运行得有多快?它对我来说已经运行了几分钟了…您确定吗你的内环没有停止条件吗?我想你应该保留
i>0
。我的错!测试
i>0
是多余的,但我忘记了
中断;
。相当优雅!
4263421511270
1个googol之间的组合。我不得不在
count
中使用
unsigned long
乌克,你统治!
#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;
}
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.