如何编码所有可能的字符串组合?

时间:2019-10-08 10:54:44

标签: java combinations

让我们说我有String word = "hello12"

我需要使用特殊字符而不是数字的所有可能组合(使用shift + number时得到的字符)。所以,我想得到的结果是hello12,hello!2,hello1 @,hello!@。

我所做的是创建所有情况下的开关(1 ='!',2 ='@'...),但是我无法获得如何对所有组合进行编码的信息。我所能编码的是用特殊符号更改所有数字(代码在下面)

char[] passwordInCharArray;

        for(int i=0; i<passwordList.length; i++){
            for(int j = 0; j<passwordList[i].length(); j++){
                if(Character.isDigit((passwordList[i].charAt(j)))){
                    passwordInCharArray = passwordList[i].toCharArray();
                    passwordInCharArray[j] = getSpecialSymbol(passwordList[i].charAt(j));
                    passwordList[i]=String.valueOf(passwordInCharArray);
                }
            }
        }

2 个答案:

答案 0 :(得分:1)

Generate All Possible Combinations - Java中的代码为基础,我想出了实现您需要的此实现。它将找到字符串中所有数字的索引,然后生成所有可能的特殊字符替换它们的可能性。

import java.util.*;

public class Comb {

    public static List<String> combinations(String pass) {
        String replace = ")!@#$%^&*(";
        char[] password = pass.toCharArray();
        List<Integer> index = new ArrayList<Integer>();
        List<String> results = new ArrayList<String>();
        results.add(pass);

        //find all digits
        for (int i = 0; i < password.length; i++) {
            if (Character.isDigit(password[i])) {
                index.add(i);
            }
        }

        //generate combinations
        int N = (int) Math.pow(2d, Double.valueOf(index.size()));  
        for (int i = 1; i < N; i++) {
            String code = Integer.toBinaryString(N | i).substring(1);
            char[] p = Arrays.copyOf(password, password.length);

            //replace the digits with special chars
            for (int j = 0; j < index.size(); j++) {
                if (code.charAt(j) == '1') {
                    p[index.get(j)] = replace.charAt(p[index.get(j)] - '0');
                }
            }
            results.add(String.valueOf(p));
        }
        return results;
    }

    public static void main(String... args) {
        System.out.println(combinations("hello12"));
    }
}

答案 1 :(得分:1)

理论

使用recursive methods(自称方法的方法)通常更容易表达组合。

我认为通过一个示例可以更轻松地理解该算法,因此让我们以String word = hello12为例。

我们将迭代每个字符,直到找到一个数字。第一个是1。在这一点上,我们可以想象一个虚拟光标将单词分为两部分:

  • hello在左侧。我们知道它不会改变。
  • 12在右侧。每个字符可能都是一个数字,因此会发生变化。

要检索所有可能的组合,我们想要:

  1. 保留单词的第一部分
  2. 计算单词第二部分的所有可能组合
  3. 将这些组合的每一个附加到单词的第一部分

下面的树表示我们要计算的内容(根是单词的第一部分,每个分支表示一个组合)

hello
├───1
│   ├───2 (-> hello12)
│   └───@ (-> hello1@)
└───!
    ├───2 (-> hello!2)
    └───@ (-> hello!@)

您要编写一种算法来收集该树的所有分支。

Java代码

/!\我建议您在看代码之前尝试实现上述内容:这就是我们提高自我的方式!

以下是相应的Java代码:

public static void main(String[] args) {
    Set<String> combinations = combinate("hello12");
    combinations.forEach(System.out::println);
}

public static Set<String> combinate(String word) {
    // Will hold all the combinations of word
    Set<String> combinations = new HashSet<String>();

    // The word is a combination (could be ignored if empty, though)
    combinations.add(word);

    // Iterate on each word's characters
    for (int i = 0; i < word.toCharArray().length; i++) {
        char character = word.toCharArray()[i];

        // If the character should be replaced...
        if (Character.isDigit(character)) {

            // ... we split the word in two at the character's position & pay attention not be exceed word's length  
            String firstWordPart = word.substring(0, i);
            boolean isWordEnd = i + 1 >= word.length();
            String secondWordPart = isWordEnd ? "" : word.substring(i + 1);

            // Here is the trick: we compute all combinations of the second word part... 
            Set<String> allCombinationsOfSecondPart = combinate(secondWordPart);

            // ... and we append each of them to the first word part one by one
            for (String string : allCombinationsOfSecondPart) {
                String combination = firstWordPart + getSpecialSymbol(character) + string;
                combinations.add(combination);
            }
        }
    }
    return combinations;
}

如果您想让我进一步解释该算法,请发表评论。