java - 将 for 循环重构为函数

标签 java function for-loop

我有这段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排列的基本算法如下:

  1. 选择s中的第一项。
  2. 获取 s 中其他项目的所有排列(所选项目除外)。
  3. 将所选项目添加到第 2 步中的每个排列之前。
  4. 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/

相关文章:

java - 反射访问在 IntelliJ IDEA 中的模块化(Java 9+)应用程序的测试中不起作用

javascript - 在 Java 中使用 EXSLT 验证 XML?

c - 结构中函数中的指针不起作用

javascript - 主干设置方法,传递一个变量作为键?

JavaScript + HTML : Button Not Calling on Function Onclick

Javascript 使用 for 循环累加器将数字添加到表格单元格 ID

c - 在C中循环帮助!

java - 使用 typesafe/akka config 合并多级配置

python - 如何在每次循环调用时更新 Python 函数参数?

java - 使用 JpaPagingItemReader 时无法获取基于不同 pageSize 和 ChunkSize 的所有记录