我有一些字符串。
1
2
3
如何将它们组合成所有独特的组合?
123
132
213
231
312
321
这是我的代码,但我想在没有Random
类的情况下工作,因为我知道这不是最好的方法。
import java.util.Random;
public class Solution
{
public static void main(String[] args)
{
String[] names = new String[]{"string1", "string2", "string3"};
for (int i = 0; i < 9; i++) {
Random rand = new Random();
int rand1 = rand.nextInt(3);
System.out.println(names[rand.nextInt(3)] +
names[rand1] +
names[rand.nextInt(3)]);
}
}
}
答案 0 :(得分:6)
您可以通过为每次重复创建另一个嵌套循环来遍历数组。
for (String word1 : words) {
for (String word2 : words) {
for (String word3 : words) {
System.out.println(word1 + word2 + word3);
}
}
}
以下是如何避免在一个组合中使用相同的单词。
for (String word1 : words) {
for (String word2 : words) {
if ( !word1.equals(word2)) {
for (String word3 : words) {
if ( !word3.equals(word2) && !word3.equals(word1)) {
System.out.println(word1 + word2 + word3);
}
}
}
}
}
这是一个使用回溯的多个长度的类版本。
import java.util.ArrayList;
import java.util.List;
public class PrintAllCombinations {
public void printAllCombinations() {
for (String combination : allCombinations(new String[] { "A", "B", "C" })) {
System.out.println(combination);
}
}
private List<String> allCombinations(final String[] values) {
return allCombinationsRecursive(values, 0, values.length - 1);
}
private List<String> allCombinationsRecursive(String[] values, final int i, final int n) {
List<String> result = new ArrayList<String>();
if (i == n) {
StringBuilder combinedString = new StringBuilder();
for (String value : values) {
combinedString.append(value);
}
result.add(combinedString.toString());
}
for (int j = i; j <= n; j++) {
values = swap(values, i, j);
result.addAll(allCombinationsRecursive(values, i + 1, n));
values = swap(values, i, j); // backtrack
}
return result;
}
private String[] swap(final String[] values, final int i, final int j) {
String tmp = values[i];
values[i] = values[j];
values[j] = tmp;
return values;
}
}
请注意,使用随机方法,永远不能保证所有组合都得到。因此,它应该总是遍历所有值。
答案 1 :(得分:3)
您可以使用Google Guava库来获取所有字符串排列。
Collection<List<String>> permutations = Collections2.permutations(Lists.newArrayList("string1", "string2", "string3"));
for (List<String> permutation : permutations) {
String permutationString = Joiner.on("").join(permutation);
System.out.println(permutationString);
}
输出:
string1string2string3
string1string3string2
string3string1string2
string3string2string1
string2string3string1
string2string1string3
答案 2 :(得分:0)
首先,你所追求的结果中没有随机的内容 - Random.nextInt()
不会给你独特的排列,也不一定会给你所有的排列。
对于 N 元素,有 N!( N -factorial)唯一序列 - 我相信这就是你所追求的。因此,您的三个元素提供六个唯一序列(3! = 3 * 2 * 1
)。
这是因为您可以选择第一个位置(N
)的三个元素,然后选择第二个位置的两个剩余元素(N-1
),留下一个未选择的元素最后一个位置(N-2
)。
因此,这意味着您应该能够遍历序列的所有排列;并且以下代码应该为3个元素的序列执行此操作:
// Select element for first position in sequence...
for (int i = 0 ; i < 3 ; ++i)
{
// Select element for second position in sequence...
for (int j = 0 ; j < 3 ; ++j)
{
// step over indices already used - which means we
// must test the boundary condition again...
if (j >= i) ++j;
if (j >= 3) continue;
// Select element for third position in sequence...
// (there is only one choice!)
for (int k = 0 ; k < 3 ; ++k)
{
// step over indices already used, recheck boundary
// condition...
if (k >= i) ++k;
if (k >= j) ++k;
if (k >= 3) continue;
// Finally, i,j,k should be the next unique permutation...
doSomethingWith (i, j, k);
}
}
}
现在,我刚刚写了这个OTH的重要警告,所以没有guarentees。但是,希望你能看到你需要做什么。当然,这可以而且应该推广到支持仲裁集大小,在这种情况下,您可以使用序列的索引填充int[]
。
但是,我想如果你环顾四周会有更好的算法来生成序列的排列。