我正在尝试查找字符串的所有排列并按字母顺序对它们进行排序。
这是我到目前为止所做的:
public class permutations {
public static void main(String args[]) {
Scanner s = new Scanner(System.in);
System.out.print("Enter String: ");
String chars = s.next();
findPerms("", chars);
}
public static void findPerms(String mystr, String chars) {
List<String> permsList = new ArrayList<String>();
if (chars.length() <= 1)
permsList.add(mystr + chars);
//System.out.print(mystr + chars + " ");
else
for (int i = 0; i < chars.length(); i++) {
String newString = chars.substring(0, i) + chars.substring(i + 1);
findPerms(mystr + chars.charAt(i), newString);
}
Collections.sort(permsList);
for(int i=0; i<permsList.size(); i++) {
System.out.print(permsList.get(i) + " ");
}
}
}
如果我输入字符串“玩具”,我会得到:
玩具tosy tyos tyso tsoy tsyo otys otsy oyts oyst osty osyt ytos ytso yots yost ysto ysot stoy styo soty soyt syto syot
我做错了什么。我怎样才能按字母顺序排列它们?谢谢!
答案 0 :(得分:8)
您正在从递归方法中调用您的排序例程,该方法在完全填充之前找到您的String的所有排列
import java.util.*;
public class permutations {
public static void main(String args[]) {
Scanner s = new Scanner(System.in);
System.out.print("Enter String: ");
String chars = s.next();
List<String> myList = new ArrayList<String>();
findPerms(myList, "", chars);
Collections.sort(myList);
for(int i=0; i<myList.size(); i++) {
System.out.print(myList.get(i) + " ");
}
}
public static void findPerms(List<String> permsList, String mystr, String chars) {
if (chars.length() <= 1)
permsList.add(mystr + chars);
else
for (int i = 0; i < chars.length(); i++) {
String newString = chars.substring(0, i) + chars.substring(i + 1);
findPerms(permsList, mystr + chars.charAt(i), newString);
}
}
}
答案 1 :(得分:2)
有些评论已经指出,你的递归例程不能对叶子节点进行排序,并期望对整个列表进行排序。您必须返回集合中的累积字符串,然后在结尾处对它们进行排序和打印。
更重要的是,有一个很好的算法可以按词汇顺序排列数组。它被C ++中的next_permutation库函数使用(您可以查找解释),但它很容易转换为java。您可以使用char[]
提取getCharArray
数组,并使用Arrays.sort
对其进行排序,然后运行此数组,直到它返回false。
/** Helper function */
void reverse(char[] a, int f, int l)
{
while(l>f)
{
char tmp = a[l];
a[l] = a[f];
a[f] = tmp;
l--; f++;
}
}
/** actual permutation function */
boolean next_permutation(char[] a)
{
if(a.length < 2) return false;
for(int i = a.length-1; i-->0;)
if(a[i] < a[i+1])
{
int j=a.length-1;
while(!(a[i] < a[j]))
j--;
char tmp=a[i];
a[i]=a[j];
a[j]=tmp;
reverse(a, i+1, a.length-1);
return true;
}
reverse(a, 0, a.length-1);
return false;
}
一旦你理解它的作用,只需运行while(next_permutation(array)) {println(array);}
,你就可以了。请注意,这对于超过13个元素的数组来说非常糟糕。
答案 2 :(得分:0)
您需要对findperms调用的结果进行排序,而不是在重复调用中。
答案 3 :(得分:0)
答案 4 :(得分:0)
您可以放置已经获得的所有排列,并将它们放在TreeSet
或PriorityQueue
中,这将使它们按顺序排列。然后,您必须将它们放回到ArrayList中。
或者您可以使用Collections Sort对ArrayList进行排序。
我推荐最后一个选项。 Here is an example如果您不理解它。