[英]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;
}
對於這個問題,您確實需要考慮使用基本案例。 看一下您必須處理的一些簡單案例:
從上面我們可以了解問題的結構:
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})。
然后上面的內容回滾了我們得到的“樹”結構:
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.