让我们说我有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);
}
}
}
答案 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
在右侧。每个字符可能都是一个数字,因此会发生变化。要检索所有可能的组合,我们想要:
下面的树表示我们要计算的内容(根是单词的第一部分,每个分支表示一个组合)
hello
├───1
│ ├───2 (-> hello12)
│ └───@ (-> hello1@)
└───!
├───2 (-> hello!2)
└───@ (-> hello!@)
您要编写一种算法来收集该树的所有分支。
/!\我建议您在看代码之前尝试实现上述内容:这就是我们提高自我的方式!
以下是相应的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;
}
如果您想让我进一步解释该算法,请发表评论。