找出弦的所有排列的优雅方法是什么。例如,ba的排列,将是ba和ab,但更长的字符串,如abcdefgh?是否有Java实现示例?
当前回答
使用递归的简单python解决方案。
def get_permutations(string):
# base case
if len(string) <= 1:
return set([string])
all_chars_except_last = string[:-1]
last_char = string[-1]
# recursive call: get all possible permutations for all chars except last
permutations_of_all_chars_except_last = get_permutations(all_chars_except_last)
# put the last char in all possible positions for each of the above permutations
permutations = set()
for permutation_of_all_chars_except_last in permutations_of_all_chars_except_last:
for position in range(len(all_chars_except_last) + 1):
permutation = permutation_of_all_chars_except_last[:position] + last_char + permutation_of_all_chars_except_last[position:]
permutations.add(permutation)
return permutations
其他回答
递归是不必要的,甚至你可以直接计算任何排列,这个解决方案使用泛型来排列任何数组。
这里有关于这个algorihtm的很好的信息。
对于c#开发人员来说,这里有更有用的实现。
public static void main(String[] args) {
String word = "12345";
Character[] array = ArrayUtils.toObject(word.toCharArray());
long[] factorials = Permutation.getFactorials(array.length + 1);
for (long i = 0; i < factorials[array.length]; i++) {
Character[] permutation = Permutation.<Character>getPermutation(i, array, factorials);
printPermutation(permutation);
}
}
private static void printPermutation(Character[] permutation) {
for (int i = 0; i < permutation.length; i++) {
System.out.print(permutation[i]);
}
System.out.println();
}
该算法计算每个排列的时间和空间复杂度为O(N)。
public class Permutation {
public static <T> T[] getPermutation(long permutationNumber, T[] array, long[] factorials) {
int[] sequence = generateSequence(permutationNumber, array.length - 1, factorials);
T[] permutation = generatePermutation(array, sequence);
return permutation;
}
public static <T> T[] generatePermutation(T[] array, int[] sequence) {
T[] clone = array.clone();
for (int i = 0; i < clone.length - 1; i++) {
swap(clone, i, i + sequence[i]);
}
return clone;
}
private static int[] generateSequence(long permutationNumber, int size, long[] factorials) {
int[] sequence = new int[size];
for (int j = 0; j < sequence.length; j++) {
long factorial = factorials[sequence.length - j];
sequence[j] = (int) (permutationNumber / factorial);
permutationNumber = (int) (permutationNumber % factorial);
}
return sequence;
}
private static <T> void swap(T[] array, int i, int j) {
T t = array[i];
array[i] = array[j];
array[j] = t;
}
public static long[] getFactorials(int length) {
long[] factorials = new long[length];
long factor = 1;
for (int i = 0; i < length; i++) {
factor *= i <= 1 ? 1 : i;
factorials[i] = factor;
}
return factorials;
}
}
改进的代码相同
static String permutationStr[];
static int indexStr = 0;
static int factorial (int i) {
if (i == 1)
return 1;
else
return i * factorial(i-1);
}
public static void permutation(String str) {
char strArr[] = str.toLowerCase().toCharArray();
java.util.Arrays.sort(strArr);
int count = 1, dr = 1;
for (int i = 0; i < strArr.length-1; i++){
if ( strArr[i] == strArr[i+1]) {
count++;
} else {
dr *= factorial(count);
count = 1;
}
}
dr *= factorial(count);
count = factorial(strArr.length) / dr;
permutationStr = new String[count];
permutation("", str);
for (String oneStr : permutationStr){
System.out.println(oneStr);
}
}
private static void permutation(String prefix, String str) {
int n = str.length();
if (n == 0) {
for (int i = 0; i < indexStr; i++){
if(permutationStr[i].equals(prefix))
return;
}
permutationStr[indexStr++] = prefix;
} else {
for (int i = 0; i < n; i++) {
permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i + 1, n));
}
}
}
作为Python生成器,带有现代类型提示:
from typing import Iterator
def permutations(string: str, prefix: str = '') -> Iterator[str]:
if len(string) == 0:
yield prefix
for i, character in enumerate(string):
yield from permutations(string[:i] + string[i + 1:], prefix + character)
for p in permutations('abcd'):
print(p)
这是一个具有O(n!)时间复杂度的算法,具有纯递归和直观。
public class words {
static String combinations;
public static List<String> arrlist=new ArrayList<>();
public static void main(String[] args) {
words obj = new words();
String str="premandl";
obj.getcombination(str, str.length()-1, "");
System.out.println(arrlist);
}
public void getcombination(String str, int charIndex, String output) {
if (str.length() == 0) {
arrlist.add(output);
return ;
}
if (charIndex == -1) {
return ;
}
String character = str.toCharArray()[charIndex] + "";
getcombination(str, --charIndex, output);
String remaining = "";
output = output + character;
remaining = str.substring(0, charIndex + 1) + str.substring(charIndex + 2);
getcombination(remaining, remaining.length() - 1, output);
}
}
public class StringPermutation {
// Function to print all the permutations of str
static void printPermutn(String str, String ans) {
// If string is empty
if (str.length() == 0) {
System.out.print(ans + " ");
return;
}
for (int i = 0; i < str.length(); i++) {
// ith character of str
char ch = str.charAt(i);
// Rest of the string after excluding
// the ith character
String ros = str.substring(0, i) + str.substring(i + 1);
// Recurvise call
printPermutn(ros, ans + ch);
}
}
public static void main(String[] args) {
String s = "ABC";
printPermutn(s, "");
}
}
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap