पुनरावृत्ति एल्गोरिथ्म की दक्षता कैसे बढ़ाएं?

Aug 22 2020

प्रश्न है:

एक गैर-नकारात्मक int n को देखते हुए, पुनरावर्ती (कोई छोरों) की गणना 8 के अंकों की संख्या को एक अंक के रूप में करें, सिवाय इसके कि एक 8 एक और 8 के साथ तुरंत अपने बाएं गिना जाता है, इसलिए 8818 पैदावार 4. ध्यान दें कि मॉड (%) 10 के द्वारा सबसे सही अंक (126% 10 6 है), जबकि 10 से विभाजित (/) सही अंक को हटाता है (126/10 है 12)।

count8 (8) → 1 count8 (818) → 2 count8 (8818) → 4

मेरा समाधान कुछ इस तरह से देखा:

public int count8(int n) {
  if(n == 0)  return 0;
  
  int faith = count8(n/10);
  int c = 0;
  if(n%10 == 8){
    n /= 10;
    if(n%10 == 8){
      c++;
    }
    c++;
  }
  return c + faith;
}

क्या कोई तरीका है अगर मैं कई स्थितियों को हटा सकता हूं और इस क्लीनर को और अधिक कुशल बना सकता हूं?

जवाब

4 Bobby Aug 23 2020 at 06:53

चर नाम। अपने चरों को नाम दें कि वे क्या करते हैं, कोई अपवाद नहीं।


एक विचार के रूप में, ध्यान दें कि आप जावा में पूर्णांक विभाजन कैसे काम करते हैं, इस पर निर्भर हैं।


यह कहते हुए कि, आप स्पष्ट होकर कोड में सुधार कर सकते हैं।

// As I've said, always name your variables and functions after
// what they are doing. Don't be afraid to use longer names,
// longer names which tell you what the class does are a good
// thing, even if they sound "funny".
public int countEights(int value) {
    // Early exit conditions are a good thing.
    if(value == 0) {
        return 0;
    }
    
    // We could also skip the declaration and instead return
    // the right count together with the function call. From
    // the viewpoint of the JVM it doesn't make a difference,
    // but here in the code it means that we have the logic
    // for stripping the last digit only once.
    int countedEights = 0;
    
    // We are testing explicitly for the mentioned "double eights",
    // this has the upside that the intent is clearly visible
    // when reading the code.
    if ((value % 100) == 88) {
        countedEights = 2;
    } else if ((value % 10) == 8) {
        countedEights = 1;
    }
    
    // And finally we call the function again in the return
    // statement, as it is easier to follow the recursion when
    // it is being called at the end of the function.
    return countedEights + countEights(value / 10);
}

जैसा कि आप देख सकते हैं, हम ifअपने इरादे के बारे में स्पष्ट होने से नेस्टेड से पूरी तरह से छुटकारा पा सकते हैं ।

2 chromaticc Aug 22 2020 at 15:22

पुनरावृत्ति से निपटने के दौरान, यह ध्यान रखना महत्वपूर्ण है कि आपके आधार और पुनरावर्ती मामले क्या हैं और वहां से जाएं। ये विभिन्न मामले अनिवार्य रूप से आपके कार्य की संरचना बन जाएंगे।

आप अपनी समस्या के लिए पहले ही विभिन्न मामलों का पता लगा चुके हैं:

  1. अगर n == 0
  2. यदि 8 अंक वाले स्थान पर है ( n % 10 == 8)
  3. यदि 8 अंक वाले स्थान पर नहीं है ( n % 10 != 8)

यदि n == 0, तो हम सिर्फ 0 लौटाते हैं।

यदि n % 10 == 8, तो हमें पता है कि हमारे पास एक 8 है, लेकिन हमें अपने इनपुट पैरामीटर के रूप में count8फिर से कॉल करने की आवश्यकता n / 10है count8जब हम इस कॉल से बाहर लौटते हैं, तो हम इसे वापस करने से पहले हमारे परिणाम में 1 जोड़ते हैं क्योंकि हमने पहले ही एक 8 पाया था। अब count8कॉल के परिणाम में 1 (8 जो हमने पहले ही पाया था) जोड़ें ।

  • इस मामले में, आप यह जांचना चाहेंगे कि अगला अंक 8 है या नहीं। यदि यह है, तो आप लौटने से पहले अपने परिणाम को 1 से बढ़ाना चाहेंगे। आप पहले पुनरावर्ती कॉल से पहले या बाद में ऐसा कर सकते हैं। n / 10बैक-टू-बैक 8 के "हटाए" जाने के बाद बस पास सुनिश्चित करें ।

यदि n % 10 != 8, तो हम बस हमारे इनपुट पैरामीटर के रूप में कॉल count8करते हैं n / 10और इस कॉल से परिणाम वापस करते हैं।

उम्मीद है कि यह एक तस्वीर को साफ करता है कि आप अपने फ़ंक्शन को कैसे स्पष्ट रूप से तैयार कर सकते हैं।