将多个字符串混合到所有可能的组合中

时间:2014-11-11 14:52:08

标签: java string mixing

我有一些字符串。

  1. 1

  2. 2

  3. 3

  4. 如何将它们组合成所有独特的组合?

    1. 123

    2. 132

    3. 213

    4. 231

    5. 312

    6. 321

    7. 这是我的代码,但我想在没有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)]);
              }
          }
      }
      

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[]

但是,我想如果你环顾四周会有更好的算法来生成序列的排列。