C语言中数字的唯一组合
我需要用C设计一个算法来计算0到1000000的唯一数字组合。例如,当出现13时,31将不包括在此序列中。有人能帮我找到一个算法来描述这个吗?该系列的前几个数字是: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
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.