2013-03-03 4 views
8

मेरे कार्यक्रम में कुछ बार, मुझे यह जांचना पड़ा कि कोई चर कई विकल्पों में से एक था या नहीं। उदाहरण के लिएसी ++ एक चर से कई मानों की तुलना करने के लिए सबसे प्रभावी तरीका है?

if (num = (<1 or 2 or 3>)) { DO STUFF } 

मैंने 'OR' के साथ गड़बड़ी की है, लेकिन कुछ भी सही नहीं लगता है। मैंने कोशिश की है

if (num == (1 || 2 || 3)) 

लेकिन यह कुछ भी नहीं करता है। कृपया सहायता कीजिए! अग्रिम धन्यवाद।

पीएस मुझे कई समूहों के बीच अंतर करने की जरूरत है। उदाहरण के लिए ...

if (num = (1,2,3)) 

else if (num = (4,5,6)) 

else if (num = (7,8,9)) 
+2

है 'अगर (संख्या == 1 || संख्या == 2 || संख्या == 3)' या 'अगर (संख्या> = 1 && संख्या <= 3) 'बहुत ज्यादा टाइपिंग? यदि यह लंबा है, तो आप हमेशा कुछ प्रकार की सरणी बना सकते हैं और 'std :: find' का उपयोग कर सकते हैं। – chris

+1

त्वरित प्रतिक्रियाओं के लिए धन्यवाद http://stackoverflow.com/q/14368525/726361 –

+0

देखें। @ क्रिस, मैं बस थोड़ा और सुरुचिपूर्ण कुछ ढूंढ रहा था। –

उत्तर

6

है यह देखने के लिए ढूंढें विधि का उपयोग कर सकते हैं तो जो मान आप जांचना चाहते हैं कि पर्याप्त रूप से छोटे हैं, आप अपने द्वारा प्राप्त मूल्यों का थोड़ा मुखौटा बना सकते हैं और फिर उस बिट को सेट करने के लिए जांच सकते हैं।

मान लीजिए, आप कुछ समूहों की परवाह करते हैं।

static const unsigned values_group_1 = (1 << 1) | (1 << 2) | (1 << 3); 
static const unsigned values_group_2 = (1 << 4) | (1 << 5) | (1 << 6); 
static const unsigned values_group_3 = (1 << 7) | (1 << 8) | (1 << 9);  
if ((1 << value_to_check) & values_group_1) { 
    // You found a match for group 1 
} 
if ((1 << value_to_check) & values_group_2) { 
    // You found a match for group 2 
} 
if ((1 << value_to_check) & values_group_3) { 
    // You found a match for group 3 
} 

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

+0

कूल। इससे चीज आसान हो जाती है। अगर मैं देखना चाहता हूं "अगर 1; अन्य यदि 2, तो अगर 3;" मुझे यह कैसे करना है? क्या मुझे एक नया सा मास्क चाहिए, या मैं बस "(2 << n)" में जोड़ सकता हूं? –

+0

यदि आप मान 1, 2 और 3 की जांच करना चाहते हैं, तो आपका बिट मास्क इसके बदले वैल्यू_आई_like = (1 << 1) | (1 << 2) | (1 << 3) ;. –

+0

नहीं, आप गलत समझते हैं। मैं (1,2,3) और (4,5,6) –

4

आपको प्रत्येक मूल्य के साथ तुलना करना है। जैसे

if (num == 1 || num == 2 || num == 3) { stuff } 

तुम भी और एक स्विच पर विचार कर सकते जानबूझकर मामलों के माध्यम से गिरने (हालांकि मैं इसे आप क्या बताते हुए कर रहे हैं के लिए सबसे अच्छा समाधान है नहीं लगता है)।

switch (num) { 
    case 1: 
    case 2: 
    case 3: 
     {DO STUFF} 
     break; 

    default: 
     //do nothing. 
} 
+0

हाँ, ठीक वही नहीं जो मैं ढूंढ रहा हूं। फिर भी धन्यवाद! –

+1

उम्म, नहीं, आप ऐसा करने के लिए _have_ नहीं करते हैं। – einpoklum

2

आप पूर्णांकों का एक सेट को परिभाषित इसे करने के लिए वांछित मान जोड़ने, और फिर अगर सवाल में मूल्य सेट में

std::set<int> values; 
// add the desired values to your set... 
if (values.find(target) != values.end()) 
    ... 
+0

यह चीजों को करने का एक दिलचस्प तरीका है ... मैं इसे आज़मा दूंगा, धन्यवाद! –

+0

क्षमा करें, मुझे बस त्रुटियों का एक टन मिल रहा है। आप इसका उपयोग कैसे करते हैं? क्या आप एक उदाहरण दे सकते हैं? –

+2

लॉल, इसकी सादगी में प्रतिभा! @TheWalkingCactus बस 'set' के साथ' count' का उपयोग करें। –

14

यहाँ सी ++ 11 में एक तरीका है, std :: initializer_list का उपयोग कर:

#include <initializer_list> 

template <typename T> 
bool is_in(const T& val, const std::initializer_list<T>& list) 
{ 
    for (const auto& i : list) { 
     if (val == i) { 
      return true; 
     } 
    } 
    return false; 
} 
उस के साथ

, आप कर सकते हैं:

if (is_in(num, {1, 2, 3}) { DO STUFF } 

नोट तथापि कि <1 तरह बातें संभव नहीं हैं।

+0

यह सुविधाजनक दिखता है, लेकिन मैं 11 का उपयोग नहीं कर रहा हूं। मैं सिर्फ सादा ओल 'सी ++ में हूं। –

3

मैं सिर्फ एक समान समस्या थी और मैं इन सी ++ 11 समाधान के लिए आया था:

template <class T> 
struct Is 
{ 
    T d_; 
    bool in(T a) { 
    return a == d_; 
    } 
    template <class Arg, class... Args> 
    bool in(Arg a, Args... args) { 
    return in(a) || in(args...); 
    } 
}; 

template <class T> 
Is<T> is(T d) { 
    return Is<T>{d}; 
} 

या प्रत्यावर्तन समाप्त विधि के बिना विकल्प के रूप में। ध्यान रखें कि तुलनाओं का क्रम अपरिभाषित है और यह पहला मिलान मिलने पर जल्दी समाप्त नहीं होता है। लेकिन कोड अधिक कॉम्पैक्ट है।

template <class T> 
struct Is { 
    const T d_; 
    template <class... Args> 
    bool in(Args... args) { 
    bool r{ false }; 
    [&r](...){}(((r = r || d_ == args), 1)...); 
    return r; 
    } 
}; 

template <class T> 
Is<T> is(T d) { 
    return Is<T>{d}; 
} 

तो दोनों के समाधान के लिए कोड देखने की तरह होगा:

if (is(num).in(1,2,3)) { 
    // do whatever needs to be done 
} 
0

मैं enums के लिए इसी तरह कुछ करने के लिए की जरूरत है। मेरे पास एक चर है और मूल्यों की एक श्रृंखला के खिलाफ इसका परीक्षण करना चाहता हूं।

यहां मैंने एक विविध टेम्पलेट फ़ंक्शन का उपयोग किया है। const char* प्रकार के लिए विशेषज्ञता पर ध्यान दें, ताकि is_in(my_str, "a", "b", "c")my_str स्टोर "a" के लिए अपेक्षित परिणाम हो।

#include <cstring> 

template<typename T> 
constexpr bool is_in(T t, T v) { 
    return t == v; 
} 

template<> 
constexpr bool is_in(const char* t, const char* v) { 
    return std::strcmp(t,v); 
} 

template<typename T, typename... Args> 
constexpr bool is_in(T t, T v, Args... args) { 
    return t==v || is_in(t,args...); 
} 

उदाहरण उपयोग:

enum class day 
{ 
    mon, tues, wed, thur, fri, sat, sun 
}; 

bool is_weekend(day d) 
{ 
    return is_in(d, day::sat, day::sun); 
} 
संबंधित मुद्दे

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