我有这段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。将它放入函数中似乎很容易,但我无法立即找到它。
最佳答案
这是获取 all permutations of a string 的经典问题的变体.
你的教授希望你做出的归纳是,这个问题非常适合使用递归的解决方案。
字符串s
排列的基本算法如下:
- 选择
s
中的第一项。 - 获取
s
中其他项目的所有排列(所选项目除外)。 - 将所选项目添加到第 2 步中的每个排列之前。
- 对
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 的一个很好的用例。 。使用 Function 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;
}
关于java - 将 for 循环重构为函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/720866/