我决定递归地实现一个非常简单的程序,看看Java如何处理递归*,并且有点简短。这就是我最后写的:
public class largestInIntArray {
public static void main(String[] args)
{
// These three lines just set up an array of ints:
int[] ints = new int[100];
java.util.Random r = new java.util.Random();
for(int i = 0; i < 100; i++) ints[i] = r.nextInt();
System.out.print("Normal:"+normal(ints,-1)+" Recursive:"+recursive(ints,-1));
}
private static int normal(int[] input, int largest) {
for(int i : input)
if(i > largest) largest = i;
return largest;
}
private static int recursive(int[] ints, int largest) {
if(ints.length == 1)
return ints[0] > largest ? ints[0] : largest;
int[] newints = new int[ints.length - 1];
System.arraycopy(ints, 1, newints, 0, ints.length - 1);
return recursive(newints, ints[0] > largest ? ints[0] : largest);
}
}
这样做很好,但因为它有点难看,我想知道是否有更好的方法。如果有人有任何想法/替代/语法糖分享,那将非常感激!
P.S。如果你说“使用Lisp”你什么都不赢(但尊重)。我想知道是否可以在 Java 中看起来很好。
*以及 I 处理递归的程度
答案 0 :(得分:10)
以下是我如何使递归方法看起来更好:
private static int recursive(int[] ints, int largest, int start) {
if (start == ints.length) {
return largest;
}
return recursive(ints, Math.max(ints[start], largest), start + 1);
}
这避免了昂贵的数组副本,并适用于空输入数组。您可以实现一个额外的重载方法,只有两个参数用于与迭代函数相同的签名:
private static int recursive(int[] ints, int largest) {
return recursive(ints, largest, 0);
}
答案 1 :(得分:7)
2项改进:
无需提供当前最大值
private static int recursive(int[] ints, int offset) {
if (ints.length - 1 == offset) {
return ints[offset];
} else {
return Math.max(ints[offset], recursive(ints, offset + 1));
}
}
使用recursive(ints, 0)
开始递归。
答案 2 :(得分:2)
您可以将当前索引作为参数传递,而不是每次都复制几乎整个数组,或者您可以使用分而治之的方法。
答案 3 :(得分:1)
public static int max(int[] numbers) {
int size = numbers.length;
return max(numbers, size-1, numbers[size-1]);
}
public static int max(int[] numbers, int index, int largest) {
largest = Math.max(largest, numbers[index]);
return index > 0 ? max(numbers, index-1, largest) : largest;
}
答案 4 :(得分:1)
...看看Java处理递归的程度
简单的答案是Java不能很好地处理递归。具体来说,Sun java编译器和Hotspot JVM不实现尾调用递归优化,因此递归密集型算法很容易消耗大量的堆栈空间。
但是,我看过有些文章说IBM的JVM 做支持这种优化。我看到一封非Sun公司的电子邮件,他说他将其作为一个实验性Hotspot扩展添加为论文项目。
答案 5 :(得分:1)
这里有一个细微的变化,显示了链接列表对递归的好处,其中“更好”意味着“方法签名中的参数更少”
private static int recursive(LinkedList<Integer> list) {
if (list.size() == 1){
return list.removeFirst();
}
return Math.max(list.removeFirst(),recursive(list));
}
答案 6 :(得分:0)
您的递归代码使用System.arrayCopy
,但您的迭代代码不会这样做,因此您的微基准测试不准确。正如其他人所提到的,您可以使用Math.min
并使用数组索引而不是类似于队列的方法来清理该代码。
答案 7 :(得分:0)
public class Maximum
{
/**
* Just adapted the iterative approach of finding maximum and formed a recursive function
*/
public static int max(int[] arr,int n,int m)
{
if(m < arr[n])
{
m = arr[n];
return max(arr,n - 1,m);
}
return m;
}
public static void main(String[] args)
{
int[] arr = {1,2,3,4,5,10,203,2,244,245,1000,55000,2223};
int max1 = max(arr,arr.length-1,arr[0]);
System.out.println("Max: "+ max1);
}
}
答案 8 :(得分:0)
我实际上有一个预制类,我设置它来查找任何值集的最大整数。您可以将此类放入项目中,只需在任何类中使用它,如下所示:
System.out.println(figures.getLargest(8,6,12,9,120));
这将返回值“120”并将其放在输出中。如果您有兴趣使用它,那么这是方法源代码:
public class figures {
public static int getLargest(int...f) {
int[] score = new int[f.length];
int largest=0;
for(int x=0;x<f.length;x++) {
for(int z=0;z<f.length;z++) {
if(f[x]>=f[z]) {
score[x]++;
}else if(f[x]<f[z]) {
}else {
continue;
}
if(z>=f.length) {
z=0;
break;
}
}
}
for(int fg=0;fg<f.length;fg++) {
if(score[fg]==f.length) {
largest = f[fg];
}
}
return largest;
}
}
答案 9 :(得分:0)
以下是我的Java讲师吴教授在他的一个讲座中给出的示例代码。希望它有所帮助。
import java.util.Random;
public class Recursion
{
static int s = 0;
public static Double max(Double[] d, int n, Double max)
{
if (n==0) { return max;}
else
{
if (d[n] > max)
{
max = d[n];
}
return max(d, n-1, max);
}
}
public static void main(String[] args)
{
Random rn = new Random();
Double[] d = new Double[15];
for (int i=0; i {
d[i] = rn.nextDouble();
System.out.println(d[i]);
}
System.out.print("\nMax: " + max(d, d.length-1, d[0]));
}
}
答案 10 :(得分:0)
这是我的替代
public class recursion
{
public static int max( int[] n, int index )
{
if(index == n.length-1) // If it's simple, solve it immediately:
return n[index]; // when there's only one number, return it
if(max(n, index+1) > n [index]) // is one number bigger than n?
return max(n, index+1); // return the rest, which contains that bigger number
return n[index]; // if not, return n which must be the biggest number then
}
public static void main(String[] args)
{
int[] n = {100, 3, 5, 1, 2, 10, 2, 15, -1, 20, -1203}; // just some numbers for testing
System.out.println(max(n,0));
}
}