我想用a-z创建所有可能的5个字母的单词。请建议任何好的和快速的算法。
我尝试创建一个,它看起来像这样......
byte[] allchar=new byte[] {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
int lengthOfAllChar=allchar.length;
System.out.println(lengthOfAllChar);
for (int i = 0; i < lengthOfAllChar; i++){
for(int j = 0; i < lengthOfAllChar; j++){
StringBuffer finalWordBuffer = new StringBuffer();
finalWordBuffer.append((char)allchar[i]);
finalWordBuffer.append((char)allchar[j]);
}
}
答案 0 :(得分:24)
以下是为任意长度的任何字符集生成所有序列的示例:
public class WordPermutations {
public static void main(String[] args) {
char[] chars = "abcdefghijklmnopqrstuvwxyz".toCharArray();
int len = 5;
iterate(chars, len, new char[len], 0);
}
public static void iterate(char[] chars, int len, char[] build, int pos) {
if (pos == len) {
String word = new String(build);
// do what you need with each word here
return;
}
for (int i = 0; i < chars.length; i++) {
build[pos] = chars[i];
iterate(chars, len, build, pos + 1);
}
}
}
在我的机器上花费大约250ms来迭代所有11,881,376个序列。
请注意,新的char[len]
仅在开头创建一次,并作为构建用于构建排列。第一次拨打iterate()
的电话以pos
0
开头。跳到for循环,循环遍历每个字符。构建的第一个char设置为,然后我们递归调用相同的方法在pos + 1
设置下一个。一旦发生了5次,pos将在len
。这是pos == len
在方法顶部开始的时候。然后它只是根据构建中构建的String
来构建,这就是你的话。
答案 1 :(得分:4)
这也可以在没有递归的情况下轻松完成(在C中)
int i, k, n;
char tmp[6]; tmp[5] = 0;
for (i=0;i<26*26*26*26*26;i++) {
n = i;
for (k=4;k>=0;k--){
tmp[k] = 'a' + (n % 26);
n /= 26;
}
output_string(tmp);
}
或者你可以随身携带:
char tmp[6]; int i, k;
strcpy(tmp, "aaaaa");
for (i=0;i<26*26*26*26*26;i++) {
output_string(tmp);
tmp[4]++;
k = 4;
while (k > 0 && tmp[k] == 'z') { tmp[k] = 'a'; k--; tmp[k]++; }
}
答案 2 :(得分:2)
public static List<String> getAll(int length) {
final char[] chars = "0123456789".toCharArray();
final double NUMBER_OF_PERMUTATIONS = Math.pow(chars.length, length);
List<String> words = new ArrayList<>(Double.valueOf(
NUMBER_OF_PERMUTATIONS).intValue());
char[] temp = new char[length];
Arrays.fill(temp, '0');
for (int i = 0; i < NUMBER_OF_PERMUTATIONS; i++) {
int n = i;
for (int k = 0; k < length; k++) {
temp[k] = chars[n % chars.length];
n /= chars.length;
}
words.add(String.valueOf(temp));
}
return words;
}
以下是antti.huima代码的Java 7版本。
答案 3 :(得分:0)
这是一个让你尝试的算法,伪代码:
array seenWords;
while size of seenWords[] < 26^5:
generate random string of length 5 letters
is string in seenWords?
yes:
go back to while
no:
push string onto end of seenWords[]
done while
您应该能够轻松地将此伪代码转换为适当的Java代码。唯一棘手的一点是生成随机字符串。你可以拿出你的字母数组,选择1到26之间的随机值,然后用它来写一个字母。重复那五次,你有一个五个字母的字符串!
这是一个“好”还是“快”的算法取决于你。你还没有定义“好”或“快”的意思,所以我无法判断。您的标准可能与我不同。
请注意,这将生成所有包含五个字母的字符串。这些可能不是文字。从您的示例代码判断,您希望所有字符串中包含五个字母,而不是包含五个字母的字符。