2009-12-31 28 views
6

द्वारा सरणी में सबसे बड़ा सकारात्मक int ढूँढना मैंने जावा को रिकर्सन को कितनी अच्छी तरह से संभाला है, यह देखने के लिए, मैंने एक बहुत ही सरल प्रोग्राम को दोबारा लागू करने का निर्णय लिया, और थोड़ा सा आया।रिकर्सन

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); 
    } 
} 

और वह ठीक काम करता है, लेकिन जैसा कि यह थोड़ा बदसूरत है मैं अगर वहाँ एक बेहतर तरीका था सोचा: यह है कि मैं क्या लेखन समाप्त हो गया है। अगर किसी के पास साझा करने के लिए कोई विचार/विकल्प/वाक्य रचनात्मक चीनी है, तो इसकी बहुत सराहना की जाएगी!

पी। यदि आप कहते हैं "लिस्प का उपयोग करें" तो आप कुछ भी नहीं जीतते (लेकिन सम्मान)। मैं जानना चाहता हूं कि यह जावा में अच्छा दिखने के लिए बनाया जा सकता है या नहीं।

* और कैसे अच्छी तरह से मैं संभाल प्रत्यावर्तन

+0

Recursion बहुत दुर्लभ मामलों को छोड़कर यात्रा के रूप में सरल या जावा में कुशल होने के लिए नहीं जा रहा है। –

+0

हाँ, लेकिन अगर कोई रिकर्सन की अंतरिक्ष जटिलता के लिए अच्छी तरह से तैयार होने जा रहा है, तो यह जावा डेवलपर है :) –

+2

किसी भी भाषा में, आपको हमेशा सरणी की प्रतिलिपि बनाना होगा, या उस सरणी में इंडेक्स पास करना होगा। यदि आपका मतलब है "लिंक्ड सूची का उपयोग करके लिस्प", तो सुनिश्चित करें कि यह "जावा एक सरणी का उपयोग कर" से बेहतर है, लेकिन मुझे लगता है कि "एक्स एक लिंक्ड लिस्ट का उपयोग कर एक्स" किसी भी एक्स और वाई के लिए "ए सर का उपयोग कर" से बेहतर है। (सामान्य लिस्प में विस्थापित सरणी आपके लिए कुछ बहीखाता संभालती हैं, लेकिन मुझे नहीं लगता कि वे वास्तव में इस मामले को अधिक सरल बनाते हैं।) – Ken

उत्तर

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)); 
        } 
    } 
    
  • देने के लिए कोई जरूरत नहीं 0

recursive(ints, 0) के साथ रिकर्सन प्रारंभ करें।

+0

मैं वास्तव में इसे पसंद करता हूं क्योंकि इसका पुनरावृत्ति का उपयोग विजेता उत्तर से अधिक प्रेरक है, लेकिन यह कुछ चीजें नहीं करता जो विजेता करता है। धन्यवाद हालांकि :) –

+0

जैसे? मेरी आंखों में एकमात्र अंतर एक खाली सरणी का संचालन है जो यहां अपवाद फेंकता है (अच्छा, कोई अधिकतम कोई अच्छा जवाब नहीं है) जीतने वाले उत्तर में मनमानी (झूठा) मूल्य लौट रहा है। – Jerome

+0

अच्छा बिंदु। बदला हुआ। –

2

हर बार लगभग पूरे सरणी को कॉपी के बजाय एक पैरामीटर के रूप में वर्तमान सूचकांक गुजारें सकता या आप एक विभाजन का उपयोग करें और दृष्टिकोण को जीत सकता है।

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

जौई, क्या मैथ.मैक्स और एक टर्नरी ऑपरेटर के बीच कोई अंतर है? –

+0

हां, मुझे लगता है कि एक ही उद्देश्य के लिए जावा सशर्त ऑपरेटर का उपयोग करने से 'अधिकतम() 'का उपयोग करना आसान है। यदि कोई प्रदर्शन अंतर है, तो आपको इसे अपने विशिष्ट वातावरण के लिए मापना होगा। –

+1

अधिकतम() के साथ आपको खुद को दोहराना नहीं है। – Ken

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; 
} 
0

आपका रिकर्सिव कोड System.arrayCopy का उपयोग करता है, लेकिन आपका पुनरावृत्ति कोड ऐसा नहीं करता है, इसलिए आपका माइक्रोबेंमार्क सटीक नहीं होगा। जैसा कि अन्य ने उल्लेख किया है, आप Math.min का उपयोग कर उस कोड को साफ़ कर सकते हैं और आपके पास कतार जैसी दृष्टिकोण के बजाय सरणी अनुक्रमणिका का उपयोग कर सकते हैं।

1

... कितनी अच्छी तरह जावा प्रत्यावर्तन

संभालती देखने के लिए सरल जवाब है कि जावा प्रत्यावर्तन अच्छी तरह से संभाल नहीं है। विशेष रूप से, सूर्य जावा कंपाइलर्स और हॉटस्पॉट जेवीएम पूंछ कॉल रिकर्सन ऑप्टिमाइज़ेशन को लागू नहीं करते हैं, इसलिए आवर्ती गहन एल्गोरिदम आसानी से बहुत सी स्टैक स्पेस का उपभोग कर सकते हैं।

हालांकि, मैंने लेखों को देखा है जो कहते हैं कि आईबीएम के जेवीएम इस अनुकूलन का समर्थन करते हैं। और मैंने कुछ गैर-सूर्य लड़के से एक ईमेल देखा जिसने कहा कि वह इसे एक प्रयोगात्मक हॉटस्पॉट एक्सटेंशन के रूप में एक थीसिस प्रोजेक्ट के रूप में जोड़ रहा था।

+0

मुझे आश्चर्य है कि इसमें कुछ भी आया है। –

+0

[स्पष्ट रूप से कुछ नहीं] (http://www.drdobbs.com/jvm/tail-call-optimization-and-java/240167044) :) –

1

यहाँ एक मामूली दिखा कैसे लिंक्ड सूचियों अक्सर प्रत्यावर्तन, जहाँ "अच्छे" का अर्थ है "विधि हस्ताक्षर में कम पैरामीटर"

private static int recursive(LinkedList<Integer> list) { 
    if (list.size() == 1){ 
     return list.removeFirst(); 
    } 
    return Math.max(list.removeFirst(),recursive(list)); 
    } 
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); 
    } 
} 
+1

स्टैक ओवरफ़्लो में आपका स्वागत है! क्या आप यह बताने के लिए कुछ कथाएं जोड़ने पर विचार करेंगे कि यह कोड क्यों काम करता है, और यह सवाल का जवाब क्या बनाता है? प्रश्न पूछने वाले व्यक्ति के लिए यह बहुत उपयोगी होगा, और कोई और जो साथ आता है। –

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; 
    } 
} 
0

निम्नलिखित एक नमूना उनके व्याख्यानों में से एक में मेरी जावा प्रशिक्षक, प्रोफेसर पेन वू, द्वारा दिए गए कोड है: यहाँ तरीकों स्रोत कोड यदि आप इसे उपयोग करने में रुचि हो रहा है। आशा करता हूँ की ये काम करेगा।

 
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]));
}
}
+0

एसओ में आपका स्वागत है! कृपया इस प्रश्न का उत्तर देने के तरीके के बारे में विस्तृत स्पष्टीकरण शामिल करने के लिए अपने प्रश्न को संपादित करने पर विचार करें। इसके अतिरिक्त, आप एक सामान्य सौजन्य के रूप में, एक प्रोफेसर कोड या उसके नाम से जुड़े नाम को पोस्ट करने से पहले अनुमति प्राप्त करना चाह सकते हैं। – filoxo

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)); 
    } 
} 
संबंधित मुद्दे