2012-01-04 55 views
1

我是新来的,对C#没有什么经验。我一直在搜索MSDN文档和谷歌,但无法找到答案(我尽量一般说尽可能):.NET C# - 阵列中不同阵列的数量

我想存储一个固定长度的有序序列的整数一个列表或数组,然后创建这些整数数组的数组。有谁知道我可以如何计算不同的整数数组的数量,以及我应该使用哪些特定的数据类型(列表,普通数组等)?我没有我一直在与确切的代码,但这里的相似,我一直在努力的东西:

int[] set1 = {2, 56, 8}; 
int[] set2 = {8, 25, 90}; 
int[] set3 = {2, 56, 8}; 

var superset = new List<int[]>; 
superset.Add(set1); 
superset.Add(set2); 
superset.Add(set3); 

Console.Out.WriteLine(superset.Distinct().Count()); // would like this to output 2, but Distinct() doesn't seem to actually work and I would get 3 
+1

你绝对需要使用整数数组吗?如果将固定长度的数组定制到自定义对象中,那么只需在该自定义类上实现'IEquatable(T)'并且'.Distinct()'将本地比较它。 – David 2012-01-04 20:05:28

+0

+1用于思考相同的方向。如果我们知道确切的问题是什么,这可能会容易得多。 – 2012-01-04 20:08:45

回答

-1

请记住一句名言:“聪明的数据结构和愚蠢的代码工作不是其他的方式要好很多”


-Eric雷蒙德,大教堂和市集

听起来这里的目标是能够使用简单和富有表现力的代码(.Distinct())来比较您的数据。在这种情况下,我建议从简单的数组升级到更丰富的对象。类似这样的:

class Numbers 
{ 
    public int FirstNumber { get; set; } 
    public int SecondNumber { get; set; } 
    public int ThirdNumber { get; set; } 
} 

然后你可以有一个这些对象的数组,而不是一个数组数组。这里的好处是你可以赋予这个对象更丰富的功能。如:

class Numbers : IEquatable<Numbers> 
{ 
    public int FirstNumber { get; set; } 
    public int SecondNumber { get; set; } 
    public int ThirdNumber { get; set; } 

    public bool Equals(Numbers other) 
    { 
    if (other == null) 
     return false; 
    return (
     this.FirstNumber == other.FirstNumber && 
     this.SecondNumber == other.SecondNumber && 
     this.ThirdNumber == other.ThirdNumber 
    ); 
    } 
} 

现在,您的智能数据类型可以通过dumber代码更有效地使用。 (只需引用引用,不要认为它是在编写愚蠢的代码或者任何没有帮助的东西)。这通常是首选,因为这意味着您不必重写多个比较逻辑如果它需要在多个地方使用的话。比较逻辑发生在数据类型的内部,而不是程序代码中。


注意,这是未经测试写意代码。如果我在执行过程中遗漏了某些东西,请更正我:)

+0

谢谢,先生!在我添加一个GetHashCode()方法后,这工作。我同意这句话 - 我承认我有一个大部分功能性的编程背景(C,汇编),并没有研究超出介绍性课程的算法和数据结构。非常感激! – user1130698 2012-01-04 21:00:31

+0

这个问题的答案如何? – Richard 2012-01-04 21:12:31

+1

发生了一个解决方案,首先用最小的努力来实现。其他答案似乎也是正确的,但David建议使用更丰富的数据类型而不是依赖程序代码是我的问题的一半(使用哪种数据类型)并且具有启发性。 – user1130698 2012-01-04 23:16:13

3

Distinct方法有一个重载需要的IEqualityComparer一个实例。为int数组创建一个IEqualityComparer实现(即public class IntArrayComparer : IEqualityComparer<int[]>),并将实例传递给Distinct调用。

SequenceEqual方法可能对执行IEqualityComparer<int[]>.Equals有一定的帮助,但该练习由您决定。

3

您只需要为整数数组创建一个Comparer类,并将其实例传递给Distinct方法。

Console.Out.WriteLine(superset.Distinct(new ArrayComparer()).Count()); 

下面是一个例子:

class ArrayComparer : IEqualityComparer<int[]> 
{ 
    public bool Equals(int[] x, int[] y) 
    { 
     //Check whether the compared objects reference the same data. 
     if (Object.ReferenceEquals(x, y)) return true; 

     //Check whether any of the compared objects is null. 
     if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) 
      return false; 

     if (x.Length != y.Length) 
      return false; 

     //Check whether the arrays' values are equal. 
     for(int i = 0; i < x.Length; i++){ 
      if(x[i] != y[i]) 
       return false; 
     } 

     // If got this far, arrays are equal 
     return true; 
    } 

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects. 

    public int GetHashCode(int[] intArray) 
    { 
     //Check whether the object is null 
     if (Object.ReferenceEquals(intArray, null)) return 0; 

     //Calculate the hash code for the array 
     int hashCode = 0; 
     bool isFirst = true; 
     foreach(int i in intArray){ 
      if(isFirst) { 
       hashCode = i; 
       isFirst = false; 
      } 
      else 
      { 
       hashCode = hashCode^i; 
      } 
     } 
     return hashCode; 
    } 
} 

这对我的作品。给出你想要的结果。

0

没有发布的答案解释了为什么Distinct().Count()返回3:原因是Distinct()正在使用数组的默认相等比较器,它比较参考相等性。此代码将返回2:

int[] set1 = {2, 56, 8}; 
int[] set2 = {8, 25, 90}; 
int[] set3 = set1; 

var superset = new List<int[]>(); 
superset.Add(set1); 
superset.Add(set2); 
superset.Add(set3); 

Console.WriteLine(superset.Distinct().Count()); 

由于鲍勃和理查德建议,你可以通过创建IEqualityComparer<int[]>的实现,将使你所期望的行为克服这一点。

0
private int CountDistinct2DPoints(double[][] data) 
    { 
     Dictionary<Tuple<double, double>, int> pointsMap = new Dictionary<Tuple<double, double>, int>(); 
     for(int i = 0; i < data.Length; i++) 
     { 
      if (!pointsMap.ContainsKey(Tuple.Create(data[i][0], data[i][1]))) 
      { 
       pointsMap.Add(Tuple.Create(data[i][0], data[i][1]), 1); 
      } 
      else 
      { 
       pointsMap[Tuple.Create(data[i][0], data[i][1])]++; 
      } 
     } 
     return pointsMap.Keys.Count; 
    } 
+0

这为我工作:) .........可以从2D扩展到更多的维度....虽然不知道效率! – 2015-04-23 18:18:42