2015-10-26 8 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]; 
    } 

谢谢所有帮助,我没有得到任何错误了。