2011-07-20 22 views
9

के सूचकांक के अंदर रखने के लिए मॉड्यूलस ऑपरेटर का उपयोग करना मान लें कि मेरे पास एम तत्वों के साथ वेक्टर वी है, और वेक्टर को यादृच्छिक एक्सेस इंडेक्स I कहा जाता है।कंटेनर

जब मैं सूचकांक में वृद्धि करता हूं, यदि यह सीमा से बाहर हो जाता है, तो मैं पहले (शून्य) तत्व को इंडेक्स करना चाहता हूं। इसी तरह, जब मैं सूचकांक में कमी करता हूं, अगर सूचकांक < 0 है, तो मैं अंतिम तत्व को इंडेक्स करना चाहता हूं। पल मैं एक बार में केवल कंटेनर एक तत्व के माध्यम से आगे बढ़ रहा हूँ पर है, इसलिए इस समारोह के साथ आया था:

unsigned int GetIndexModM(int index,unsigned int m) {return (index + m) % m;} 

कॉल-साइट इस प्रकार दिखाई देंगे:

std::vector<Whatever> v = ... // initialise with 5 elements 
unsigned int i = 0; 
unsigned int j = GetIndexModM(static_cast<int>(i) - 1,v.size()); // get preceeding index 

यह कार्य नहीं करेंगी

unsigned int j = GetIndexModM(static_cast<int>(i) - 17,v.size()); // oops: returns -2 

मेरा प्रश्न: एक समारोह है कि किसी भी पूर्णांक लेता है और यह एक सूचकांक के रूप में जगह है रिटर्न के सबसे सुरुचिपूर्ण कार्यान्वयन क्या है लेकिन अगर एक एक मूल्य> मीटर सूचकांक से घटा देती है असफल?

val = ((val % mod_val) + mod_val) % mod_val; 

उदाहरण के लिए, मान लेते हैं हम 0 और 359 के बीच समावेशी मूल्य रखना चाहते हैं:

उत्तर

12

एमओडी से निपटने के लिए चाल इस है, जो सकारात्मक है और साथ ही ऋणात्मक संख्याओं के साथ काम करता है। हम इसका उपयोग कर सकते थे:

val = ((val % 360) + 360) % 360; 

यहां सी ++ में एक साधारण उदाहरण है।

int getmod(int val, int mod) { 
    return ((val % mod) + mod) % mod; 
} 

int main() { 
    printf("%d\n", getmod(50,360)); // prints 50 
    printf("%d\n", getmod(-400,360)); // prints 320 
    printf("%d\n", getmod(350,360)); // prints 350 
    printf("%d\n", getmod(375,360)); // prints 15 
    printf("%d\n", getmod(-725,360)); // prints 355 


    return 0; 
} 
+0

कुछ प्लेटफार्मों पर, तुलनात्मक लागत पर दूसरे मॉड्यूलो ऑपरेशन से बचने के लिए तेज़ी से हो सकता है: 'val = val% mod; वापसी मूल्य <0? वैल + मोड: वैल; ' –

+0

क्या यह काम करता है जब' val <-mod_val', या यह केवल '-mod_val

+0

@ एंड्रे कैरॉन - यह उस परिदृश्य में काम करता है, मैंने एक और उदाहरण जोड़ा (अंतिम प्रिंटफ देखें)। – dcp

0

दुर्भाग्यवश, सी ++ उचित मॉड्यूलस को लागू नहीं करता है जो अभी भी नकारात्मक पूर्णांक के लिए सही तरीके से काम करता है।

मुझे लगता है कि सबसे साफ समाधान वास्तव में सभी मामलों का ख्याल रखने के लिए if का उपयोग कर रहा है। यह कम से कम कोड स्पष्ट करता है (क्योंकि हर मामले स्पष्ट है) और त्रुटियों ढूंढना आसान:

unsigned GetIndexModM(int index, unsigned m) { 
    if (index < 0) 
     return GetIndexModM(index + m, m); 
    if (index >= m) 
     return index % m; 
    return index; 
} 
+3

यदि सूचकांक बड़ा और नकारात्मक है तो यह बहुत अक्षम है। –

+0

मैंने आपके फ़ंक्शन को तर्क -400,360 के साथ करने की कोशिश की और मुझे 216 लौटा, लेकिन जवाब 320 होना चाहिए। – dcp

+0

@dcp फिर से प्रयास करें, भयानक त्रुटि। –

-1

निम्नलिखित सुनिश्चित करता है कि index [0, n) में है, लेकिन केवल एक मापांक आपरेशन और कोई शाखाओं के साथ :

index = index % n + (index < 0)*n 

जहां पहले कार्यकाल (मापांक ऑपरेटर युक्त) (-n, n) में मूल्य हो जाता है और दूसरे कार्यकाल सुनिश्चित करता है कि मूल्य [0, n) में है।

ध्यान दें कि यह अविश्वसनीय है n एक अहस्ताक्षरित प्रकार है और सी के पुराने (पूर्व 11) संस्करणों में जब ++ जहां% ऑपरेटर कार्यान्वयन नकारात्मक तर्क के लिए निर्भर है।