तीन संख्याओं की तुलना करने का सरल और साफ तरीका


11

मुझे कुछ कोड मिले हैं जिनमें ifउस काम का एक क्रम है , लेकिन सिर्फ गड़बड़ महसूस करते हैं। मूल रूप से, मैं तीन पूर्णांकों में से सबसे बड़ा चुनना चाहता हूं और यह कहने के लिए एक स्थिति ध्वज सेट करना चाहता हूं जिसे चुना गया था। मेरा वर्तमान कोड इस तरह दिखता है:

a = countAs();
b = countBs();
c = countCs();

if (a > b && a > c)
    status = MOSTLY_A;
else if (b > a && b > c)
    status = MOSTLY_B;
else if (c > a && c > b)
    status = MOSTLY_C;
else
    status = DONT_KNOW;

यह पैटर्न कुछ बार होता है, और लंबे चर नामों के साथ यह थोड़ा मुश्किल होता है कि नेत्रहीन पुष्टि करें कि प्रत्येक ifसही है। मुझे लगता है कि ऐसा करने का एक बेहतर और स्पष्ट तरीका हो सकता है; क्या कोई कुछ भी सुझा सकता है?


कुछ संभावित डुप्लिकेट हैं, लेकिन वे इस प्रश्न के साथ बिल्कुल संरेखित नहीं करते हैं।

सुझाए गए डुप्लिकेट में: कई स्थितियों की जाँच करने के लिए दृष्टिकोण? सभी सुझाए गए समाधान मूल कोड के समान ही भद्दे लगते हैं, इसलिए वे एक बेहतर समाधान प्रदान नहीं करते हैं।

और यह पोस्ट यदि आप (यदि और) केवल घोंसले के स्तर और विषमता से निपटने के लिए सुरुचिपूर्ण तरीके से पोस्ट करते हैं , जो यहां समस्या नहीं है।


3
मेरे लिए एकमात्र समस्या कोड पुनरावृत्ति है। यहाँ आपके पास पढ़ने के लिए बहुत स्पष्ट है, ऐसा क्यों? बस इसे एक फंक्शन में तोड़ें जो कि, b, c और रिटर्न स्टेटस में लेता है। यदि आप इसे बेहतर महसूस करते हैं, तो इस पर एक "इनलाइन" छोड़ दें। कोई मैक्रोज़, कोई जटिलता नहीं, बस अच्छा पुराना फ़ंक्शन निष्कर्षण। यदि मुझे बाद में इसके साथ काम करने की आवश्यकता हुई तो मैं आपके स्पष्ट कोड के लिए धन्यवाद दूंगा।
जे त्राना



ध्यान दें कि आपके #defines का नाम खराब है। A = 40, b = 30, c = 30 पर विचार करें। परिणाम MOSTLY_A है। लेकिन ज्यादातर चीजें वास्तव में ए नहीं हैं, लेकिन बी या सी। आप MORE_A (हालांकि अभी भी अस्पष्ट है - बी से अधिक ए और सी से अधिक ए, या बी और सी से अधिक ए संयुक्त?), या ए थरजेस्ट की कोशिश करना चाहते हैं? MAX_IS_A, ...? (जो प्रश्न के उत्तर के रूप में अधिकतम (ए, अधिकतम (बी, सी)) भी सुझाता है।
tony

जवाबों:


12

तर्क को फैक्टराइज़ करें, जल्दी लौटें

जैसा कि टिप्पणियों में सुझाया गया है, यह किसी फ़ंक्शन में बस अपने तर्क को लपेटने और returnचीजों को सरल बनाने के लिए जल्दी से बाहर निकलने के लिए पर्याप्त होगा । इसके अलावा, आप किसी अन्य फ़ंक्शन के लिए परीक्षणों को प्रत्यायोजित करके बहुत अधिक कार्यकुशलता का कारक बन सकते हैं। अधिक संक्षेप में:

bool mostly(max,u,v) {
   return max > u && max > v;
}

status_t strictly_max_3(a,b,c)
{
  if mostly(a,b,c) return MOSTLY_A;
  if mostly(b,a,c) return MOSTLY_B;
  if mostly(c,a,b) return MOSTLY_C;
  return DONT_KNOW;
}

यह मेरे पिछले प्रयास से कम है:

status_t index_of_max_3(a,b,c)
{
  if (a > b) {
    if (a == c)
      return DONT_KNOW;
    if (a > c)
      return MOSTLY_A;
    else
      return MOSTLY_C;
  } else {
    if (a == b)
      return DONT_KNOW;
    if (b > c)
      return MOSTLY_B;
    else
      return MOSTLY_C;
  }
}

ऊपर एक और अधिक क्रिया है, लेकिन IMHO को पढ़ना आसान है और कई बार तुलना को फिर से नहीं करता है।

दृश्य की पुष्टि

में आपका जवाब आप कहते हैं:

मेरा मुद्दा ज्यादातर दृश्य पुष्टि था कि सभी तुलनाओं में समान चर का उपयोग किया गया था

... यह भी, आपके प्रश्न में, आप कहते हैं:

यह पैटर्न कुछ बार होता है, और लंबे चर नामों के साथ यह देखना थोड़ा मुश्किल हो जाता है कि प्रत्येक सही है या नहीं।

मुझे समझ में नहीं आ रहा है कि आप क्या हासिल करने की कोशिश कर रहे हैं: क्या आप हर जगह उस पैटर्न को कॉपी-पेस्ट करना चाहते हैं जिसकी आपको ज़रूरत है? ऊपर के एक फ़ंक्शन के साथ, आप एक बार पैटर्न कैप्चर करते हैं, और आप एक बार उन सभी के लिए जांच करते हैं जो सभी तुलनाओं का उपयोग करते हैं a, bऔर cआवश्यकतानुसार। फिर, जब आप फ़ंक्शन को कॉल करते हैं, तो आपको अब और चिंता करने की आवश्यकता नहीं है। बेशक, शायद आपकी समस्या व्यवहार में आपके द्वारा वर्णित की तुलना में थोड़ी अधिक जटिल है: यदि हां, तो कृपया यदि संभव हो तो कुछ विवरण जोड़ें।


1
मुझे DONT_KNOW के बारे में आपकी टिप्पणी समझ में नहीं आती , क्या होगा यदि c सबसे छोटा है और a और b समान हैं? एल्गोरिथ्म वापस आ जाएगा कि बी सबसे बड़ा है, जबकि एक बी के समान है।
पीटर बी

@PieterB मैं यह सोचते हैं कि यह नहीं बात करता है, तो हम या तो लौट आए हैं wronlgy था MOSTLY_Aया MOSTLY_Cमामले में a == cऔर a > b। यह तय है। धन्यवाद।
coredump

@ डॉकब्रोन ग्रांटेड, अधिकांश लाभ शुरुआती निकास व्यवहार से आते हैं।
coredump

1
+1, अब यह वास्तव में ओपी मूल कोड पर एक सुधार है।
डॉक ब्राउन

9

टी एल: डॉ; आपका कोड पहले से ही सही और "साफ" है।

मैंने देखा कि बहुत से लोग जवाब के आसपास इंतजार कर रहे हैं लेकिन हर कोई पेड़ों के माध्यम से जंगल को याद कर रहा है। आइए इस प्रश्न को पूरी तरह से समझने के लिए पूर्ण कंप्यूटर विज्ञान और गणितीय विश्लेषण करें।

सबसे पहले, हम ध्यान दें कि हमारे पास 3 चर हैं, जिनमें से प्रत्येक में 3 राज्य हैं: <, =, या>। क्रमपरिवर्तन की कुल संख्या 3 ^ 3 = 27 राज्य है, जिसे मैं प्रत्येक राज्य के लिए P # नाम से निरूपित एक अद्वितीय संख्या बताऊंगा। यह P # संख्या एक भाज्य संख्या प्रणाली है

हमारे पास सभी क्रमपरिवर्तन की गणना:

a ? b | a ? c | b ? c |P#| State
------+-------+-------+--+------------
a < b | a < c | b < c | 0| C
a = b | a < c | b < c | 1| C
a > b | a < c | b < c | 2| C
a < b | a = c | b < c | 3| impossible a<b b<a
a = b | a = c | b < c | 4| impossible a<a
a > b | a = c | b < c | 5| A=C > B
a < b | a > c | b < c | 6| impossible a<c a>c
a = b | a > c | b < c | 7| impossible a<c a>c
a > b | a > c | b < c | 8| A
a < b | a < c | b = c | 9| B=C > A
a = b | a < c | b = c |10| impossible a<a
a > b | a < c | b = c |11| impossible a<c a>c
a < b | a = c | b = c |12| impossible a<a
a = b | a = c | b = c |13| A=B=C
a > b | a = c | b = c |14| impossible a>a
a < b | a > c | b = c |15| impossible a<c a>c
a = b | a > c | b = c |16| impossible a>a
a > b | a > c | b = c |17| A
a < b | a < c | b > c |18| B
a = b | a < c | b > c |19| impossible b<c b>c
a > b | a < c | b > c |20| impossible a<c a>c
a < b | a = c | b > c |21| B
a = b | a = c | b > c |22| impossible a>a
a > b | a = c | b > c |23| impossible c>b b>c
a < b | a > c | b > c |24| B
a = b | a > c | b > c |25| A=B > C
a > b | a > c | b > c |26| A

निरीक्षण से हम देखते हैं कि हमारे पास है:

  • 3 राज्य जहां A अधिकतम है,
  • 3 राज्य जहां B अधिकतम है,
  • 3 राज्य जहां C अधिकतम है, और
  • 4 राज्य जहां या तो ए = बी, या बी = सी।

आइए एक प्रोग्राम लिखें (फुटनोट देखें) ए, बी, और सी के लिए इन सभी क्रमपरिवर्तन की गणना करें पी द्वारा # स्थिर छँटाई:

a ?? b | a ?? c | b ?? c |P#| State
1 <  2 | 1 <  3 | 2 <  3 | 0| C
1 == 1 | 1 <  2 | 1 <  2 | 1| C
1 == 1 | 1 <  3 | 1 <  3 | 1| C
2 == 2 | 2 <  3 | 2 <  3 | 1| C
2  > 1 | 2 <  3 | 1 <  3 | 2| C
2  > 1 | 2 == 2 | 1 <  2 | 5| ??
3  > 1 | 3 == 3 | 1 <  3 | 5| ??
3  > 2 | 3 == 3 | 2 <  3 | 5| ??
3  > 1 | 3  > 2 | 1 <  2 | 8| A
1 <  2 | 1 <  2 | 2 == 2 | 9| ??
1 <  3 | 1 <  3 | 3 == 3 | 9| ??
2 <  3 | 2 <  3 | 3 == 3 | 9| ??
1 == 1 | 1 == 1 | 1 == 1 |13| ??
2 == 2 | 2 == 2 | 2 == 2 |13| ??
3 == 3 | 3 == 3 | 3 == 3 |13| ??
2  > 1 | 2  > 1 | 1 == 1 |17| A
3  > 1 | 3  > 1 | 1 == 1 |17| A
3  > 2 | 3  > 2 | 2 == 2 |17| A
1 <  3 | 1 <  2 | 3  > 2 |18| B
1 <  2 | 1 == 1 | 2  > 1 |21| B
1 <  3 | 1 == 1 | 3  > 1 |21| B
2 <  3 | 2 == 2 | 3  > 2 |21| B
2 <  3 | 2  > 1 | 3  > 1 |24| B
2 == 2 | 2  > 1 | 2  > 1 |25| ??
3 == 3 | 3  > 1 | 3  > 1 |25| ??
3 == 3 | 3  > 2 | 3  > 2 |25| ??
3  > 2 | 3  > 1 | 2  > 1 |26| A

मामले में आप सोच रहे थे कि मैं कैसे जानता था कि कौन से P # राज्य असंभव थे, अब आप जानते हैं। :-)

आदेश का निर्धारण करने के लिए तुलना की न्यूनतम संख्या है:

लॉग 2 (27) = लॉग (27) / लॉग (2) = ~ 4.75 = 5 तुलना

कोरडंप ने सही 5 न्यूनतम संख्या की तुलना की। मैं उनके कोड को इस रूप में प्रारूपित करूंगा:

status_t index_of_max_3(a,b,c)
{
    if (a > b) {
        if (a == c) return DONT_KNOW; // max a or c
        if (a >  c) return MOSTLY_A ;
        else        return MOSTLY_C ;
    } else {
        if (a == b) return DONT_KNOW; // max a or b
        if (b >  c) return MOSTLY_B ;
        else        return MOSTLY_C ;
    }
}

आपकी समस्या के लिए हम समानता के लिए परीक्षण के बारे में परवाह नहीं करते हैं ताकि हम 2 परीक्षणों को छोड़ सकें।

इससे कोई फर्क नहीं पड़ता कि कोड कितना साफ / खराब है अगर उसे गलत उत्तर मिल जाता है तो यह एक अच्छा संकेत है कि आप सभी मामलों को सही तरीके से संभाल रहे हैं!

अगला, जैसा कि सादगी के लिए होता है, लोग उत्तर को "सुधार" करने की कोशिश करते रहते हैं, जहां उन्हें लगता है कि सुधार का मतलब तुलनाओं की संख्या को "अनुकूलित" करना है, लेकिन यह कड़ाई से नहीं है जो आप पूछ रहे हैं। आपने हर किसी को भ्रमित किया जहां आपने पूछा "मुझे लगता है कि एक बेहतर हो सकता है" लेकिन यह परिभाषित नहीं किया कि 'बेहतर' का क्या मतलब है। तुलना कम? कम कोड? इष्टतम तुलना?

अब चूंकि आप कोड की पठनीयता (शुद्धता के बारे में) के बारे में पूछ रहे हैं, मैं केवल पठनीयता के लिए आपके कोड में एक बदलाव करूंगा: दूसरों के साथ पहला परीक्षण संरेखित करें।

        if      (a > b && a > c)
            status = MOSTLY_A;
        else if (b > a && b > c)
            status = MOSTLY_B;
        else if (c > a && c > b)
            status = MOSTLY_C;
        else
            status = DONT_KNOW; // a=b or b=c, we don't care

व्यक्तिगत रूप से मैं इसे निम्नलिखित तरीके से लिखूंगा लेकिन यह आपके कोडिंग मानकों के लिए बहुत ही अपरंपरागत हो सकता है:

        if      (a > b && a > c) status = MOSTLY_A ;
        else if (b > a && b > c) status = MOSTLY_B ;
        else if (c > a && c > b) status = MOSTLY_C ;
        else /*  a==b  || b ==c*/status = DONT_KNOW; // a=b or b=c, we don't care

फुटनोट: यहाँ क्रमचय उत्पन्न करने के लिए C ++ कोड है:

#include <stdio.h>

char txt[]  = "< == > ";
enum cmp      { LESS, EQUAL, GREATER };
int  val[3] = { 1, 2, 3 };

enum state    { DONT_KNOW, MOSTLY_A, MOSTLY_B, MOSTLY_C };
char descr[]= "??A B C ";

cmp Compare( int x, int y ) {
    if( x < y ) return LESS;
    if( x > y ) return GREATER;
    /*  x==y */ return EQUAL;
}

int main() {
    int i, j, k;
    int a, b, c;

    printf( "a ?? b | a ?? c | b ?? c |P#| State\n" );
    for( i = 0; i < 3; i++ ) {
        a = val[ i ];
        for( j = 0; j < 3; j++ ) {
            b = val[ j ];
            for( k = 0; k < 3; k++ ) {
                c = val[ k ];

                int cmpAB = Compare( a, b );
                int cmpAC = Compare( a, c );
                int cmpBC = Compare( b, c );
                int n     = (cmpBC * 9) + (cmpAC * 3) + cmpAB; // Reconstruct unique P#

                printf( "%d %c%c %d | %d %c%c %d | %d %c%c %d |%2d| "
                    , a, txt[cmpAB*2+0], txt[cmpAB*2+1], b
                    , a, txt[cmpAC*2+0], txt[cmpAC*2+1], c
                    , b, txt[cmpBC*2+0], txt[cmpBC*2+1], c
                    , n
                );

                int status;
                if      (a > b && a > c) status = MOSTLY_A;
                else if (b > a && b > c) status = MOSTLY_B;
                else if (c > a && c > b) status = MOSTLY_C;
                else /*  a ==b || b== c*/status = DONT_KNOW; // a=b, or b=c

                printf( "%c%c\n", descr[status*2+0], descr[status*2+1] );
            }
        }
    }
    return 0;
}

संपादन: फीडबैक के आधार पर, टीएल: डीआर को शीर्ष पर ले जाया गया, हटाए गए टेबल को हटा दिया, 27 को स्पष्ट किया, कोड को साफ किया, असंभव राज्यों को वर्णित किया।


-1: निर्णय की संख्या को कम करने के लिए सरल कोड पथ और अधिक पठनीय कोड नहीं होगा? आप तर्क स्पष्ट नहीं हैं: पहले, आप कहते हैं कि हर कोई गलत है; फिर, आप एक या दो नहीं बल्कि तीन टेबल लगाते हैं; मुझे उम्मीद थी कि वे परिणाम की गणना करने के लिए एक सरल तरीका का नेतृत्व करेंगे, लेकिन इसके बजाय आपने पुष्टि की कि हर कोई पहले से ही जानता था (ओपी कोड सही काम करता है)। निश्चित रूप से, प्रश्न पठनीयता के बारे में है, लेकिन पठनीयता केवल कोड लेआउट को संशोधित करके प्राप्त नहीं की जाती है (आप अपने परिवर्तनों को मानते हैं कि शायद ही मौजूदा कोड मानक फिट होंगे)। यह पठनीयता के लिए अनुकूलन करते समय तर्क को सरल बनाने के लिए समझ में आता है।
coredump

अधिक रचनात्मक रूप से: मैं आपके उत्तर की संरचना के बारे में कुछ विवरण और सोच को छोड़कर आपके उत्तर को आसान बनाने का सुझाव दूंगा। मैं सराहना करता हूं कि आपने सी ++ कोड को क्रमपरिवर्तन उत्पन्न करने के लिए लिखने और पोस्ट करने के लिए समय लिया था, लेकिन शायद आप मुख्य परिणाम दे सकते हैं और केवल एक तालिका: जैसा कि अब है, ऐसा लगता है कि आपने अपने सभी कामों को जैसे-तैसे पूरा किया। मैं लगभग टीएल को प्राप्त करने में विफल रहा; डीआर बात (आप उस के साथ शुरू कर सकते हैं)। आशा है ये मदद करेगा।
coredump

2
रचनात्मक प्रतिक्रिया के लिए धन्यवाद coredump। मैंने बीच के अनसेंडेड टेबल को हटा दिया है क्योंकि यह आसानी से सत्यापित हो गया है।
माइकल

2
ईसा मसीह! कौन कहता है कि तीन संख्याओं की तुलना लगभग रॉकेट विज्ञान की तरह जटिल है?
मंड्रिल

@ कंप्यूटर वैज्ञानिक के रूप में यह एक समस्या को अच्छी तरह से समझने के लिए हमारा काम है । केवल 3-तरह की तुलना के लिए सभी 27 संभावित क्रमों की गणना करके हम यह सत्यापित कर सकते हैं कि हमारा समाधान सभी मामलों में काम करता है। आखिरी चीज जो हम चाहते हैं कि प्रोग्रामर छिपे हुए कीड़े और बेहिसाब किनारे वाले मामले हैं। वर्बोसिटी वह मूल्य है जो शुद्धता के लिए भुगतान करता है।
माइकल एंजेल 007

5

@msw ने आपको a, b, c, और @Basile के बजाय एक सरणी का उपयोग करने के लिए कहा था कि आपने एक फ़ंक्शन में "अधिकतम" तर्क को प्रतिबिंबित किया है। इन दो विचारों के संयोजन से होता है

val[0] = countAs();    // in the real code, one should probably define 
val[1] = countBs();    // some enum for the indexes 0,1,2 here
val[2] = countCs();

 int result[]={DONT_KNOW, MOSTLY_A, MOSTLY_B, MOSTLY_C};

फिर एक फ़ंक्शन प्रदान करें जो एक मनमाना सरणी के अधिकतम सूचकांक की गणना करता है:

// returns the index of the strict maximum, and -1 when the maximum is not strict
int FindStrictMaxIndex(int *values,int arraysize)
{
    int maxVal=INT_MIN;
    int maxIndex=-1;
    for(int i=0;i<arraysize;++i)
    {
       if(values[i]>maxVal)
       {
         maxVal=values[i];
         maxIndex=i;
       }
       else if (values[i]==maxVal)
       {
         maxIndex=-1;
       }
    }
    return maxIndex;
}

और इसे कॉल करें

 return result[FindStrictMaxIndex(val,3)+1];

LOC की कुल संख्या मूल रूप से बढ़ी हुई प्रतीत होती है, लेकिन अब आपके पास पुन: प्रयोज्य फ़ंक्शन में मुख्य तर्क है, और यदि आप फ़ंक्शन को कई बार पुन: उपयोग कर सकते हैं, तो यह भुगतान करना शुरू कर देता है। इसके अलावा, FindStrictMaxIndexफ़ंक्शन आपकी "व्यावसायिक आवश्यकताओं" के साथ किसी भी अधिक (चिंताओं को अलग करना) के बीच में नहीं है, इस प्रकार आपको बाद में इसे संशोधित करने का जोखिम आपके मूल संस्करण (खुले-बंद सिद्धांत) की तुलना में बहुत कम होगा। उदाहरण के लिए, उस फ़ंक्शन को तब भी नहीं बदलना होगा, जब तर्कों की संख्या बदल जाती है, या MOSTLY_ABC की तुलना में अन्य रिटर्न मानों का उपयोग करने की आवश्यकता होती है, या आप a, b, c की तुलना में अन्य चर संसाधित कर रहे हैं। इसके अलावा, 3 भिन्न मानों a, b, c के बजाय एक सरणी का उपयोग अन्य स्थानों में भी आपके कोड को सरल बना सकता है।

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


मुझे वह पसंद है - हिम्मत FindStrictMaxIndex()बहुत साफ नहीं हो सकती है, लेकिन देखने वाले के दृष्टिकोण से यह स्पष्ट रूप से स्पष्ट है कि क्या हासिल करने की कोशिश की जा रही है।
केन YN

या दो सरणियों को रखने के बजाय, कुंजी-मूल्य-युग्मों का एक सरणी रखें: {MOSTLY_A, countAs ()}, मूल्य द्वारा आदेश दिया गया पहला तत्व लें और कुंजी को पढ़ें।
जूलिया हेवर्ड

@ जूलियाहवर्ड: इस तरह के समाधान का सुझाव नहीं देने का मुख्य कारण था सवाल का "सी" टैग - सी में, किसी को कुंजी-मूल्य वाले जोड़े से निपटने के लिए कुछ और बॉयलरप्लेट कोड की आवश्यकता होगी, और केवीपी के संदर्भ में टाइप किए गए फ़ंक्शन का निर्माण करना होगा। शायद एक सरल intटाइप किए गए फ़ंक्शन की तुलना में विभिन्न संदर्भों में पुन: प्रयोज्य नहीं होगा । लेकिन मैं आपकी टिप्पणी से सहमत हूं अगर कोई अजगर या पर्ल जैसी किसी अन्य भाषा का उपयोग करता है।
डॉक ब्राउन

1
@ gnasher729: यह इस बात पर निर्भर करता है कि मूल कोड में कितने "डुप्लिकेट" हैं, वे वास्तव में कितने समान हैं और कितनी बार FindStrictMaxIndexफ़ंक्शन का पुन: उपयोग किया जा सकता है। एक या दो बार पुन: उपयोग के लिए, यह भुगतान नहीं करेगा, ज़ाहिर है, लेकिन यह वही है जो मैंने अपने जवाब में पहले से ही लिखा था। भविष्य के बदलावों के बारे में ऊपर बताए गए अन्य फायदों पर भी ध्यान दें।
डॉक ब्राउन

1
... और ध्यान दें कि मूल 8 लाइनों को return result[FindStrictMaxIndex(val,3)]; कोड में उस बिंदु पर एक साधारण एक-लाइनर द्वारा प्रतिस्थापित किया जा सकता है जहां मूल 8 लाइनें रखी गई थीं । अन्य भागों, विशेष रूप से FindStrictMaxIndexखुद को "व्यापार तर्क" से पूरी तरह से अलग किया जाता है, जो उन्हें बदलती व्यावसायिक आवश्यकताओं के फोकस से बाहर ले जाता है।
डॉक ब्राउन

-1

आपको संभवतः एक मैक्रो या एक फ़ंक्शन का उपयोग करना चाहिए MAX जो अधिकतम दो नंबर दे।

तो आप बस चाहते हैं:

 status = MAX(a,MAX(b,c));

आपने परिभाषित किया होगा

 #define MAX(X,Y) (((X)>(Y))?(X):(Y))

लेकिन सावधानी से दुष्प्रभाव के बारे में सावधान रहें- मैक्रोज़ का उपयोग करते समय (जब से MAX(i++,j--) अजीब व्यवहार करेंगे)

तो बेहतर है कि एक फंक्शन को परिभाषित करें

 static inline int max2ints(int x, int y) {
    return (x>y)?x:y;
 }

और इसका उपयोग करें (या कम से कम #define MAX(X,Y) max2ints((X),(Y))....)

यदि आपको MAX की उत्पत्ति को समझने की आवश्यकता है तो आपके पास एक लंबा मैक्रो हो सकता है जैसे #define COMPUTE_MAX_WITH_CAUSE(Status,Result,X,Y,Z) कि एक लंबा do{... }while(0) मैक्रो, शायद

#define COMPUTE_MAX_WITH_CAUSE(Status,Result,X,Y,Z) do { \
  int x= (X), y= (Y), z=(Z); \
  if (x > y && y > z) \
    { Status = MOSTLY_FIRST; Result = x; } \
  else if (y > x && y > z) \
    { Status = MOSTLY_SECOND; Result = y; } \
  else if (z > x && z > y) \
    { Status = MOSTLY_THIRD; Result = z; } \
  /* etc */ \
  else { Status = UNKNOWN; Result = ... } \
} while(0)

तब आप COMPUTE_MAX_WITH_CAUSE(status,res,a,b,c) कई स्थानों पर आह्वान कर सकते थे । यह थोड़ा बदसूरत है। मैं स्थानीय चर परिभाषित x, y, z बुरा दुष्प्रभाव कम करने के लिए ....


2
एक समारोह में आम तर्क को प्रतिबिंबित करना सही दृष्टिकोण है, लेकिन मैं वास्तव में यहां दो चीजों से बचूंगा: 1. मैं नई आवश्यकताओं का "आविष्कार" नहीं करूंगा (ओपी ने अधिकतम गणना करने के लिए नहीं कहा था)। और दूसरा: भले ही परिणामी कोड अधिक DRY हो सकता है, अगर यह एक जटिल मैक्रो को सही ठहराता है तो यह बहुत ही बहस का विषय है।
डॉक्टर ब्राउन

1
मैक्रोज़ अंतिम उपाय का एक उपकरण होना चाहिए। इस समस्या के लिए निश्चित रूप से सीमा से बाहर है।
केविन क्लाइन

-1

मैंने इस बारे में अधिक सोचा है, इसलिए चूंकि मेरा मुद्दा ज्यादातर दृश्य पुष्टि था कि सभी तुलना एक ही चर का उपयोग करते हैं, मुझे लगता है कि यह एक उपयोगी दृष्टिकोण हो सकता है:

a = countAs();
b = countBs();
c = countCs();

if (FIRST_IS_LARGEST(a, b, c))
    status = MOSTLY_A;
else if (SECOND_IS_LARGEST(a, b, c))
    status = MOSTLY_B;
else if (THIRD_IS_LARGEST(a, b, c))
    status = MOSTLY_C;
else
    status = DONT_KNOW; /* NO_SINGLE_LARGEST is a better name? */

यह कि प्रत्येक मैक्रो लेता है a, bऔर cउसी क्रम में पुष्टि करना आसान है, और मैक्रो नाम मुझे बचाने के लिए काम करता है जो सभी तुलना और ANDs कर रहे हैं।


1
(1) कार्यों के बजाय सहायक मैक्रोज़ क्यों? (२) आपको यहाँ दृश्य पुष्टि की आवश्यकता क्यों है? क्या यह वास्तव में आपकी मुख्य समस्या है या कोड दोहराव के परिणामस्वरूप दृश्य पुष्टि की आवश्यकता है ? आपका सबसे अच्छा विकल्प अपने कोड को एक एकल, सरल फ़ंक्शन में फैक्टर करना है जिसे आप सभी के लिए एक बार जांचते हैं
coredump
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.