2011-12-19 13 views
5

में एक तुलनात्मक कार्य कैसे करें कहें कि मेरे पास एक सूची में तत्व (एक्स, वाई, और जेड) हैं, मेरे पास एक फ़ंक्शन है, जो एक प्रतिशत उत्पन्न करता है, कितनी दो वस्तुएं एक-दूसरे के समान होती हैं।सी #

मैं आपकी क्या अपेक्षाएं हैं, वाई के खिलाफ एक्स और जेड चलाया जाता है मेरी compareElements का उपयोग कर, तो: एक्स और जेड

compareElements(Y,X); // equals 55 
compareElements(Y,Z); // equals 62 

तब के खिलाफ

compareElements(X,Y); // equals 55 
compareElements(X,Z); // equals 60 

फिर वाई वाई और एक्स

के खिलाफ जेड
compareElements(Z,X); // equals 60 
compareElements(Z,Y); // equals 62 

फिर, मैं सबसे अधिक मूल्य है, जो 62.

है वापसी

जाहिर है, वहां कुछ पुनरावृत्ति है, मुझे पुनरावृत्ति की आवश्यकता नहीं है, लेकिन मुझे यकीन नहीं है कि इसे कैसे खत्म किया जाए।

पुनरावृत्ति के बिना, प्रत्येक तत्व पर यह तुलना करने के लिए मैं अपनी LINQ क्वेरी, या फ़ंक्शन/एल्गोरिदम कैसे बना सकता हूं?

यदि मैं कर सकता हूं तो मैं LINQ का उपयोग करना पसंद करूंगा, क्योंकि मुझे एक गणित पारित किया जा रहा है और सूची वास्तव में गणना की जाने से पहले फ़ंक्शन रिटर्न है, इसलिए जब तक सूची की गणना नहीं की जाती है, हम तुलना करने की लागत को बचा सकते हैं । मेरी वास्तविक परिणाम सेट मैं इस सूची में 3 और 10 तत्वों के बीच औसत के साथ काम कर रहा हूँ, भाग गया है कि जरूरत:

सभी मैं की जरूरत है कि उच्चतम मूल्य तुलना कार्यों की, 62.

नोट है इस तुलना समारोह के माध्यम से।

+0

क्या आपके पास एक सूची > या समान है? या आपके पास एक्स, वाई, जेड आइटम कैसे व्यवस्थित हैं? –

+0

क्या आपको यह जानने की भी आवश्यकता है कि किस दो ऑब्जेक्ट का उच्चतम मूल्य हुआ? –

+0

यदि आप केवल उच्चतम तत्व चाहते हैं, तो आप केवल List.Sort() का उपयोग नहीं कर सकते हैं। अंतिम()? –

उत्तर

2

पठनीयता के कारण के लिए, मैं एक iterator ब्लॉक बारे में एक गैर दोहराए ढंग से तुलना उत्पन्न करने के लिए होगा:

IEnumerable<Tuple<T, T>> GetComparisons<T>(IEnumerable<T> elements) 
{ 
    var visited = new List<T>(); 

    foreach(T current in elements) 
    { 
     foreach(T previous in visited) 
      yield return new Tuple<T, T>(current, previous); 

     visited.Add(current); 
    } 
} 

तो आप निम्न कर सकते हैं:

var highScore = GetComparisons(listOfElements) 
        .Select(x=>compareElements(x.Item1, x.Item2) 
        .Max(); 

(यही कारण है कि ने कहा कि मैं उन स्थितियों के लिए स्मेल्च के सुझाव को प्राथमिकता देता हूं जहां LINQ या iterators का उपयोग करने के लिए कोई व्यावहारिक कारण नहीं है, जैसे कि कंपोज़ेबल दिनचर्या की आवश्यकता है।)

+0

आपका समाधान मेरे और क्लाइंट के लिए बहुत अच्छा काम कर रहा है! GetComparisons वास्तव में एक अच्छा विचार था! –

5

मुझे यकीन है कि मैं तुम्हें सही ढंग से समझ रहा हूँ नहीं कर रहा हूँ, लेकिन कुछ इस तरह का प्रयास करें:

public int compareElementList(List<Element> elements) 
    { 
     int result = 0; 
     for (int i = 0; i < elements.Count - 1; i++) 
     { 
      for (int q = i + 1; q < elements.Count; q++) 
      { 
       result = Math.Max(result, compareElements(elements[i], elements[q])); 
      } 
     } 

     return result; 
    } 

यह आपके लिए डुप्लिकेट तुलना समाप्त करेंगे। यह LINQ का उपयोग नहीं करता है, लेकिन मुझे लगता है कि यह अभी भी काफी पठनीय है।

अद्यतन: यहां मेरा संस्करण IENumerables को संभालने के लिए संशोधित किया गया है। यह जॉन हन्ना से भिन्न होता है जिसमें यह एक नई सूची नहीं बनाता है, यह सिर्फ दो पुनरावृत्तियों का ट्रैक रखता है।

public int compareElementEnumerable(IEnumerable<Element> elements) 
    { 
     int result = 0, i = 0, q = 1; 
     foreach (Element el in elements) 
     { 
      foreach (Element el2 in elements) 
      { 
       if (q > i) 
       { 
        result = Math.Max(result, compareElements(el, el2)); 
       } 
       q++; 
      } 
      i++; 
     } 

     return result; 
    } 
+0

सुंदर जगह पर लगता है। LINQ का एक उपकरण है, और यदि हथौड़ों के समूह के साथ किसी ने पूछा कि नाखूनों को चीजों में कैसे रखा जाए, तो कोई बात नहीं है कि ऐसा करने के लिए एक स्क्रूड्राइवर का उपयोग कैसे किया जाए, भले ही उन्होंने कहा कि वे एक का उपयोग करना चाहते हैं। –

+1

यह अधिक प्रदर्शन करने वाला भी हो सकता है। मुझे संदेह है कि LINQ का उपयोग करने वाली कोई भी विधि या तो कई तुलनाओं को डुप्लिकेट करेगी या बहुत से मध्यवर्ती वस्तुओं को उत्पन्न करेगी। –

+0

@ सेनयू समस्या यह है कि मुझे एक आईनेमरेबल पास किया जा रहा है, मुझे इसे किसी सूची या सरणी में पहले डालना होगा? क्या यह उतना महंगा नहीं होगा? –

2

आप संभव संयोजनों आप एक List<Tuple<int, int>> में परीक्षण और उसके बाद करना चाहते हैं की सूची बनाता सकता है अधिकतम

mylist.Select(i => new [] { Tuple.New(i.X, i.Y}, Tuple.New(i.X, i.Z), Tuple.New(i.Y, i.Z)}) 
     .Max(t => compareElements(t.First, t.Second)) 
+0

कि काम करता है, लेकिन मैं अभी भी पहली सूची संकलित करने के लिए है –

+0

अपने मॉडल है कि काम चाहेंगे? –

0

एक अपठनीय LINQ कार्यान्वयन का चयन करें (संकलन नहीं हो सकता है, मैं परीक्षण नहीं किया):

Enumerable.Range(0, listOfElements.Length).ToList().ForEach(i=>Enumerable.Range(i, listOfElements.Length-i-1).ToList().ForEach(j=>compareElements(listOfElements[i], listOfElements[j]))).Max(); 
2
अगर यह होता है कि आप क्या खोज रहे हैं

पता नहीं है, लेकिन मैं इस तरह से LINQ का उपयोग करने की कोशिश करेंगे:

012,
var linq = from el1 in list 
      from el2 in list 
      where el1 != el2 
      select CompareFunction(el1, el2); 

int max = linq.Max(); 

तुलना नमूना कार्यान्वयन:

int CompareFunction(string a, string b) 
{ 
    return a.Length - b.Length; 
} 

इस तरह आप सूची में अन्य तत्वों (यह परिवर्तन का एक तरह मुझे लगता है कि है) ही छोड़कर के खिलाफ प्रत्येक तत्व की तुलना करें, तो तुलना मान का चयन और अंत में उच्चतम मूल्य

+0

क्या वह अभी भी तुलना दोहराएगा? यदि सूची में आइटम 1, 2, 3 है; यह 1-2 की तुलना करेगा, फिर 1-3, फिर 2-1, 2-3, अंत में 3-1 और 3-2। 1-2 2-1 का डुप्लिकेट है, 1-3 3-1 और 2-3 का डुप्लिकेट 3-2 का डुप्लिकेट है। – comecme

+0

मैंने इसके बारे में सोचा, लेकिन यह समस्या का समाधान नहीं करता है कि यह डुप्लिकेट कोड चलाएगा। –

8

मैं ऐसा करने के इच्छुक हूं यह इस तरह है:

int count = list.Count; 
var query = from index1 in Enumerable.Range(0, count) 
      from index2 in Enumerable.Range(index1 + 1, count - (index1 + 1)) 
      select ComputeSimilarity(list[index1], list[index2]); 
var maxSimilarity = query.Max(); 
1
सुंदर ज्यादा

दिया एक जोड़ी के रूप में ही है, लेकिन पहले एक सूची के लिए आवंटित करने के लिए एक आवश्यकता नहीं है।

List<Element> soFar = new List<Element>(); 
// If I expected a good few duplicate values, and if 
// compareElements(x, x) isn't 100% - i.e. it's not a similarity 
// check for example, then I'd use HashSet<Element> and skip 
// when .Add() fails. 

int result = 0; 
foreach(Element el in sourceEnumeration) 
{ 
    for(int i = 0; i != soFar.Count; ++i) 
    { 
    int cmp = compareElements(el, soFar[i]); 
    if(cmp > result) 
    { 
     if(cmp == 100) 
     return 100; 
     cmp = result; 
    } 
    } 
    soFar.Add(el); 
} 
return result;