从一个全组合算法想到的……

jackylingzeng 2009-03-14 12:20:08
我刚学算法,这两天都在写全排列全组合,都是用字典序法,今天有幸看到了 http://topic.csdn.net/u/20090217/21/f41ed9f6-f929-451c-a5c9-80d2e408422a.html?seed=2130980366 这张帖子,其中大牛们的算法很精妙让我耳目一新,但我现在有些疑惑,我按组合数学书上的字典序算法实现的全组合 n = 11(ABCDEFGHIJk)时 平均时间在0.3秒带屏幕显示排列结果(我的配置是迅驰I 1.4G 1G内存),和帖子里 127楼 min_jie 用C#实现的时间差不多。我不是认为我比帖子里的大牛们强,因为他们的方法很精妙,我一点都没想到过,而且要慢慢看才能理解他们的算法,也不认为他们钻研算法达到最好是徒劳的,因为当n很大时,只有最优秀的算法才能体现效率,但我的疑惑是最普遍的字典序算法比这些精妙的算法其实相差多少呢?而且当N很大时,真的就相差很大吗?希望大家多谈谈意见。

这是我实现的字典序全组合 n = 11 完全按照组合数学书上算法写的。


#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// 元素数量
#define ELEM_SIZE 11
// 打印元素排列
void printString(char s[], int list[], int size);
// 初始化数组
void initList(int list[], int size);
// 字典序生成组合
void combinDict(char s[], int n, int k);

int main(void)
{
clock_t ct;
// 定义 ELEM_SIZE + 1个元素数组,使下标与值相对应
int k;
char s[ELEM_SIZE + 2] = "0ABCDEFGHIJk";

ct = clock();
// 字典序生成组合
for (k = 1; k <= ELEM_SIZE; k++)
{
combinDict(s, ELEM_SIZE, k);
}

ct = clock() - ct;

printf("time : %f\n", (double)ct / CLK_TCK);

return 0;
}

void initList(int list[], int size)
{
int i;

// 使 list[0] 为有符号最大值
list[0] = ~0U >> 1;

// 生成数组
for (i = 1; i <= size; i++)
{
list[i] = i;
}
}

void combinDict(char s[], int n, int k)
{
int i, j, *list, *blist;

i = k;
list = calloc(sizeof(int), n + 1);
blist = calloc(sizeof(int), k + 1);

// 初始化数组
initList(list, n + 1);
// 打印第一个元素组合
printString(s, list, k + 1);


// 字典序算法
while (i > 0)
{
if (list[i] < n - k + i)
{
// 生成 blist[i]
blist[i] = list[i] + 1;

// 若 i 不是最后一个元素k
if (i < k)
{
j = i + 1;

// 生成 blist[i + 1]...[k]
while (j <= k)
{
blist[j] = blist[j - 1] + 1;
j++;
}
}

// 使list[i]...[k] = blist[i]...[k]
while (i <= k)
{
list[i] = blist[i];
i++;
}

// 打印元素组合
printString(s, list, k + 1);

i = k;
}
else
{
i--;
}
}
}

void printString(char s[], int list[], int size)
{
int i;
for (i = 1; i < size; i++)
{
printf("%c", s[list[i]]);
}

printf("\n");
}



...全文
184 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
spirit_sheng 2009-03-14
  • 打赏
  • 举报
回复
绿色夹克衫 2009-03-14
  • 打赏
  • 举报
回复
字典序本身就是个不错的算法,不过效率很难达到最高,因为存在一些插入运算,当然依照实现方式的不同,效率上会有差别.

另外如果考虑到输出,那么这些算法的效率就全都回到同一个等级上了,因为输出本身是很慢的,
在比较效率和速度的时候,往往先不考虑输出.经常是生成需要1秒,效率高的可能只需要0.1秒,但是输出可能要上百秒
这样的话101同100.1比就没什么差别了!

所以LZ在比较效率的时候,最好先不输出,或者输出到字符串......这样才能看出纯粹算法以及实现本身的效率。

另外这类问题的算法效率其实都差不了多少,主要还是看如何编程实现!
lukios 2009-03-14
  • 打赏
  • 举报
回复
来顶一下啊,学习学习

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧