我正在寻找一种非常有效的方法来生成字符串(或字母表)的所有可能的排列,其中排列长度由两个变量(i, j)
在下方和上方限定。
到目前为止,我已经能够以多种方式生成排列,例如......
void swap(char *x, char *y){
char w;
w = *x;
*x = *y;
*y = w;
}
void permute(char *str, int start, int n){
int i;
if(start == n-1)
printf("%s\n", str);
else
for(i = start; i < n; i++){
swap(str+i, str+start);
permute(str, start+1, n);
swap(str+i, str+start);
}
}
...但到目前为止我找不到的算法将有效地限制结果字符串的长度。例如,如果字母表被定义为abcde
和i = 2
,j = 4
......这会产生ab
,bac
等排列, dcea
,但不是a
,edcba
,由于算法不是计算组合,因此也不会产生aab
等字符串。
答案 0 :(得分:1)
如果只是将最小和最大长度传递给函数,并在start
介于两者之间时打印字符串呢?
代码:
void permute(char *str, int start, int n, int minLength, int maxLength)
{
int i;
if (start >= minLength)
{
char temp = str[start]; // store the character, so we don't lose it
str[start] = 0; // 0x00 - end of string
printf("%s\n", str);
str[start] = temp;
}
if (start == maxLength)
return;
for (i = start; i < n; i++)
{
swap(str+i, str+start);
permute(str, start+1, n, minLength, maxLength);
swap(str+i, str+start);
}
}
如果数据中有重复项,并且您想要防止重复排列,那么您需要做的就是:
将字母排序为开头,以便任何重复的字符彼此相邻
如果最后一个字符与此字符相同,请勿执行任何操作。这可以通过简单地将以下代码添加到for循环的开头来完成:
if (i != start && str[i] == str[i-1])
continue;