我有这段java代码:
int maxDigit = 4;
for(int a = 0; a <= maxDigit; a++)
{
for(int b = 0; b <= maxDigit; b++)
{
if(b != a){
for(int c = 0; c <= maxDigit; c++)
{
if(c != a && c != b)
{
for(int d = 0; d <= maxDigit; d++)
{
if(d != a && d != b && d != c)
{
for(int e = 0; e <= maxDigit; e++)
{
if(e != a && e != b && e != c && e != d)
{
String temp = a + "" + b + "" + c + "" + d + "" + e;
System.out.println(temp);
permutations.add(Integer.parseInt(temp));
}
}
}
}
}
}
}
}
}
如何将这段代码转换为函数?
目的是生成数字0到9的排列,这里的代码在0到4之间。看起来很容易将它放在函数中,但我无法立即找到它。
答案 0 :(得分:2)
这是获取all permutations of a string的典型问题的变体。
您的教授希望您做的归纳是这个问题非常适合使用递归的解决方案。
字符串s
的排列的基本算法如下:
s
中的第一项。s
中其他项目的所有排列(所选项目除外)。s
的下一个字符。这是使用Functional Java库的有效解决方案。
导入这些......
import fj.F;
import fj.P2;
import fj.P1;
import fj.data.Stream;
import static fj.data.Stream.nil;
import static fj.data.Stream.cons;
import static fj.data.Stream.range;
import static fj.data.Enumerator.charEnumerator;
import static fj.data.Show.streamShow;
import static fj.data.Show.charShow;
import static fj.P2.map2_;
查找排列的递归函数:
public Stream<Stream<Character>> permutations(final Stream<Character> s) {
return selections(s).bind(
new F<P2<Character, Stream<Character>>, Stream<Stream<Character>>>() {
public Stream<Stream<Character>>()
f(final P2<Character, Stream<Character>> ys) {
return permutations(ys._2()).bind(cons(ys._1()));
}
});
}
依次选择每个元素的递归函数:
public Stream<P2<Character, Stream<Character>>>
selections(final Stream<Character> s) {
if (xs.isEmpty())
return nil();
else {
final char x = xs.head();
final Stream<Character> xs = s.tail()._1();
return cons(P.p(x, xs),
new P1<Stream<P2<Character, Stream<Character>>>>() {
public Stream<P2<Character, Stream<Character>>> _1() {
return selections(xs).map(map2_().f(cons(x))));
}
});
}
}
然后,获取字符'0'到'9'的所有排列:
Show<Stream<Character>> s = streamShow(charShow);
for (Stream<Character> ps : permutations(range(charEnumerator, '0', '9'))) {
System.out.println(s.showS(ps));
}
编辑:这实际上是comonads的一个很好的用例。使用Functional Java的最新主干,您可以使用Zipper comonad执行此操作,如下所示:
public static Stream<Stream<Character>> perms(Stream<Character> s) {
Stream<Stream<Character>> r = single(Stream.<Character>nil());
for (final Zipper<Character> z : fromStream(s))
r = join(z.cobind(
new F<Zipper<Character>, Stream<Stream<Character>>>() {
public Stream<Stream<Character>> f(final Zipper<Character> zp) {
return perms(zp.lefts().reverse().append(zp.rights())).map(compose(
Stream.<Character>cons().f(zp.focus()),
P.<Stream<Character>>p1()));
}
}).toStream());
return r;
}
答案 1 :(得分:1)
填补空洞:
int[] indexes = { 0, 0, 0, 0, 0 };
addPermutations(maxDigit, indexes, 0, permutations);
void addPermutations(int max, int[] indexes, int currentIndex, List<Integer> permutations) {
if (currentIndex == indexes.length) {
// terminal case
String temp = ...;
System.out.println(temp);
permutations.add(Integer.parseInt(temp));
} else {
// recursive case
for (int i = 0; i <= max; i++) {
if (... != i) {
indexes[currentIndex] = i;
addPermutations(max, indexes, currentIndex+1, permutations);
}
}
}
}
答案 2 :(得分:0)
答案 3 :(得分:0)
没有代码,但算法应如下所示。
假设您想要从0到7的所有5位数的排列。为此:
j =
十进制值为100000(1 + 5个零)for i = 0; i < j; ++i
,将每个i
转换为base-7系统,可选择在前缀为零。答案 4 :(得分:0)
您可以使用N-ary树,每个点有4个分支,递归导航树并跨越已经看到该节点数字的分支?