【发布时间】:2016-05-03 16:00:10
【问题描述】:
我有一个需要枚举算法的程序,我让它以这种方式工作:
#include <stdio.h>
void show (int subs[], int k) {
int i;
for (i=1; i<=k; i++)
printf("%i ", subs[i]);
puts("");
}
void enumerate (int n) {
int subs[n+1], k = 0;
*subs = 0;
while (1) {
if (subs[k] < n) {
subs[k+1] = subs[k] + 1;
k++;
} else {
subs[k-1] += 1;
k--;
}
if (k == 0) break;
show (subs, k);
}
}
int main(void) {
enumerate(4);
return 0;
}
它应该是 O(2N) 次调用show(subs, k)。最初,我认为这不会有问题,但我错了。实际上我的程序需要:
2 secs for n=25
4 secs for n=26
9 secs for n=27
18 secs for n=28
...
如您所见,它的时间增长得非常快。我的程序也做了一个快速排序,而不是show,它用我的逻辑调用了另一个函数,不过这里没关系。
但由于我必须做得更快,我开始分析我的问题......
我说过,如果在序列1 2 4 5(范围长度为 4)中找到我想要的解决方案,那么所有范围长度低于该值的序列对我的逻辑来说都是毫无价值的。
然后,我尝试对上面显示的enumerate 函数进行编码,使具有更大范围的序列首先出现,因为如果我得到这个,我可以在找到所需值时简单地破坏枚举函数。
但经过大约两个小时的挣扎后,我发现自己有 4 个内循环 (!!) 和错误的序列。
请各位忍者帮我解决这个问题?提前致谢。
更新
如果你运行enumerate(3),你会得到:
1
1 2
1 2 3
1 3
2
2 3
3
我想要的是首先更大的范围长度,所以:
1 2 3
1 2
1 3
2 3
1
2
3
【问题讨论】:
-
我看到一些没有明确目的的随机代码。您的计划的实际目标是什么?
-
@btilly。我试图只显示代码的相关部分。或者你的意思是一个明确的例子?我会更新一个
-
所以你只想要最后一个块? (即)您有
1 2 3但不需要 需要其他3 序列,例如3 2 1或2 3 1或1 3 2?而且,您不需要2 1?如果是这样,对上面的算法有一个轻微的扩展,可以在不需要排序的情况下按顺序给它们[更大范围优先]。我以前不得不做这种事情,但我有不同的输出要求,所以我只是想在提供答案之前了解你的。 -
@CraigEstey。我的程序读取
x间隔(开始和结束时间为整数),并返回最大不相交间隔。 x 值已给出。对不起,我的英文术语,我不知道它们是否正确