2010-01-24 17 views
9

मैं एक विशिष्ट मान के लिए 5 फ़ाइलों को स्क्रब कर रहा हूं। मैं किसी भी अलग मूल्य की उम्मीद नहीं करता हूं, लेकिन चूंकि यह मेरे अपने शैक्षणिक उद्देश्यों के लिए है, इसलिए मैं एप्लिकेशन को सबसे लोकप्रिय मूल्य की गणना, तुलना और प्रिंट करने के लिए चाहता हूं।किसी सिस्टम में मानों की तुलना/गणना करें। चयन .अरेलेलिस्ट

उदाहरण के लिए

:

ArrayList arrName = new ArrayList(); 
arrName.Add("BOB") 
arrName.Add("JOHN") 
arrName.Add("TOM") 
arrName.Add("TOM") 
arrName.Add("TOM") 

परिणाम मैं चाहते हैं टॉम होने जा रहा है, लेकिन एक नौसिखिया किया जा रहा है, मैं वास्तव में पता है कि आगे बढ़ने के लिए नहीं है।

कोई भी विचार, सुझाव या उदाहरणों की बहुत सराहना की जाती है। धन्यवाद।

उत्तर

1

आप एक शब्दकोश (उपयोग कर सकते हैं नेट 2.0+

Dictionary<string, int> counts = new Dictionary<string, int>(); 
foreach (string name in arrName) { 
    int count; 
    if (counts.TryGetValue(name, out count)) { 
     counts[name] = count + 1; 
    } else { 
     counts.Add(name, 1); 
    } 
} 

// and then look for the most popular value: 

string mostPopular; 
int max = 0; 
foreach (string name in counts.Keys) { 
    int count = counts[name]; 
    if (count > max) { 
     mostPopular = name; 
     max = count; 
    } 
} 

// print it 
Console.Write("Most popular value: {0}", mostPopular); 

आप सी # 3.0 (.NET 3.5 + उपयोग कर रहे हैं) तो का उपयोग करें::) प्रत्येक मान के बार-बार गिनती धारण करने के लिए

var mostPopular = (from name in arrName.Cast<string>() 
        group name by name into g 
        orderby g.Count() descending 
        select g.Key).FirstOrDefault(); 

Console.Write("Most popular value: {0}", mostPopular ?? "None"); 
0

लूप के माध्यम से ले जाने के लिए, आप एक foreach उपयोग कर सकते हैं:

foreach (string name in arrName) { 
    Console.WriteLine(i); 
} 

और मूल्यों की गणना करने के लिए, आप एक Hashtable, जो मूल्यों के लिए कुंजी के नक्शे का उपयोग कर सकते हैं। कुंजी एक नाम हो सकती है, और मूल्य यह हो सकता है कि आपने सूची में उस नाम को कितनी बार देखा है।

Hashtable nameHash = new Hashtable(); 
foreach (string name in arrName) { 
    if (!nameHash.ContainsKey(name)) { 
     nameHash.Add(name, 1); 
    } 
    else { 
     int num = nameHash[name]; 
     nameHash.Add(name, num + 1); 
    } 
} 
1
public static string GetMostPopular(ArrayList vals) 
    { 
     IDictionary<string, int> dict = new Dictionary<string, int>(); 
     int mx = 0; 
     string ret = ""; 
     foreach (string x in vals) 
     { 
      if (!dict.ContainsKey(x)) 
      { 
       dict[x] = 1; 
      } 
      else 
      { 
       dict[x]++; 
      } 
      if (dict[x] > mx) 
      { 
       mx = dict[x]; 
       ret = x; 
      } 
     } 
     return ret; 
    } 

    static void Main() 
    { 
     ArrayList arrName = new ArrayList(); 
     arrName.Add("BOB"); 
     arrName.Add("JOHN"); 
     arrName.Add("TOM"); 
     arrName.Add("TOM"); 
     arrName.Add("TOM"); 
     string ans = GetMostPopular(arrName); 
     Console.WriteLine(ans); 
    } 
2

आप प्रयोग कर रहे हैं की नेट/सी # संस्करण निर्दिष्ट नहीं किया है, इसलिए मैं सी # के प्रत्येक संस्करण के लिए इस तरह मानते हैं: V1, V2 और v3।

सी # V1:

class CountValueComparer : IComparer 
{ 
    public int Compare(object x, object y) 
    { 
     DictionaryEntry left = (DictionaryEntry)x; 
     DictionaryEntry right = (DictionaryEntry)y; 

     return ((int)left.Value).CompareTo((int)right.Value); 
    } 
} 

Hashtable counts = new Hashtable(); 

foreach(String value in arrName) 
{ 
    if (counts.ContainsKey(value)) 
    { 
     int valueCount = (int)counts[value]; 
     ++valueCount; 
     counts[value] = valueCount; 
    } 
    else 
    { 
     counts[value] = 1; 
    } 
} 

DictionaryEntry[] sorted = new DictionaryEntry[counts.Count]; 
counts.CopyTo(sorted, 0); 
Array.Sort(sorted, new CountValueComparer()); 

foreach (DictionaryEntry entry in sorted) 
{ 
    Console.Writeline("Name: {0}; Count: {1}", entry.Key, entry.Value); 
} 

सी # संस्करण 2:

class CountValueComparer : IComparer<KeyValuePair<String, int>> 
{ 
    public int Compare(int x, int y) 
    { 
     return x.Value.CompareTo(y.Value); 
    } 
} 

// if v2, use the List<T> class! 
List<String> arrName = new List<String>(); 

arrName.Add("TOM"); 
// etc... 

Dictionary<String, int> counts = new Dictionary<String, int>(); 

foreach(String value in arrName) 
{ 
    int count; 
    if (counts.TryGetValue(value, out count)) 
    { 
     counts[value] = ++count; 
    } 
    else 
    { 
     counts[value] = 1; 
    } 
} 

KeyValuePair<String, int>[] sorted = new KeyValuePair<String, int>[counts.Count]; 
counts.CopyTo(sorted, 0); 
Array.Sort(sorted, new CountValueComparer()); 

सी # वी 3:

// if v3, use the List<T> class! 
var arrName = new List<String>(); 

arrName.Add("TOM"); 
// etc... 

var counts = (from n in arrName 
       group n by n into g 
       select new { Name = g.Key, Count = g.Count() }) 
       .OrderByDescending(x => x.Count); 
var top = counts.FirstOrDefault(); 
Console.WriteLine("Name: {0}; Count: {1}", top.Name, top.Count); 
2

इस कार्य की तरह है जिसके लिए LINQ है अच्छी तरह से अनुकूल।

पहले, आइए हम क्या कर रहे हैं निर्दिष्ट कर सकते हैं:

  1. मूल्य
  2. द्वारा आइटम समूह प्रत्येक समूह
  3. वापसी आइटम जिसकी समूह उच्चतम गिनती

यह है गणना क्वेरी उपर्युक्त लागू करता है:

private string GetMostFrequent(IEnumerable<string> items) 
{ 
    var itemsOrderedByCount = 
     from item in items 
     group item by item into itemGroup 
     orderby itemGroup.Count() descending, itemGroup.Key 
     select itemGroup.Key; 

    return itemsOrderedByCount.FirstOrDefault(); 
} 

कार्यान्वयन उच्च स्तरीय विवरण, घोषणात्मक वाक्यविन्यास का एक अच्छा दुष्प्रभाव की तरह बहुत अधिक पढ़ता है।यहाँ प्रत्येक भाग की एक त्वरित विवरण है:

from item in items 

एक पाश घोषणा की तरह है; item लूप वैरिएबल को संदर्भित करता है।

group item by item into itemGroup 

यह प्रत्येक item को अपने मूल्य के आधार पर समूह में रखता है।

orderby itemGroup.Count() descending, itemGroup.Key 

यह प्रत्येक समूह की गणना करता है और उन्हें इस प्रकार की तरह करता है कि सबसे पहले सबसे पहले होता है। यदि एक ही गिनती वाले दो समूह हैं, तो कम मूल्य चुना जाता है। (के रूप में प्रत्येक समूह के सभी एक ही मान हैं, कुंजी गिना मद है।)

select itemGroup.Key 

यह कहा गया है कि प्रत्येक समूह के लिए, हम बस में गिना आइटम चाहते हैं।

return itemsOrderedByCount.FirstOrDefault(); 

यह आदेशित सूची में सबसे पहला आइटम (उच्चतम गिनती वाले व्यक्ति) को पकड़ता है। यदि मूल अनुक्रम खाली है, तो शून्य वापस आ गया है।

उपयोग:

var items = new[] { "BOB", "JOHN", "TOM", "TOM", "TOM" }; 

Assert.AreEqual("TOM", GetMostFrequent(items)); 
4

आप आसानी से LINQ साथ ऐसा कर सकते है अगर आप इसे उपयोग कर सकते हैं, एक प्रश्न

names.Distinct().OrderByDescending(s => names.Count(u => u == s))).FirstOrDefault(); 

के लिए इसी तरह के साथ यह उच्चतम गिनती के साथ मान प्रदान करेगा, या default(Type) । समकक्ष गणना के मामलों में, यह सबसे पहले गिनती के साथ पहले व्यक्ति को वापस कर देगा। आप सामान्य रूप से सामान्य उपयोग के लिए जेनेरिक के साथ अपने एक्सटेंशन में उस विधि को डाल सकते हैं।

class Program 
{ 
    static void Main(string[] args) 
    { 

     IEnumerable<String> names = new String[] { "BOB", 
                "JOHN", 
                "TOM", 
                "TOM", 
                "TOM" }; 
     var res = names.Top(); //returns "TOM" 
    } 
} 

public static class Extensions 
{ 

    public static T Top<T>(this IEnumerable<T> values) 
    { 
     return values.Distinct().OrderByDescending(s => values.Count(u => u.Equals(s))).FirstOrDefault(); 
    } 
} 

आप सभी मूल्यों है कि उच्चतम गिनती है की जरूरत है, जैसे कि आपकी सूची था "BOB", "JOHN", "JOHN", "TOM", "TOM" मैं आप के बजाय क्रम में इस संस्करण इस्तेमाल कर सकते हैं दोनों जॉन और टॉम वापस जाने के लिए लगता है:

public static IEnumerable<T> Top<T>(this IEnumerable<T> values) 
    { 
     List<T> ret = new List<T>(); 
     int max = -1; 

     foreach (var val in values.Distinct()) 
     { 
      int count = values.Count(t => t.Equals(val)); 

      if (count >= max) 
      { 
       if (count > max) 
       { 
        ret.Clear(); 
        max = count; 
       } 
       ret.Add(val); //stacks equivalent count, if applicable 
      } 
     } 

     return ret; 
    } 
संबंधित मुद्दे