2010-10-01 15 views
8

में डुप्लिकेट संख्या की गिनती मैं एक सूची है:एक सूची

int list = { 1,1,2,3,4,4,5,7,7,7,10}; 

अब मैं एक प्रोग्राम है जो डबल संख्या की गणना करता है बनाने की जरूरत है। एक संख्या दोगुना है जब इससे पहले की संख्या समान होती है। मुझे आशा है की तुम समझ गए होगे। तो 1 डबल है, 4 युगल है और हमें 7,7,7 में 2 डबल मिले।

+1

क्या आप थोड़ी अधिक जानकारी के बारे में बता सकते हैं कि क्यों/कैसे? होमवर्क/साक्षात्कार प्रश्न की तरह लगता है। लूप का उपयोग करके हल करना बहुत आसान होगा और मैच की तुलना में मौजूदा और स्टोर/रीसेट की तुलना में पिछली तुलना करें - 7 को रोकने के लिए अतिरिक्त तर्क का थोड़ा सा 3 बार गिना जाता है। यदि आप चाहते थे कि यह linq या कुछ में हल किया जाए तो यह और अधिक दिलचस्प है। –

उत्तर

26

यहाँ LINQ में एक समाधान है:

var doubles = list.Skip(1) 
        .Where((number, index) => list[index] == number); 

इस सूची के पहले सदस्य लंघन द्वारा एक और अनुक्रम बनाता है, और फिर दोनों दृश्यों में एक ही सूचकांक और एक ही मूल्य है कि से तत्वों पाता है। यह रैखिक समय में चलेगा, लेकिन केवल इसलिए कि सूची O(1) इंडेक्स द्वारा एक्सेस प्रदान करती है।

+2

एक निश्चित रूप से +1। जवाब संक्षेप में, सही है (परीक्षण नहीं किया गया है, लेकिन मैं जोखिम ले रहा हूं), बहुत चालाक, और सही ढंग से तर्क दिया कि यह रैखिक समय में क्यों चलता है। – Fede

+2

+1: यह बहुत ही सुरुचिपूर्ण है! – RedFilter

+9

कल्पना करें कि होमवर्क उत्तर के रूप में, फिर इसे कक्षा (और शिक्षक) को समझाएं ... mwahahaha –

2

कुछ इस तरह काम कर सकते हैं:

list.GroupBy (l => l).Where (l => l.Count() > 1).SelectMany (l => l).Distinct(); 

संपादित करें:

ऊपर कोड परिणाम ओ पी चाहता था नहीं मिलता है। :)

list.GroupBy(l => l).Select(g=>g.Skip(1)).SelectMany (l => l); 
7

यहाँ एक दृष्टिकोण है जो अपेक्षाकृत सरल है, केवल दोहराता एक बार अनुक्रम खत्म हो गया है, और किसी भी क्रम के साथ काम करता (न केवल सूचीबद्ध करता है): यहाँ एक संपादित संस्करण है कि नीचे Ani की सुरुचिपूर्ण समाधान से प्रेरणा लेकर किया जाता है:

public IEnumerable<T> FindConsecutiveDuplicates<T>(this IEnumerable<T> source) 
{ 
    using (var iterator = source.GetEnumerator()) 
    { 
     if (!iterator.MoveNext()) 
     { 
      yield break; 
     } 
     T current = iterator.Current; 
     while (iterator.MoveNext()) 
     { 
      if (EqualityComparer<T>.Default.Equals(current, iterator.Current)) 
      { 
       yield return current; 
      } 
      current = iterator.Current; 
     } 
    } 
} 

यहाँ एक और एक है जो इसे केवल एक LINQ क्वेरी है कि में भी सरल है, लेकिन यह कहाँ खंड है, जो बुरा है दुष्प्रभाव का उपयोग करता है:

IEnumerable<int> sequence = ...; 

bool first = true; 
int current = 0; 
var result = sequence.Where(x => { 
    bool result = !first && x == current; 
    current = x; 
    first = false; 
    return result; 
}); 

एक तीसरा विकल्प है, जो कुछ हद तक क्लीनर है, लेकिन एक SelectConsecutive तरीका है जिसके this answer से मूल रूप से SelectPairs है का उपयोग करता है, लेकिन नाम बदलकर थोड़ा साफ :)

IEnumerable<int> sequence = ...; 
IEnumerable<int> result = sequence.SelectConsecutive((x, y) => new { x, y }) 
            .Where(z => z.x == z.y); 
+2

आपका क्या मतलब है "दुष्प्रभाव का उपयोग करता है"? –

+2

मेरी आंखें खून बह रही हैं। –

+0

@Lasse: अच्छा बिंदु। उम, मैंने अपनी योजना बदल दी। रुको, और मैं साइड-इफेक्टिंग वर्जन बैक अप रखूंगा :) –

6

हर कोई यह कर के अच्छे तरीके खोजने की कोशिश कर किया जा रहा है, इसलिए यहां इसके बजाय वास्तव में एक बुरा तरीका है:

List<int> doubles = new List<int>(); 
Dictionary<int, bool> seenBefore = new Dictionary<int, bool>(); 

foreach(int i in list) 
{ 
    try 
    { 
     seenBefore.Add(i, true); 
    } 
    catch (ArgumentException) 
    { 
     doubles.Add(i); 
    } 
} 

return doubles; 

कृपया ऐसा मत करें।

+0

हाहा, हास्य की भावना के लिए +1। यह सभी –

+0

धन्यवाद के बाद शुक्रवार है। मुझे यकीन नहीं था कि क्या मुझे बुरा जवाब देने या वोट देने के लिए वोट-वोट मिलेगा क्योंकि यह बुरा था। :-) – teedyay

+0

+1 अपवाद के अलावा यह पूरी तरह से खराब गैर-लिंक उत्तर नहीं है - आप अपवाद से बचने के लिए ContainsKey या TryGetValue का उपयोग कर सकते हैं और यह ठीक होगा। –

0

यहाँ आप यकीनन सी # में जवाब के साथ जाना :)

int[] intarray = new int[] { 1, 1, 2, 3, 4, 4, 5, 7, 7, 7, 10 }; 

int previousnumber = -1; 
List<int> doubleDigits = new List<int>(); 
for (int i = 0; i < intarray.Length; i++) 
{ 
    if (previousnumber == -1) { previousnumber = intarray[i]; continue; } 
    if (intarray[i] == previousnumber) 
    { 
     if (!doubleDigits.Contains(intarray[i])) 
     { 
      doubleDigits.Add(intarray[i]); 
      //Console.WriteLine("Duplicate int found - " + intarray[i]); 
      continue; 
     } 
    } 
    else 
    { 
     previousnumber = intarray[i]; 
    } 
} 
0

एक उदाहरण है कि (शायद) LINQ का उपयोग की तुलना में बेहतर है, हालांकि प्रदर्शन करती है कम सुरुचिपूर्ण:

for (int i = 1; i < list.Count; i++) 
    if (list[i] == list[i - 1]) 
     doubles.Add(list[i]); 
0

आप ऐसा कर सकता है :

list.GroupBy(i => i).Where(g => g.Count() > 1).SelectMany(g => g.Skip(1)) 

यह, @ kjn के जवाब की तरह एक सा है, सिवाय इसके कि मैं यह व्यक्त करता है "युगल" और "दो युगल" लगता है कि खंड सवाल में थोड़ा बेहतर:

  1. समूह को एक साथ सभी पूर्णांकों
  2. केवल कि एक बार से अधिक दिखाई देते हैं उन में रुचि (g.Count() > 1)
  3. "युगल" का चपटा सूची का चयन करें, पहले के बाद उन जा रहा है (g.Skip(1))

पुनश्च: हम यहाँ मानते हैं, कि GroupBy पहली सूची को सॉर्ट नहीं करता है और यह करता है, तो वह उस तरह के नकारात्मक एक पूर्व अनुसार क्रमबद्ध सूची से प्रभावित नहीं है ...

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