【问题标题】:How to code all possible combinations of string?如何编码所有可能的字符串组合?
【发布时间】:2019-10-08 10:54:44
【问题描述】:

假设我有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);
                }
            }
        }

【问题讨论】:

    标签: java combinations


    【解决方案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;
    }
    

    如果您希望我进一步解释算法,请发表评论。

    【讨论】:

      【解决方案2】:

      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"));
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2017-11-11
        • 2015-05-06
        • 1970-01-01
        • 1970-01-01
        • 2018-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多