2009-03-24 4 views
16

पर सेट किए गए झंडे की संख्या की गणना करना मुझे यकीन है कि ऐसा करने का एक बेहतर तरीका होना चाहिए। मैं झंडे enum पर एक गिनती ऑपरेशन करने की कोशिश कर रहा हूँ। इससे पहले कि मैं सभी संभावित मूल्यों पर जोर दे रहा था और सफल और संचालन की गिनती कर रहा था।एक गणना

उदा

[Flags] 
public enum Skills 
{ 
    None = 0, 
    Skill1 = 1, 
    Skill2 = 2, 
    Skill3 = 4, 
    Skill4 = 8, 
    Skill5 = 16, 
    Skill6 = 32, 
    Skill7 = 64, 
    Skill8 = 128 
} 

public static int Count(Skills skillsToCount) 
{ 
    Skills skill; 
    for (int i = 0; i < SkillSet.AllSkills.Count; i++) 
    { 
     skill = SkillSet.AllSkills[i]; 
     if ((skillsToCount & skill) == skill && skill != Skills.None) 
     count++; 
    } 
    return count; 
} 

मुझे यकीन है कि ऐसा करने का एक बेहतर तरीका होना चाहिए, लेकिन मानसिक ब्लॉक से पीड़ित होना चाहिए। क्या कोई एक अच्छा समाधान सलाह दे सकता है?

+0

आप और अधिक स्पष्ट होगा कि क्या आप कौशल Enum अपने आप में झंडे की कुल संख्या पता लगाने की कोशिश कर रहे हैं? या कौशल "कौशल" पर लागू कौशल एनम मूल्य की संख्या? – Sung

+0

मैं निश्चित रूप से इसे गलत तरीके से पढ़ता हूं। ऐसा लगता है कि वह उस बिट्स की संख्या को गिनने की कोशिश कर रहा है, न कि गणना में वस्तुओं की संख्या। मैंने अपनी पोस्ट हटा दी –

+0

अस्पष्ट होने के लिए खेद है। दरअसल मैं गिनती विधि में पारित सक्रिय कौशल की संख्या को गिनने की कोशिश कर रहा हूं। यह स्पष्ट करने के लिए थोड़ा सा सवाल संपादित करेगा। – Ian

उत्तर

5

साइट पर देखने के बाद असफ ने सुझाव दिया कि मैं थोड़ा अलग समाधान ढूंढने में कामयाब रहा हूं जिसे मैंने Int32 के लिए काम किया है।

यहाँ किसी और के लिए कोड है:

internal static UInt32 Count(this Skills skills) 
    { 
     UInt32 v = (UInt32)skills; 
     v = v - ((v >> 1) & 0x55555555); // reuse input as temporary 
     v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp 
     UInt32 c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count 
     return c; 
    } 
+1

यह केवल 32 या कम विकल्पों के साथ झंडे के लिए काम करता है। –

+0

लेकिन ध्वज enums के अनुसार ध्वज enums 32 विकल्प तक सीमित हैं ताकि कोई समस्या नहीं है। – Ian

+0

यदि कोई दिलचस्पी लेता है तो उसे हेमिंग वाइग कहा जाता है। विकिपीडिया से अधिक जानकारी: https://en.wikipedia.org/wiki/Hamming_weight – SOReader

-3

Enum.GetNames() enum में सभी नामों की एक सरणी वापस कर देगा, एक जोड़ जोड़ें। गिनती खोजने के लिए।

-2
int count = Enum.GetValues(typeof(Skills)).Length; 
+2

यह सवाल का जवाब नहीं देता है, इसे फिर से पढ़ें –

3

गिनती गिनती कितने बिट्स enum का पूर्णांक मान में 1 की तैयारी में हैं के बराबर है।

उदहारण के लिए:

वहाँ C/C++, जो आप सी # करने के लिए अनुकूलित कर सकते हैं में ऐसा करने का बहुत तेजी से तरीके हैं

int bitcount(unsigned int n) { 
    /* works for 32-bit numbers only */ 
    /* fix last line for 64-bit numbers */ 

    register unsigned int tmp; 

    tmp = n - ((n >> 1) & 033333333333) 
      - ((n >> 2) & 011111111111); 
    return ((tmp + (tmp >> 3)) & 030707070707) % 63; 
} 

here से लिया।

संपादित
दिए गए लिंक मर चुका है। another one मिला जो शायद एक ही सामग्री में है।

+0

यह वही है जो मैं हाँ के बाद हूं। हालांकि यह अभी तक काम नहीं कर सकता है। – Ian

+0

आपको इस बारे में बेहतर समझ हो सकती है कि मैं ... वर्तमान में मैं UInt32 का उपयोग करने की कोशिश कर रहा हूं लेकिन 033333333333 इत्यादि UInt32 पर नहीं डालेगा। – Ian

+0

उस साइट का उपयोग करके मैंने एक अलग-अलग दृष्टिकोण के साथ एक पोस्ट ढूंढने में कामयाब रहा जो मुझे समाधान में मिला। धन्यवाद असफ। – Ian

0
<FlagsAttribute()> _ 
Public Enum Skills As Byte 
    None = 0 
    Skill1 = 1 
    Skill2 = 2 
    Skill3 = 4 
    Skill4 = 8 
    Skill5 = 16 
    Skill6 = 32 
    Skill7 = 64 
    Skill8 = 128 
End Enum 


    Dim x As Byte = Skills.Skill4 Or Skills.Skill8 Or Skills.Skill6 
    Dim count As Integer 
    If x = Skills.None Then count = 0 Else _ 
     count = CType(x, Skills).ToString().Split(New Char() {","c}, StringSplitOptions.RemoveEmptyEntries).Count 

"बेहतर" की परिभाषा पर निर्भर करता है।

कौशल के लिए जांच। किसी की आवश्यकता नहीं है क्योंकि यदि कोई बिट्स चालू नहीं है, तो स्ट्रिंग() स्किल लौटाती है। जिसके परिणामस्वरूप 1 की गणना होती है। यह पूर्णांक, लंबे और उनके हस्ताक्षरित रिश्तेदारों के लिए समान कार्य करेगा।

0

इस विधि का उपयोग करने का एकमात्र कारण यह है कि झंडे संगत नहीं हैं और यदि झंडे समय-समय पर जोड़े जाएंगे।

<FlagsAttribute()> _ 
Public Enum Skills As Integer 
    Skill1 = CInt(2^0) 'bit 0 
    Skill2 = CInt(2^1) 
    Skill3 = CInt(2^2) 
    Skill4 = CInt(2^3) 
    Skill5 = CInt(2^4) 
    Skill6 = CInt(2^5) 
    Skill7 = CInt(2^6) 
    Skill8 = CInt(2^7) 
    Skillx = CInt(2^10) 'bit 10, some bits were skipped 
End Enum 


    Dim mySkills As Integer = Skills.Skillx Or Skills.Skill4 Or Skills.Skill8 Or Skills.Skill6 
    Dim count As Integer 'count of bits on 
    count = CType(mySkills, Skills).ToString().Split(New Char() {","c}, _ 
                StringSplitOptions.RemoveEmptyEntries).Count 

यदि "बेहतर" का मतलब तेज़ है तो यह नहीं है;)।

27

निम्नलिखित कोड आपको बिट्स की संख्या के अनुसार अलग-अलग आकार के किसी भी प्रकार के किसी भी प्रकार के लिए निर्धारित बिट्स की संख्या देगा।

public static int GetSetBitCount(long lValue) 
{ 
    int iCount = 0; 

    //Loop the value while there are still bits 
    while (lValue != 0) 
    { 
    //Remove the end bit 
    lValue = lValue & (lValue - 1); 

    //Increment the count 
    iCount++; 
    } 

    //Return the count 
    return iCount; 
} 

इस कोड को अन्य उदाहरण में के रूप में के रूप में यह केवल हर संभव बिट के लिए प्रत्येक बिट के लिए एक बार के बजाय एक बार दोहराता बहुत ही कुशल है।

+4

निफ्टी! गुड बैग में जाता है! –

+1

@JohannGerell आपको [answer] (http://stackoverflow.com/a/42557518/197591) पसंद आया है मैंने अभी आपके गुडी बैग के लिए पोस्ट किया है! :) – Neo

2

BitArray और LINQ का उपयोग कर यह करने के लिए एक बहुत ही संक्षिप्त तरीके:

public static int Count(Skills skillsToCount) 
{ 
    return new BitArray(new[] {(int)skillsToCount}).OfType<bool>().Count(x => x); 
}