字符串字母的排列:如何删除重复的排列?
这是一个打印字符串字符排列的标准函数:
void permute(char *a, int i, int n)
{
int j;
if (i == n)
printf("%s\n", a);
else
{
for (j = i; j < n; j++) //check till end of string
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j)); //backtrack
}
}
}
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
它工作正常,但有一个问题,它还会打印一些重复的排列,例如:
如果字符串是“AAB”,
则输出为:
AAB
ABA
AAB
ABA
BAA
BAA
这有 3 个重复条目出色地。
有办法防止这种情况发生吗?
——
谢谢
Alok Kr。
Here is a standard function to print the permutations of characters of a string:
void permute(char *a, int i, int n)
{
int j;
if (i == n)
printf("%s\n", a);
else
{
for (j = i; j < n; j++) //check till end of string
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j)); //backtrack
}
}
}
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
It works fine but there is a problem, it also prints some duplicate permutations, exapmle:
if string is "AAB"
the output is:
AAB
ABA
AAB
ABA
BAA
BAA
This is having 3 duplicate entries as well.
Can there be a way to prevent this to happen?
--
Thanks
Alok Kr.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
记下您之前交换的字符:
这必须是迄今为止条目中最快的一个,“AAAABBBCCD”(100 个循环)上的一些基准:
Take notes which chars you swapped previously:
This has to be the fastest one from the entries so far, some benchmark on a "AAAABBBCCD" (100 loops):
标准库有您需要的:
结果:
Standard library has what you need:
Result:
另一种方法可能是:
对数组进行预排序。
这将确保所有重复项现在都是连续的。
所以,我们只需要查看我们修复的前一个元素(并排列其他元素)
如果当前元素与前一个元素相同,不排列。
Another approach could be:
Presort the array.
This will ensure that all duplicate are now consecutive.
So, we just need to see the previous element which we we fixed (and permuted others)
if current element is same as previous, don't permute.
我将按照以下方式执行此操作:首先,我生成字符“组”(即
AABBBC
生成两个组:(AA) 和 (BBB) 和 (C)
。首先,我们将
AA
的所有分布迭代到n
字符上。对于找到的每个分布,我们将BBB
的所有分布迭代到n
上。 code>n-2 剩余字符(不对于涉及A
和B
的每个分布,我们迭代C< 的所有分布。 /code> 到剩余的空闲字符位置。
I would do it the following way: First, I generate "groups" of characters (i.e.
AABBBC
yields two groups:(AA) and (BBB) and (C)
.First, we iterate over all distributions of
AA
onto then
characters. For each distribution found, we iterate over all distributions ofBBB
onto then-2
remaining characters (not occupied by anA
). For each of these distributions involvingA
s andB
s, we iterate over all distributions ofC
onto the remaining free character positions.您可以使用 std::set 来确保结果的唯一性。也就是说,如果它是 C++(因为你这样标记它)。
否则 - 手动浏览结果列表并删除重复项。
当然,您必须保存结果并对其进行后处理,而不是像现在一样立即打印。
You can use
std::set
to ensure uniqueness of the results. That is if it is C++ (because you tagged it as such).Otherwise - go through the list of the results manually and remove duplicates.
You'll have to save the results and post-process them of course, not print immediately as you do now.
如果您只是认为这是一个需要存储所有排列以供将来使用的问题,那就非常简单了。
所以你将有一个排列字符串的数组。
现在考虑一个新问题,这也是一个标准问题,您需要从数组中删除重复项。
我希望这有帮助。
It would quite simple if you just think it as a problem where you need to store all the permutations for some future use.
SO you'll have an array of permuted strings.
Now think of a new problem, which is also an standard one where you need to remove the duplicates from array.
I hope that helps.
@Kumar,我认为你想要的是如下所示的内容:
根据要求,此代码是 C 代码,它非常快并且可以执行你想要的操作。当然,它包含可能的缓冲区溢出,因为偏移缓冲区具有固定大小,但这只是一个示例,对吗?
编辑:有人尝试过吗?有没有更简单或更快的解决方案?令人失望的是没有人进一步评论!
@Kumar, I think what you want is something like the following:
This code is C, as requested, it's pretty fast and does what you want. Of course it contains a possible buffer overflow because the offset buffer has a fixed size, but this is just an example, right?
EDIT: Did anyone try this out? Is there a simpler or faster solution? It's disappointing noone commented any further!
只需将其用作 permute("word");
And simply use it as permute("word");
不要在
字符串
的不同位置对相同字符进行排列。在Python中:
Do not permute for same character at different position of the
string
.In Python:
算法步骤:
我认为,这是最好、最有效的解决方案。
Algorithm steps:
I think, this is best and efficient solution.