2011-10-04 29 views
6

मैं लंबाई के योग जिससेयोग करने के लिए

syra(1) = 1

syra(2) = n + syra(n/2) if n%2==0

syra(3) = n + (n*3) + 1

जैसे गणना करने के लिए एक कोड लिखा है एक कारगर तरीका बनाएँ।

  • syra (1) उत्पन्न होगा 1
  • syra (2) उत्पन्न 2 1
  • syra (3) उत्पन्न होगा 3 10 5 16 8 4 2 1
  • लंबाई (3) होगा सभी syra (1), syra (2), syra का योग (3) जो है 11.

कोड यह रहा:

public static int lengths(int n) throws IllegalArgumentException{ 
    int syra = n; 
    int count = 0;  
    int sum = 0; 
    if (syra < 1){ 
    throw new IllegalArgumentException("Value must be greater than 0"); 
    }else{ 
    for (int i=1; i<=syra; i++){ 
     count = i; 
     sum++; 
     while (count > 1){ 
     if ((count % 2) == 0){ 
      count = count/2; 
      sum++; 
     }else{ 
      count = (count * 3) + 1; 
      sum++; 
     } 
     } 
    } 
    } 
    return sum; 
} 

प्रश्न यह है कि, यदि मैं बड़े मूल्य के साथ लंबाई को विस्फोट करता हूं जैसे कि 700000, इसमें बहुत लंबा समय लगेगा और उन सिरा (10), सिरा (5) के लिए दोहराना कदम होगा ... जो पहले ही सिरा (3) में दिखाई देता है।

मैं ओवरलैप अनुक्रमों के कुछ अस्थायी (सरणी) को स्टोर करने के लिए कोड को कैसे ठीक कर सकता हूं?

ठीक है, जानकारी के अनुसार, यहां सरणी के साथ मेरा एक और संशोधित कोड है, यह बाध्य त्रुटि से सरणी अनुक्रमणिका क्यों उत्पन्न करता है?

public class SyraLengths{ 

public static void main (String[]args){ 
    lengths(3); 
} 

public static int lengths(int n) throws IllegalArgumentException{ 
    int syra = n; 
    int count = 0; 
    int sum = 0; 
    int [] array = new int [syra+1]; 
    array[0] = 0; 
    if (syra < 1){ 
     throw new IllegalArgumentException("Value must be greater than 0"); 
     }else{ 


       for (int i=1; i<=syra; i++){ 
        count = i; 
        sum++; 

        while (count > 1){ 

         if(array[count] !=0){sum = sum + array[count];} 

         else if ((count % 2) == 0){ 
          count = count/2; 
          array[count]=sum; 
          sum++; 
         }else{ 
          count = (count * 3) + 1; 
          array[count]=sum; 
          sum++; 

          } 
         } 
       } 
      }return sum; 
} 

}

+2

'syra (2) = n + syra (n/2) 'में' n' क्या है? –

+0

@ हेमल - कोड पढ़ें। –

+0

धन्यवाद, @ एडी। गणितज्ञ नहीं होने के नाते मुझे नहीं पता था कि सिरा समारोह क्या था और सोचा था कि मैं spec के खिलाफ कोड की जांच करूंगा। –

उत्तर

3

परिणाम है कि आप पहले से ही गणना की है स्टोर करने के लिए एक HashMap<Integer, Integer> का उपयोग करें, और उन्हें recompute करने प्रयास करने से पहले वहाँ मूल्यों को देखने। इस तकनीक को memoization के रूप में जाना जाता है।

+2

इसे 'हैश मैप <इंटीजर, इंटीजर>' होना चाहिए। –

+0

@ कुबलई खान: ठीक किया गया; धन्यवाद। (मैं ज्यादातर सी # में कोडिंग कर रहा हूं, इसलिए मैं इसके बारे में भूल गया ...) –

+3

एक साधारण int सरणी बहुत तेज, आसान, छोटी होगी। –

1

वह तकनीक जिसे आप करना चाहते हैं उसे memoization कहा जाता है।

आपको कुछ डेटा संरचनाओं में उन छोटी कॉलों के आउटपुट को स्टोर करने की आवश्यकता होगी और फिर इसे और अधिक गणना करने के बजाय इसका उपयोग करना होगा।

accessOrder=True और overrriden removeEldestEntry() विधि के साथ LinkedHashMap विशेष निर्माता का उपयोग करने पर विचार करें। Javadoc LinkedHashMap पढ़ें। यह अच्छी तरह से वर्णित है।

ऐसा करने से, आप आसानी से केवल उन सबसे अधिक उपयोग किए गए मानों को रख सकते हैं और अपना कैश उचित छोटा रख सकते हैं (यानी अधिकतर 1000 तत्वों का उपयोग किया जाता है)।

संबंधित मुद्दे