给出3个唯一字母:您可以使用递归功能打印六个可能的字母的非重复组合。 “ cat”应输出:cat,act,atc,tac,tca和cta。这是我的程序,找不到递归算法。这是我的尝试:
static void findWords(StringBuilder string, int start, int stride) {
//1. iterate through all possible combinations of the chars recursively
System.out.println(string);
if (stride < string.length() && start < string.length())
{
char temp = string.charAt(stride);
string.setCharAt(stride, string.charAt(start));
string.setCharAt(start, temp);
findWords(string, start, stride + 1);
findWords(string, start + 1, stride + 1 );
}
}
public static void main(String[] args)
{
StringBuilder word = new StringBuilder("cat");
findWords(word,0,1);
}
答案 0 :(得分:1)
解决方案:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
static List<String> resultList = new ArrayList<>();
static void computeResult(char[] s, int pos, String resultString) {
if (pos == 3) {
resultList.add(resultString);
return;
}
for (int i = 0; i < 3; ++i) {
if (!resultString.contains(String.valueOf(s[i]))) {
computeResult(s, pos + 1, resultString + s[i]);
}
}
}
public static void main(String... args) {
Scanner sc = new Scanner(System.in);
char[] s = sc.next().toCharArray();
sc.close();
computeResult(s, 0, "");
for(String str : resultList) {
System.out.println(str);
}
}
}
说明:
递归由computeResult
函数完成。它以空字符串开头,然后遍历所有可能的字母“ c”,“ a”和“ t”,并将它们附加到resultString上,现在有3个字符串,并且每个字符串都有函数computeResult
再次被调用。然后,它执行相同的操作,并且仅将尚未添加的那些字母添加到resultString中,因此在“ c”中,我们附加“ a”,从而导致“ ca”和“ t”,从而导致“ ct”,我想想剩下的你可以弄清楚自己。
请注意,如果字母是唯一的,则可以这样做。如果没有,例如,给您提供字符串“ tat”,则可以将其转换为t1a1t2,并对数组['t1','a1','t2']执行相同的过程,然后删除数字。 / p>
答案 1 :(得分:1)
我使用的算法非常简单。将每个字符设为字符串的第一个字符,然后查找与其他两个字符的组合。因此,对于字符c,a,t,组合为
c at
c ta
a ct
a tc
t ca
t ac
代码:
static void findWords(String str, int pos) {
if(str == null || pos < -1) {
return;
}
int len = str.length();
if(pos + 1 < len) {
findWords(str, pos + 1);
}
//find char swap positions
int pos1 = (pos + 1) % len;
int pos2 = (pos - 1 + len) % len;
char[] chars = str.toCharArray();
String str1 = new String(new char[] {chars[pos], chars[pos1], chars[pos2]});
String str2 = new String(new char[] {chars[pos], chars[pos2], chars[pos1]});
System.out.println(str1);
System.out.println(str2);
}
public static void main(String[] args) {
String word = new String("abc");
findWords(word, 0);
}
答案 2 :(得分:0)
这是一个完整的工作示例,上面有我的评论来解释算法。
此解决方案基于回溯。详细了解该here。把问题看成一棵树。在您的示例中,单词是“ cat”。这里有一些ascii艺术...
cat
/ | \
Cat Act Tca
/ \ / \ / \
CAt CTa ACt ATc TCa TAc
每次通过时,您都要固定一个字母(我把它写为大写)。树越深,交换就越少,因为您已经固定了一定数量的字母(在级别0,什么都没有固定,在级别1,一个字母是固定的,所以可以进行交换,在第2级,您不再有交换(交换将与它本身进行),因此递归达到其基本情况。
public static void main(String[] args) {
// get all the permutations of a word with distinct letters
Set<String> permutations = getPermutations("cat");
// print the resulting set
System.out.println(permutations);
}
private static Set<String> getPermutations(String string) {
// recursive call to get a permutation of the given string and put it in
// the set of permutations (initially empty)
return permute(string, 0, string.length() - 1, new HashSet<String>());
}
private static Set<String> permute(String string, int left, int right, Set<String> set) {
if (left == right) {
// swap would be with itself so just add the string
// this is the base case
set.add(string);
} else {
for (int i = left; i <= right; i++) {
// indices are different, something can be swapped so swap it
string = swap(string, left, i);
// permute the swapped string starting from the next available character
permute(string, left + 1, right, set);
}
}
return set;
}
// utility method to carry out the swapping
// you could do this with primitive char[] and probably improve performance
// but for the sake of simplicity as it's just an exercise I used a
// StringBuilder
private static String swap(String in, int i, int j) {
char tmp1 = in.charAt(i);
char tmp2 = in.charAt(j);
StringBuilder sb = new StringBuilder(in);
// put the char at j in place of the char at i
sb.setCharAt(i, tmp2);
// and do the same the other way around
sb.setCharAt(j, tmp1);
return sb.toString();
}