【发布时间】:2016-11-12 16:15:08
【问题描述】:
假设我有ABCDEF。然后,有6个!重新排序该字符串的排列。现在,我只想处理没有相邻字符的排列。这意味着,我想查看满足这些约束的所有排列:
- B 不在 A 或 C 旁边
- C 不在 B 或 D 旁边
- D 不在 C 或 E 旁边
- E 不在 D 或 F 旁边
我对这个算法的处理方法是下面的伪代码:
//generate all 6! permutations
//check all permutations and see where B is next to A || C
//remove all instances
//check all permutations and see where C is next to D
//remove all instances
//check all permutations and see where D is next to E
//remove all instances
//check all permutations and see where E is next to F
//remove all instances
但是,这些屏蔽操作变得非常低效并且花费了我很长时间,特别是如果我的字符串长度大于 6。我怎样才能更有效地做到这一点?我看到了这些类似的帖子,1、2,并希望提取一些可能对我有帮助的关键想法。但是,这也是蛮力检查。我想从一开始就只生成独特的模式,而不是生成所有东西并一一检查。
编辑:目前这是我用来生成所有排列的方法。
static String[] designs;
static int index;
protected static String[] generateDesigns(int lengthOfSequence, int numOfPermutations){
designs = new String[numOfPermutations];
StringBuilder str = new StringBuilder("1");
for(int i = 2; i <= lengthOfSequence; i++)
str.append(i);
genDesigns("", str.toString()); //genDesigns(6) = 123456 will be the unique characters
return designs;
}
//generate all permutations for lenOfSequence characters
protected static void genDesigns(String prefix, String data){
int n = data.length();
if (n == 0) designs[index++] = prefix;
else {
for (int i = 0; i < n; i++)
genDesigns(prefix + data.charAt(i), data.substring(0, i) + data.substring(i+1, n));
}
}
【问题讨论】:
-
嗯,我们来粗略估计一下。给定 n 个字母的随机烫发,两个特定字母彼此相邻的概率为 2(n-1)/(n(n-1)) = 2/n。由于我们有 n-1 个这些约束,手动独立假设表明,对于大 n,随机烫发有效的概率约为 (1-2/n)^(n-1) ≈ 1/e^2 ≈ 0.135 .如果这是一个合理的估计,那么你就不能指望获得大的收益——有效的烫发太多了(七分之一或八分之一)!
-
嗯,这里是用于推导有多少这样的排列的实际方程:“随机重排后邻居仍然是邻居的概率”,Amer。数学。月刊 87 (1980), 122-124
-
相同的公式。很高兴知道有一个正式的推导(但我一点也不惊讶)。
标签: java string algorithm permutation