簡體   English   中英

在Java中使用遞歸查找數組中的最大元素

[英]Finding the largest element in an array using recursion in Java

這是我到目前為止所擁有的,但我對如何跟蹤索引感到困惑。 我會更改方法的參數,但不允許。 我只能使用循環來制作另一個數組。 這些是限制。

public class RecursiveFinder {

    static int checkedIndex = 0;
    static int largest = 0;


    public static int largestElement(int[] start){
        int length = start.length;

        if(start[length-1] > largest){
            largest = start[length-1];
            int[] newArray = Arrays.copyOf(start, length-1);
            largestElement(newArray);
        }
        else{
            return largest;
        }
    }


    /**
     * @param args
     */
    public static void main(String[] args) {
        int[] array1 = {0,3,3643,25,252,25232,3534,25,25235,2523,2426548,765836,7475,35,547,636,367,364,355,2,5,5,5,535};
        System.out.println(largestElement(array1));
        int[] array2 = {1,2,3,4,5,6,7,8,9};
        System.out.println(largestElement(array2));
    }

}

遞歸方法不需要將最大值保留在里面。

2參數方法

開始調用:

largestElement(array, array.length-1)

這是方法:

public static int largestElement(int[] start, int index) {
    if (index>0) {
        return Math.max(start[index], largestElement(start, index-1))
    } else {
        return start[0];
    }
}

第 3 行方法是最難理解的。 它返回兩個元素之一,即當前索引中的一個和要遞歸檢查的剩余元素中的一個。

if (index>0)的條件類似於 while 循環。 只要索引保持正數(到達數組中的元素),就會調用該函數。


1 參數方法

這個有點棘手,因為您必須傳遞比上一次迭代更小的數組。

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

我希望您出於學習目的這樣做,實際上沒有人需要在 Java 中這樣做。

你不需要在你的方法之外保留一個largest的變量——這通常不是遞歸的好習慣,它應該返回結果的所有上下文。

當您考慮遞歸時,請嘗試根據答案顯而易見的簡單基本情況進行思考,然后對於所有其他情況如何將其分解為更簡單的情況。

所以在偽代碼中你的算法應該是這樣的:

func largest(int[] array)
    if array has 1 element
        return that element
    else
        return the larger of the first element and the result of calling largest(remaining elements)

您可以使用Math.max進行“更大”的計算。

不幸的是,您無法更改參數,因為如果您可以將索引傳遞到開始處或使用列表和子列表,則會更容易。 但是您的復制方法應該可以正常工作(假設效率不是問題)。

上述算法的替代方法是將空數組作為基本情況。 這具有處理空數組的優點(通過返回 Integer.MIN_VALUE):

int largest(int[] array) {
    return array.length == 0 
        ? Integer.MIN_VALUE
        : Math.max(array[0], largest(Arrays.copyOfRange(array, 1, array.length)));
}

嘗試上層階級,留下正確的主要方法。

public class dammm {



public static int largestElement(int[] start){
int largest = start[0];

for(int i = 0; i<start.length; i++) {
    if(start[i] > largest){

        largest = start[i];
    }

    }return largest;
}

對於這個問題,您確實需要考慮使用基本案例。 看一下您必須處理的一些簡單案例:

  1. 如果數組長度為 1,則返回唯一值
  2. 如果數組長度為 2,則返回兩個值中的最大值
  3. 如果數組長度為 3,那么 ?

從上面我們可以了解問題的結構:

if array.length == 1 then
    return array[0]
else
    return the maximum of the values

在上面如果我們只有一個元素,它是列表中的最大值。 如果我們有兩個值,那么我們必須找到這些值的最大值。 由此,我們可以使用這樣的想法,如果我們有三個值,我們可以找到其中兩個的最大值,然后將最大值與第三個值進行比較。 將其擴展為偽代碼,我們可以得到如下內容:

if array.length == 1 then
    return array[0]
else
    new array = array without the first element (e.g. {1, 2, 3} => {2, 3})
    return maximum(array[0], largestElement(new array))

為了更好地解釋上面的內容,可以將執行想象成一個鏈(例如 {1, 2, 3})。

  • 數組:{1, 2, 3},最大值(數組 [0] = 1,最大元素(新數組 = {2, 3}))
    • 數組:{2, 3},最大值(數組 [0] = 2,最大元素(新數組 = {3}))
      • 數組:{3},數組[0] = 3 => 長度為 1 所以返回 3

然后上面的內容回滾了我們得到的“樹”結構:

maximum (1, maximum(2, (return 3)))

一旦你有了最大值,你就可以使用上面的示例原理,通過單獨的方法找到索引:

indexOf(array, maximum)
    if array[0] == maximum then
       return 0
    else if array.length == 1 then
       return -1 
    else
       new array = array without the first element (e.g. {1, 2, 3} => {2, 3})
       result = indexOf(new array, maximum)
       return (result == -1) ? result : result + 1

為了更多地研究這個,我會從 Racket 語言中閱讀這個 從本質上講,它展示了純粹由pairs組成的數組的想法,以及如何使用遞歸對其進行迭代。

如果你有興趣,Racket 是理解遞歸的一個很好的資源。 您可以查看關於 Racket 的滑鐵盧大學教程 它可以以易於理解的方式向您簡要介紹遞歸,並通過一些示例引導您更好地理解它。

如果您的目標是通過使用遞歸來實現這一點,那么這就是您需要的代碼。 它不是最有效的,也不是解決問題的最佳方法,但它可能是您所需要的。

public static int largestElement(int[] start){
    int length = start.length;

    if (start.lenght == 1){
        return start[0];
    } else {
        int x = largestElement(Arrays.copyOf(start, length-1))
        if (x > start[length-1]){
            return x;
        } else {
            return start[length-1];
        }
    }       
}

想象一下,您有一組數字,您只需將一個數字與其他數字進行比較。

例如,給定集合{1,8,5}我們只需要檢查5是否大於{1,8}中的最大值。 以同樣的方式,您必須檢查8是否大於{1}的最大值。 在下一次迭代中,當集合有一個值時,您知道該值是集合中的較大值。

因此,您返回上一級並檢查返回值 ( 1 ) 是否大於8 結果 ( 8 ) 將返回到上一級並與5進行檢查。 結論是8是較大的值

一個參數,不復制。 棘手的是,我們需要將一個較小的數組傳遞給同一個方法。 所以需要一個全局變量。

    // Number of elements checked so far.
    private static int current = -1;

    // returns the largest element.
    // current should be -1 when user calls this method.
    public static int largestElement(int[] array) {
        if (array.length > 0) {
            boolean resetCurrent = false;

            if (current == -1) {
                // Initialization
                current = 0;
                resetCurrent = true;
            } else if (current >= array.length - 1) {
                // Base case
                return array[array.length - 1];
            }

            try {
                int i = current++;
                return Math.max(array[i], largestElement(array));
            } finally {
                if (resetCurrent) {
                    current = -1;
                }
            }
        }
        throw new IllegalArgumentException("Input array is empty.");
    }

如果您可以創建另一種方法,那么一切都會簡單得多。

private static int recursiveFindLargest(int [] array, int i) {
    if (i > 0) {
        return Math.max(array[i], recursiveFindLargest(array, i-1));
    } else {
        return array[0];
    }
}

public static int largestElement(int [] array) {
    // For empty array, we cannot return a value to indicate this situation,
    //all integer values are possible for non-empty arrays.
    if (array.length == 0) throw new IllegalArgumentException();

    return recursiveFindLargest(array, array.length - 1);
}

您可以通過比較數組中的兩個數字([n]和[n + 1]),然后將較大的值放在較小的位置來使用遞歸來修改數組。 因此,通過增加n,可以比較所有元素。 因此,數組的最后一個元素是最大的。

public static int findLargest( int[] nums, int n ) {

  if ( nums[n] > nums[n+1] ) {
     nums[ n + 1 ] = nums[n];
  }

  else if ( n == nums.length - 2 ) { //if last element is bigger than previous one
     return nums[nums.length - 1]; 
  } 

  if( n == nums.length - 2 ){ return nums[n]; }
  return findLargest( nums, n + 1 );

}

這是具有一種方法參數的代碼的工作示例

    public int max(int[] list) {
        if (list.length == 2) return Math.max(list[0], list[1]);
        int max = max(Arrays.copyOfRange(list, 1, list.length));
        return list[0] < max ? max : list[0];
    }
private static int maxNumber(int[] arr,int n,int max){
    if(n<0){
        return max;
    }
   max = Math.max(arr[n],max);
   return maxNumber(arr,n-1,max);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM