2008-12-10 12 views
19

क्या linq का उपयोग कर एक त्वरित और अच्छा तरीका है?सूची में सबसे अधिक संख्या संख्या खोजें <int>

+0

@AakashM, यह लगभग सुनिश्चित है कि लैम्ब्डा अभिव्यक्ति ओपी द्वारा लिनक, और कुछ प्रतिनिधि/अभिव्यक्ति दृष्टिकोण नहीं था। कोई विचार नहीं कि संपादन क्यों वापस किया गया था। – nawfal

+0

@nawfal 1) इस अनियंत्रित उपयोगकर्ता को 4 + साल पहले क्या संदेह है, यहां तक ​​कि 'लगभग निश्चित' होने के लिए भी संदेह करने का कोई तरीका नहीं है।2) [टैग: खोज-घटनाएं] एक गरीब है और किसी भी मामले में अनुचित टैग है। 3) शब्द "linq" कोड नहीं है और इसलिए कोड के रूप में स्वरूपित नहीं किया जाना चाहिए। मेरे दिमाग में एक संपादन के लिए तीन सबसे अच्छे-संदिग्ध हिस्सों में बदलाव के लिए पूरी तरह से अच्छे आधार हैं, लेकिन यदि आप असहमत हैं तो इसे मेटा में ले जाएं। – AakashM

+0

@AakashM मैं 3 से सहमत हूं। फिर भी मेरे संपादन का सारांश एक और समझदार सवाल था। आप अनुचित (?) टैग को हटा सकते थे, और कोड स्वरूपण भी कर सकते थे अगर वह वापस करने के बजाए रीडिटिंग द्वारा महत्वपूर्ण होता है। तो अब, * किसी भी मामले में अनुचित टैग *, तो किस प्रकार के प्रश्न यह अधिक उपयुक्त हैं? 2) आपको क्या लगता है कि ओपी का मतलब * लैम्ब्डा एक्सप्रेशन * से होना चाहिए? मेरा मुद्दा है ** ** कुछ समय के लिए सी # सर्कल में होने पर संदेह करने का एक तरीका है, और इसका उत्तर एक मजबूत संदेह है जिसे उत्तर ओपी ने चुना है। – nawfal

उत्तर

60

कैसे के बारे में:

var most = list.GroupBy(i=>i).OrderByDescending(grp=>grp.Count()) 
     .Select(grp=>grp.Key).First(); 

या क्वेरी सिंटैक्स में:

public static T MostCommon<T>(this IEnumerable<T> list) 
{ 
    return ... // previous code 
} 

:

var most = (from i in list 
      group i by i into grp 
      orderby grp.Count() descending 
      select grp.Key).First(); 
बेशक

, अगर आप इस बार-बार प्रयोग करेंगे, तो आप एक विस्तार विधि जोड़ सकते हैं फिर आप इसका उपयोग कर सकते हैं:

var most = list.MostCommon(); 
+0

जो कुछ मैं प्राप्त करने की कोशिश कर रहा था, लेकिन मेरा दिमाग इस समय काम नहीं कर रहा है। –

+5

क्या होगा अगर एक से अधिक तत्व उत्तर हैं? –

+1

@ वारुन - अच्छा सवाल; लेकिन मूल LINQ के साथ –

4

लैम्ब्डा भाव के बारे में सुनिश्चित नहीं हैं, लेकिन मैं

  1. क्रमबद्ध सूची जाएगा [O (n लॉग ऑन एन)]

  2. सूची की जांच करके [हे (एन)] सबसे लंबे समय तक चलाने की खोज -length।

  3. इसे फिर से स्कैन करें [ओ (एन)] उस रन-लंबाई वाले प्रत्येक नंबर की रिपोर्टिंग।

ऐसा इसलिए है क्योंकि एक से अधिक होने वाली संख्या हो सकती है।

0

किसी ने ऐसे समाधान के लिए कहा जहां संबंध हैं।

int indicator = 0 

var result = 
    list.GroupBy(i => i) 
    .Select(g => new {i = g.Key, count = g.Count()} 
    .OrderByDescending(x => x.count) 
    .TakeWhile(x => 
    { 
     if (x.count == indicator || indicator == 0) 
     { 
     indicator = x.count; 
     return true; 
     } 
     return false; 
    }) 
    .Select(x => x.i); 
2

मेरा उत्तर here से लिया:: यहाँ पर एक चाकू है

public static IEnumerable<T> Mode<T>(this IEnumerable<T> input) 
{    
    var dict = input.ToLookup(x => x); 
    if (dict.Count == 0) 
     return Enumerable.Empty<T>(); 
    var maxCount = dict.Max(x => x.Count()); 
    return dict.Where(x => x.Count() == maxCount).Select(x => x.Key); 
} 

var modes = { }.Mode().ToArray(); //returns { } 
var modes = { 1, 2, 3 }.Mode().ToArray(); //returns { 1, 2, 3 } 
var modes = { 1, 1, 2, 3 }.Mode().ToArray(); //returns { 1 } 
var modes = { 1, 2, 3, 1, 2 }.Mode().ToArray(); //returns { 1, 2 } 

मैं ऊपर दृष्टिकोण और David B'sTakeWhile के बीच एक प्रदर्शन परीक्षण के लिए चला गया।

स्रोत = {}, पुनरावृत्तियों = 1000000
मेरा - 300 एमएस, डेविड - 930 एमएस

स्रोत = {1}, पुनरावृत्तियों = 1000000
मेरा - 1070 एमएस, डेविड की - 1560 एमएस

स्रोत = 2 डुप्लिकेट, पुनरावृत्तियों = 10000
मेरा साथ 100 + ints - साथ 100 + के बारे में घ 500 एमएस

स्रोत = 10000 यादृच्छिक ints - 300 एमएस, डेविड uplicates, पुनरावृत्तियों = 1000
मेरा - 1280 एमएस, डेविड की - 1400 एमएस

1

यहाँ एक और सवाल का जवाब है, जो तेजी से हो रहा है है। मुझे लगता है कि Nawfal's answer आमतौर पर तेज़ है लेकिन यह लंबे अनुक्रमों पर इसे छाया कर सकता है।

public static IEnumerable<T> Mode<T>(
    this IEnumerable<T> source, 
    IEqualityComparer<T> comparer = null) 
{ 
    var counts = source.GroupBy(t => t, comparer) 
     .Select(g => new { g.Key, Count = g.Count() }) 
     .ToList(); 

    if (counts.Count == 0) 
    { 
     return Enumerable.Empty<T>(); 
    } 

    var maxes = new List<int>(5); 
    int maxCount = 1; 

    for (var i = 0; i < counts.Count; i++) 
    { 
     if (counts[i].Count < maxCount) 
     { 
      continue; 
     } 

     if (counts[i].Count > maxCount) 
     { 
      maxes.Clear(); 
      maxCount = counts[i].Count; 
     } 

     maxes.Add(i); 
    } 

    return maxes.Select(i => counts[i].Key); 
} 
+0

यह एक अद्यतन के योग्य भी है :) – nawfal

+0

@nawfal वास्तव में, सहमत और किया। – Jodrell

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