2015-10-26 11 views
0

我想通過使用ArrayList創建自己的多線程mergesort算法。我在Java中熟悉這種方法,但試圖將它帶入C#並沒有按計劃運行。嘗試比較兩個ArrayList項目Error 1 Operator '<' cannot be applied to operands of type 'object' and 'object'時出現以下錯誤。我知道你不能直接比較這樣的兩個對象,在Java中你可以使用compareTo或類似的東西,是否有任何等效的C#?檢查ArrayList中的哪個項更小c#

這裏是導致錯誤的代碼,如果你需要的話,記住我從我的一個Java程序中使用整型數組複製了它。

int size = (last - first) + 1; 
ArrayList temp = new ArrayList();    
int mid = (first + last)/2; 
int i1 = 0; 
int i2 = first; 
int i3 = mid + 1; 
while(i2 <= mid && i3 <= last) 
{ 
    if(list[i2] < list[i3]) 
     temp[i1++] = list[i2++]; 
    else temp[i1++] = list[i3++]; 
} 

while(i2 <= mid) 
    temp[i1++] = list[i2++]; 

while(i3 <= last) 
    temp[i1++] = list[i3++]; 

i3 = first; 
for(i1 = 0; i1 < temp.Count; i1++, i3++) 
    list[i3] = temp[i1]; 
+4

這裏有一個提示:不要使用'ArrayList',使用類型列表,例如'List '。 – DavidG

+0

你的'list' var聲明在哪裏? –

+0

好的,我將如何去比較列表中的兩個項目? –

回答

0

你可以每個項目強制轉換爲IComparable或做一個as IComparable和檢查空(鑄造將拋出一個異常,如果對象實例沒有實現接口)。但@DavidG L建議可能的路要走。但是要對T進行約束,必須實現IComparable

+0

好吧,我會嘗試 –

1

我建議看看IComparer<T>界面。您可以創建MergeSort算法的一個版本,該算法採用IComparer<T>,該版本可用於比較要排序的對象。它可能會給你類似於你習慣的功能。

除了定義將類型限制爲IComparable<T>的MergeSort版本外,您還可以這樣做。這樣,在這兩個版本的函數之間,可以處理已經實現了接口的對象,並且還允許用戶爲未實現它的對象提供比較。

您可以像這樣在IList<T>接口上將合併排序設置爲Extension Method

public static class MergeSortExtension 
{ 
    public static IList<T> MergeSort<T>(this IList<T> list) where T : IComparable<T> 
    { 
     return list.MergeSort(Comparer<T>.Default); 
    } 

    public static IList<T> MergeSort<T>(this IList<T> list, IComparer<T> comparer) 
    { 
     // Sort code. 
    } 
} 
1

我覺得只是用INTS的排序列表。

var sl = new SortedList(); 
sl.Add(15, 15); 
sl.Add(443, 443); 
sl.Add(2, 2); 
sl.Add(934, 934); 
sl.Add(55, 55); 
foreach (var item in sl.Values) 
{ 
    Console.WriteLine(item); // Outputs 2, 15, 55, 443, 934 
} 

或者一個普通的List和調用Sort(更好的perf我認爲)。

var list = new List<int>(); 
list.Add(5); 
list.Add(1); 
list.Add(59); 
list.Add(4); 
list.Sort(); 
foreach (var element in list) 
{ 
    Console.WriteLine(element); // Outputs 1, 4, 5, 59 
} 
0

的問題是,ArrayList不是一個泛型集合,因此它允許調用僅object的任何項目的方法。您可以使用LINQ轉換爲普通IEnumerable<int>,那麼你將能夠呼籲int方式,包括比較和排序:

ArrayList al = new ArrayList(); 
al.Add(1); 
al.Add(2); 

IEnumerable<int> coll = al.Cast<int>(); 

if (coll.ElementAt(0) < coll.ElementAt(1)) 
// ... 

或:

var ordered = coll.OrderBy(n => n).ToList(); 

如果您ArrayList包含不同類型的對象,您應該使用OfType<int>來刪除int s,但正確的方法是使用類型集合,如List<int>而不是ArrayList

0

考慮您的所有建議考慮我想出了以下解決方案:

public static void merge(List<T> list , int first, int last) { 
    int size = (last - first) + 1; 
    List<T> temp = new List<T>(); 
    IEnumerable<IComparable> sorter = (IEnumerable<IComparable>)list; 
    int mid = (first + last)/2; 
    int i1 = 0; 
    int i2 = first; 
    int i3 = mid + 1; 
    while(i2 <= mid && i3 <= last) 
    { 
     if (sorter.ElementAt(i2).CompareTo(sorter.ElementAt(i3)) < 0) 
      temp[i1++] = list[i2++]; 
     else temp[i1++] = list[i3++]; 
     } 

     while(i2 <= mid) 
      temp[i1++] = list[i2++]; 

     while(i3 <= last) 
      temp[i1++] = list[i3++]; 

     i3 = first; 
     for(i1 = 0; i1 < temp.Count; i1++, i3++) 
      list[i3] = temp[i1]; 
    } 

謝謝所有幫助,我沒有得到任何錯誤了。