2015-11-20 18 views
7

N तत्वों को देखते हुए, केवल पहले (0) और अंतिम (एन -1) तत्व को संसाधित करें।पहले और अंतिम तत्व पर लूप केवल

लेकिन, यदि N = 1, केवल एक बार एक तत्व को संसाधित करें।

एक लूप का उपयोग करना जो एक या दो बार चलता है, उचित रूप से, हमें लूप बॉडी को डुप्लिकेट करने से बचने देता है। यदि ऐसा करने के लिए एक पठनीय तरीका है, तो इसका स्रोत-कोड आकार का लाभ होता है। यदि लूप बॉडी बड़ा है, तो इसमें मशीन-कोड आकार के फायदे भी हो सकते हैं, और संकलक इसे डुप्लिकेट नहीं कर सकता है।


मैं N-1 से incrementing कोशिश की, लेकिन यह काम नहीं करेगा जब N=1 (हमेशा के लिए लूप)। क्या वहां चालें हैं (रिवर्स लूप एफ.आई) जो इसे ठीक करेगी?

for (i = 0 ; i < N ; i += (N - 1)) 

संपादित करें:

मेरे मूल समस्या एक्स, वाई, जेड दिशा में तीन नेस्टेड छोरों से संबंधित है, जिसके कारण मैं कर सकता न सिर्फ प्रक्रिया ELEM [0]) और ELEM [एन 1]। अब मैं निम्नलिखित

#define forEachLglBound(i_,j_,k_)         \ 
     for(Int i_ = 0;i_ < NPX;i_+=((NPX>1) ? (NPX-1) : 1))  \ 
      for(Int j_ = 0;j_ < NPY;j_+=((NPY>1) ? (NPY-1) : 1)) \ 
       for(Int k_ = 0;k_ < NPZ;k_+=((NPZ>1) ? (NPZ-1) : 1)) 

+0

आपको लगातार दो तत्वों के लिए लूप की आवश्यकता क्यों है? – kaylum

+0

यदि आप केवल पहले और अंतिम तत्व –

+6

तक पहुंचना चाहते हैं तो आपको लूप की आवश्यकता क्यों होगी? काम करने के लिए बस एक फ़ंक्शन लिखें और इसे 'सरणी [0]' और 'सरणी [एन -1]' के साथ कॉल करें। इरादा बहुत स्पष्ट होगा। – clcto

उत्तर

6

निम्न पंक्ति के बारे में कैसे। मूल समाधान के लिए बहुत करीब (textwise!)।

for (i = 0 ; i < N ; i += (N > 1) ? N-1 : 1) 
+0

* टर्नरी * ऑपरेटर के कई अद्वितीय उपयोग हैं। पहले ब्लश में यह तर्क के अजीब बिट की तरह दिख सकता है, लेकिन इसकी इनलाइन सशर्त निर्णय लेने से कई उपयोगी तरीकों से अन्यथा संभव नहीं होगा। –

+0

यह [काफी अच्छे कोड] (http://goo.gl/OxdrQW) से संकलित है, लेकिन पढ़ना बहुत आसान नहीं है, आईएमओ। मुझे लगता है कि मेरा जवाब अधिक पठनीय है। –

3
for (i = 0, repeat = 0; repeat < 2 && repeat < N; repeat++, i = N-1) 

या

repeat = (N<2) ? N : 2; 
for (i = 0; repeat > 0; repeat--, i = N-1) 
+0

धन्यवाद। मुझे लगता है कि यह एकमात्र रास्ता हो सकता है। – user1382302

-1

इस बारे में है, हालांकि शायद एक for loop उपयोग करने के लिए की जरूरत नहीं है कैसे है, लेकिन यह एक आसान तरीका और समझने में आसान है।

for (int first = 0, last = N - 1;;) { 
    // the stuff use first 
    if (first != last) { 
    // the stuff use last 
    } 
    break; 
} 
+0

यह वही तत्व पर 'सामान' को दो बार चलाने से नहीं बचाता है जब 'N = 1'। यही कारण है कि यह सवाल तुच्छ नहीं है। –

+0

सामान पहले और आखिरी बार उपयोग करने का मतलब पहले दो बार उपयोग नहीं करता है! @ पीटरकॉर्ड – luoluo

+1

'के लिए {...; टूटना; } 'संरचना बिल्कुल कुछ नहीं कर रही है। अभी भी एक डाउनवोट, क्योंकि अगर आप उसे 'if' का उपयोग करने और' सामान 'दोहराने के लिए बताना चाहते हैं, तो कहें। –

3

आप एक समारोह या मैक्रो में पाश शरीर को अलग कर सकते हैं, शायद सबसे पठनीय तरीका है:

process(arr[0]); 
if (N-1 != 0) 
    process(arr[N-1]); 

अगर वह एक विकल्प नहीं है, या आप इनमें से किसी एक लगता है लूप संरचना पर्याप्त पठनीय है:

एक्सओआर 0 के बीच एक चर टॉगल कर सकता है और आपके साथ एक्सओआर मूल्य।

int i=0; 
do { 
    process(arr[i]); 
} while(i ^= (N-1)); // xor to toggle, but stays zero if N-1 is zero 

यह अन्य विकल्प, as you can see on godbolt में से किसी की तुलना में बेहतर एएसएम को संकलित करता है। मैंने अन्य उत्तरों से विचारों को शामिल किया, जिसमें सरल if शामिल है (जो ऑपरेशन को डुप्लिकेट करते समय बहुत अच्छा करता है)।

xor संस्करण ट्रिपल-नेस्टेड लूप में बहुत अच्छी तरह से काम करता रहता है (गॉडबॉल्ट लिंक के नीचे while_xor_triple फ़ंक्शन देखें)।


XOR का उपयोग कर के बिना, मुझे लगता है कि इस पाश मामूली पढ़ी जा सकती है:

int i=0; 
do { 
    process(arr[i]); 
} while((i!=N-1) && (i=N-1)); 

अगर i पहले से ही N-1, नहीं है कि करने के लिए यह सेट और पाश फिर से करना। यह एन-1 के अलावा किसी भी अभिव्यक्ति की गणना किए बिना, कंपाइलर को कुशलतापूर्वक परीक्षण करने के लिए आसान बनाना चाहिए। जीसीसी अभी भी && दोनों ऑपरेटरों पर परीक्षण और शाखाएं अलग-अलग हैं, लेकिन कुछ अन्य उत्तरों की तुलना में कम ओवरहेड के साथ।


2 जबकि पाश कुछ इस तरह के संकलन सकता है (लेकिन दुर्भाग्य से नहीं हुआ, क्योंकि जीसीसी मेरी पहली दो insns की प्रवंचना नहीं है):

xor edx, edx 
.repeat: 
    mov ecx, edx 
     ... loop body using i (ecx) 
    mov edx, [N] 
    dec edx  ; edx = N-1 
    cmp ecx, edx 
    jne .repeat 

मैं के बारे में सोचा एएसएम में इसे कैसे करें इसके बारे में सोचते समय एक्सओआर विचार। IDK अगर एक स्मार्ट संकलक while(i!=N-1 && i=N-1) संस्करण से इस उत्पादन कर सकता है, लेकिन यह निश्चित रूप से बेहतर है: mov/dec मक्खी पर यह गणना करने के लिए दूर जाना

xor ecx, ecx 
.repeat: 
     ... loop body using i (ecx) 
    mov edx, [N] 
    dec edx  ; edx = N-1 
    xor ecx, edx ; i ^= N-1 
    jnz .repeat  ; jump if the last result wasn't zero 

आप N-1 एक रजिस्टर या स्मृति में संग्रहीत है, तो।

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