执行“max”的功能方式(使用递归/没有可变变量)

时间:2013-04-22 21:33:36

标签: java scala functional-programming

使用命令式代码在未排序的数组中查找最大值非常简单

e.g。在Java中(我确信它可以写得更好,仅用于说明目的)

public class Main {
    public static void main(String[] args) {
        int[] array = {1,3,5,4,2};
        int max = findMax(array);
        System.out.println(max);
    }

    public static int findMax(int[] array){
        int max = Integer.MIN_VALUE; //or array[0], but it requires a null check and I want to keep it simple :)
        for (int i = 0, size = array.length; i < size ; i++) {
            int current = array[i];
            if(current > max) max = current;
        }
        return max;
    }
}

这样做的功能方法是什么?例如

  • 没有可变变量(例如,scala中的最大值为val / Java中的final
  • 没有循环(例如使用递归,首选尾部)

在Scala的消息来源中,我看到它是使用recudeLeft完成的,这看起来很聪明

  def max[B >: A](implicit cmp: Ordering[B]): A = {
    if (isEmpty)
      throw new UnsupportedOperationException("empty.max")

    reduceLeft((x, y) => if (cmp.gteq(x, y)) x else y)
  }

但是,假设我没有(由于某种原因)reduce / reduceLeft可用/已实现(我不希望/不能因某些原因实现它,即我正在使用普通Java)

什么是“惯用”功能方式,在不依赖其他功能方法的情况下做到最大化(例如,我将如何在简单的Java中实现它,但是考虑到功能范例)

答案可以使用任何语言(但Java / Scala首选)

3 个答案:

答案 0 :(得分:4)

这是一个尾调用递归实现,累加器为最大值。

public class Main {

    public static void main(String[] args) {
        System.out.println(max(new int[]{6, 3, 9, 4}));
    }

    public static int max(int[] ints) {
        return max(ints, Integer.MIN_VALUE);
    }

    public static int max(int[] ints, int max) {
        if (ints.length == 0) {
            return max;
        } else {
            return max(Arrays.copyOfRange(ints, 1, ints.length), ints[0] > max ? ints[0] : max);
        }
    }

}

答案 1 :(得分:1)

你可以使用普通递归来实现,但是maba的尾递归版应该有更好的性能。

import java.util.Arrays;
public class TestMax {
public static int findMax(int[] array) {
    if(array.length == 1)
        return array[0];
    int[] newArray = Arrays.copyOfRange(array, 1, array.length);
    if(array[0] > findMax(newArray))
        return array[0];
    else
        return findMax(newArray);
}
/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    int[] array = {1,3,5,4,2, 9};
    int max = findMax(array);
    System.out.println(max);
}
}

答案 2 :(得分:1)

基于maba的优秀答案,如果有人感兴趣,可以使用Scala版本

  def max(list: List[Int]) = {
    maxAcc(list, Int.MinValue)
  }                                               

  def maxAcc(list: List[Int], curMax:Int):Int = {
    list match {
        case Nil => curMax
        case head :: tail => maxAcc(tail, if (head > curMax ) head else curMax )
    }
  }

编辑:感谢maba对@tailrec的评论 - 这是修改后的版本

 def max(list: List[Int]) = {
    @tailrec def maxAcc(list: List[Int], curMax: Int): Int = {
      list match {
        case Nil => curMax
        case head :: tail => maxAcc(tail, if (head > curMax) head else curMax)
      }
    }
    maxAcc(list, Int.MinValue)
  }