2009-06-21 9 views
19

मैं Project Euler पर समस्या 9 को हल कर रहा हूं। मेरे समाधान में मैं लूप के लिए दो में से बाहर निकलने के लिए "गोटो" कथन का उपयोग करता हूं। समस्या यह है:गोटो को दो लूपों से बाहर निकलने का एक वैध तरीका उपयोग कर रहा है?

एक पाइथागोरस त्रिक तीन प्राकृतिक संख्या, का एक सेट है एबीसी, जो,

एक^2 + b^2 = ग^2

उदाहरण के लिए के लिए, 3^2 + 4^2 = 9 + 16 = 25 = 52.

बिल्कुल एक पायथागोरियन ट्रिपलेट मौजूद है जिसके लिए एक + बी + सी = 1000. उत्पाद एबीसी खोजें।

मेरे समाधान C++ है:

int a,b,c; 
const int sum = 1000; 
int result = -1; 
for (a = 1; a<sum; a++){ 
    for (b = 1; b < sum; b++){ 
      c = sum-a-b; 
      if (a*a+b*b == c*c){ 
       result = a*b*c; 
       goto found; 
      } 
    } 
} 
found: 
std::cout << "a:" << a << std::endl; 
std::cout << "b:" << b << std::endl; 
std::cout << "c:" << c << std::endl; 
std::cout <<"Result:" << result << std::endl; 

के बाद से "गोटो" बयान C++ प्रोग्रामर के बीच बहुत लोकप्रिय नहीं हैं, मैं इस "गोटो" का एक उचित उपयोग पर विचार किया जा सकता है अगर, जानना चाहते हैं । या यदि समस्या के लिए एक बेहतर समाधान है जिसे "गोटो" की आवश्यकता नहीं है। इसके द्वारा मेरा मतलब यह नहीं है कि एक समाधान जो "गेटो" से बचाता है, लेकिन जो एल्गोरिदम को सुधारने के तरीके में "गोटो" से बचाता है।

+13

मैं उन 8-स्पेस टैब से प्यार करता हूं जिनका आप उपयोग कर रहे हैं .... बहुत सेक्सी। –

+0

धन्यवाद, मुझे भी उन्हें पसंद है :-) – Lucas

+10

मध्य में 16-स्पेस टैब के साथ ... –

उत्तर

45

return एक "संरचित" goto है जो कई प्रोग्रामर अधिक स्वीकार्य पाते हैं! तो:

static int findit(int sum, int* pa, int* pb, int* pc) 
{ 
    for (int a = 1; a<sum; a++) { 
     for (int b = 1; b < sum; b++) { 
      int c = sum-a-b; 
      if (a*a+b*b == c*c) { 
       *pa = a; *pb = b; *pc = c; 
       return a*b*c; 
     } 
    } 
    return -1;  
} 

int main() { 
    int a, b, c; 
    const int sum = 1000; 
    int result = findit(sum, &a, &b, &c); 
    if (result == -1) { 
     std::cout << "No result!" << std::endl; 
     return 1; 
    } 
    std::cout << "a:" << a << std::endl; 
    std::cout << "b:" << b << std::endl; 
    std::cout << "c:" << c << std::endl; 
    std::cout <<"Result:" << result << std::endl; 
    return 0; 
} 
+21

+1: यदि यह गोटो पर विचार करने के लिए पर्याप्त जटिल है, तो यह एक फ़ंक्शन में समाहित करने और गेटो से बचने के लिए पर्याप्त जटिल है। –

+2

हाँ। लूप को जटिल मत करो। बस निकल जाओ। सही समाधान लेकिन आप संदर्भ से ए, बी, सी पास कर सकते हैं। तो आपको पॉइंटर्स के साथ गड़बड़ करने की आवश्यकता नहीं है। –

+0

धन्यवाद, यह एक अच्छा समाधान है। यह कोड को कम पठनीय नहीं बनाता है। – Lucas

4

मैं बेहतर विकल्प के बारे में नहीं सोच सकता। लेकिन goto का उपयोग कर एक विकल्प नहीं पहले for -loop संशोधित होगा:

for (a = 1; a<sum && result == -1; a++){ 

फिर break दूसरा for -loop से बाहर। यह मान लेगा कि परिणाम -1 दूसरे for के बाद कभी भी break द्वारा तोड़ दिया गया है।

+2

मैं इसे बेहतर के रूप में नहीं देखता हूं। आप कोड को पढ़ने के लिए कठिन बना रहे हैं क्योंकि आप परीक्षण में और अधिक शर्तें जोड़ रहे हैं। –

+0

और आप सही हैं। जैसा कि मैंने कहा, मैं एक बेहतर विकल्प के बारे में नहीं सोच सका, मैंने कोड को काफी बदलाव किए बिना गोटो लूप से बचने का एक तरीका दिखाया। – Blixt

+0

मैं यह जोड़ना चाहता हूं कि एलेक्स मार्टेलि का समाधान निश्चित रूप से बेहतर है। एक समारोह में इसे Encapsulating शायद इस मामले में सबसे अच्छा समाधान है। – Blixt

4

आप शीर्ष पर एक bool found = false घोषित कर सकता है और उसके बाद अपने पाश के लिए सशर्त को && !found जोड़ने और फिर (a < sum और b < sum के बाद) को सही पर पाया सेट जहां अपने वर्तमान गोटो है। फिर अपने आउटपुट को वास्तविक होने पर सशर्त बनाएं।

3

मुझे यह "संबंधित" साइडबार पर मिला। समग्र रूप से एक दिलचस्प धागा, लेकिन विशेष रूप से, this मेरे प्रश्न का उत्तर है।

6

2 loops से बाहर तोड़ने के बारे में this question देखें। गोटो का उपयोग करने के मुकाबले बहुत अच्छे उत्तर दिए गए हैं।

प्रदान किया गया सबसे अच्छा उत्तर आपके दूसरे लूप को फ़ंक्शन में रखना है, और उस फ़ंक्शन को अपने पहले लूप के अंदर से कॉल करना है।

कोड mquander की प्रतिक्रिया

public bool CheckWhatever(int whateverIndex) 
{ 
    for(int j = 0; j < height; j++) 
    { 
     if(whatever[whateverIndex][j]) return false; 
    } 

    return true; 
} 

public void DoubleLoop() 
{ 
    for(int i = 0; i < width; i++) 
    { 
     if(!CheckWhatever(i)) break; 
    } 
} 

से नकल हालांकि मैं कैसा महसूस करते हैं कि इस मामले में एक गोटो का उपयोग कर काफी के रूप में बिल्ली के बच्चे की मौत हो गई के रूप में बुरा नहीं है। लेकिन यह करीब है।

+10

हम सभी को मस्तिष्क धोया गया है? :) इस कोड की परिणामी संरचना गोटो का उपयोग करने से अधिक "जटिल" है (डबल लूप में अतिरिक्त 'if-statement' के कारण)। कोड आउट को विभाजित करने से ऑप्टिमाइज़ेशन के सेट को भी कम किया जा सकता है जो एक कंपाइलर कर सकता है - उदाहरण के लिए एक वैरिएबल जो स्थानीय रूप से "चेकवॉउथ" के लिए स्थानीय है, को संभावित रूप से संलग्न लूप के बाहर अनुकूलित किया जा सकता था। –

+0

गोटो संस्करण बहुत आसान है। – jv110

18

मेरी राय में यह इस तरह एक स्थिति में goto उपयोग करने के लिए ठीक है।

Btw, गोटो के खिलाफ कृपालु उपदेश आमतौर पर लोग सिर्फ तोता जो वे दूसरों का क्या कहना या कहीं पढ़ा सुना से आता है ..

+1

जावा ने loops नाम दिया है, जो इस – Casebash

+3

@Casebash के लिए काफी समान हैं: निश्चित रूप से। लेकिन यह उत्तर या प्रश्न से कैसे संबंधित है? –

1
int a,b,c,sum = 1000; 
for (a = 1; a<sum; ++a) 
for (b = 1; b<sum; ++b){ 
    c = sum-a-b; 
    if (a*a+b*b == c*c) sum = -a*b*c; 
} 
printf("a: %d\n",a-1); 
printf("b: %d\n",b-1); 
printf("c: %d\n",c); 
printf("Result: %d\n",-sum); 

भी अनुकूलित परिणाम बाहर ..: पी

वैसे भी मैं प्यार gotos!

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