1

我正在尝试计算两个数组,例如myArray{a,b,c}urArray{a,b,c,c}

我想检查两个元素是否具有相同的元素,例如在上述条件下,第二个数组urArray有一个额外的 'c' 。

如果两组数组是否具有相同的元素并且元素的顺序无关紧要,代码应该能够等同于它们。只是两个数组应该有相同的元素,即如果一个有两个'c',另一个也应该有两个'c',否则条件为假。

所以我所做的是:

char[] myArray = new char[] {'a','b','c','c'};
char[] urArray = new char[] { 'a', 'b', 'c' ,'a'};
List<char> tmp2 = new List<char>(urArray);

for (int i = 0; i < myArray.Length; ++i)
{
    for (int j = 0; j < urArray.Length; ++j)
    {
        if (myArray[i] == urArray[j])
        {

            Console.WriteLine(urArray[j] + "--> " + "urArray"+"  myArray"+"--> "+myArray[i]);
            tmp2.Remove(urArray[j]);

            urArray = tmp2.ToArray();

        }
        else if (myArray[i] != urArray[j])
        {
            Console.WriteLine(myArray[i] + "--> " + "myArray" + "  urArray" + "--> " + urArray[j]);
        }
    }
}

但不知道如何表明数组是否具有相同的元素......

我怎样才能做到这一点?

4

9 回答 9

8

这是一些使用 linq 的 C# 代码应该可以完成这项工作,它基本上是排序/比较序列形式的实现——这是最可靠的。此代码将对两个序列进行排序并比较它们的等价性。您可以通过首先检查myArrayurArray的长度来稍微优化它,以避免不必要的排序。

char[] myArray = new char[] {'a','b','c','c'};
char[] urArray = new char[] { 'a', 'b', 'c' ,'a'};

var areEqual = myArray.OrderBy( x => x )
                      .SequenceEqual( urArray.OrderBy( x => x ) );

如果由于某种原因您不能(或不想)使用 linq,这里是使用 .NET 2.0 代码的等效版本:

public static bool AreEquivalentArray( char[] a, char[] b )
        {
            if (a.Length != b.Length)
                return false;

            Array.Sort(a);
            Array.Sort(b);
            for (int i = 0; i < a.Length; i++)
            {
                if( !a[i].Equals( b[i] ) )
                    return false;
            }
            return true;
        }
于 2009-06-15T14:46:27.780 回答
4

您可以对两个数组进行排序,然后按顺序比较元素。如果在任何时候被比较的两个元素不同,则数组包含不同的元素。

于 2009-06-15T13:54:58.620 回答
3

这似乎与我遇到的相同问题:Comparing Two Collections for Equality

于 2009-06-15T13:53:48.343 回答
2

我建议计算两个序列的直方图之间的差异。如果无法对序列进行排序或没有有效的方法来确定序列的长度,这甚至会起作用。

public static Boolean CompareCollections<T>(IEnumerable<T> a, IEnumerable<T> b)
{
    Dictionary<T, Int32> histogram = new Dictionary<T, Int32>();

    foreach (T item in a)
    {
        Int32 count;
        if (histogram.TryGetValue(item, out count))
        {
            histogram[item]++;
        }
        else
        {
            histogram[item] = 1;
        }
    }

    foreach (T item in b)
    {
        Int32 count;
        if (histogram.TryGetValue(item, out count))
        {
            if (count <= 0)
            {
                return false;
            }

            histogram[item]--;
        }
        else
        {
            return false;
        }
    }

    foreach (Int32 value in histogram.Values)
    {
        if (value != 0)
        {
            return false;
        }
    }

    return true;
}

如果可以得到序列的长度,检查字典中的所有值是否为零可以替换为检查相等的序列长度。

public static Boolean CompareCollections<T>(ICollection<T> a, ICollection<T> b)
{
    if (a.Count != b.Count)
    {
        return false;
    }

    Dictionary<T, Int32> histogram = new Dictionary<T, Int32>();

    foreach (T item in a)
    {
        Int32 count;
        if (histogram.TryGetValue(item, out count))
        {
            histogram[item]++;
        }
        else
        {
            histogram[item] = 1;
        }
    }

    foreach (T item in b)
    {
        Int32 count;
        if (histogram.TryGetValue(item, out count))
        {
            if (count <= 0)
            {
                return false;
            }

            histogram[item]--;
        }
        else
        {
            return false;
        }
    }

    return true;
}

这个解决方案是O(n)如果构建字典的成本可以忽略不计,而排序需要O(n*log(n))时间。

于 2009-06-15T14:26:20.307 回答
1

这是使用 LINQ 的单行代码:

bool same = !array1.Except (array2).Any() && !array2.Except (array1).Any();

或者,您可以在每个序列上调用 OrderBy 以按相同顺序对它们进行排序,然后使用 Enumerable.SequenceEqual 来比较它们:

bool same = Enumerable.SequenceEqual (array1.OrderBy (n => n), array2.OrderBy (n => n));
于 2009-06-15T14:44:24.790 回答
1
return myArray.OrderBy(c => c).SequenceEqual(urArray.OrderBy(c => c));
于 2009-06-19T12:16:21.813 回答
0

首先,您应该检查数组的长度是否相同。

如果是,那么我们需要对数组进行排序。

然后遍历两个数组并比较每个元素。

    char[] myArray = new char[] { 'a', 'b', 'c', 'c' };
    char[] urArray = new char[] { 'a', 'b', 'c', 'a' };


    if (myArray.Length.Equals(urArray.Length))
    {
        ///
        /// sort arrays
        ///

        System.Array.Sort(myArray);
        System.Array.Sort(urArray);

        for (int i = 0; i < myArray.Length; i++)
        {
            if (myArray[i] != urArray[i])
            {
                ///
                /// Arrays do not have same elements.
                ///
                break;

            }

        }
        ///
        /// if reach this code path the two arrays are equal.
        ///


    } else
    {
        ///
        /// Arrays not equal lenght
        ///

    }
于 2009-06-15T18:31:59.207 回答
0

如果您的数组仅包含唯一元素,我将从它们创建两个 HashSet,然后从另一个中减去一个以查看结果是否为空集。

于 2009-06-15T14:35:42.517 回答
0

如果您无法使用 LINQ,那么这应该可以解决问题:

char[] myArray = new char[] { 'a', 'b', 'c', 'c' };
char[] urArray = new char[] { 'a', 'b', 'c' ,'a' };

Console.WriteLine(AreEqual(myArray, urArray));    // False

// ...

public bool AreEqual<T>(IEnumerable<T> first, IEnumerable<T> second)
{
    Dictionary<T, int> map = new Dictionary<T, int>();

    foreach (T item in first)
    {
        if (map.ContainsKey(item))
            map[item]++;
        else
            map[item] = 1;
    }

    foreach (T item in second)
    {
        if (map.ContainsKey(item))
            map[item]--;
        else
            return false;
    }

    foreach (int i in map.Values)
    {
        if (i != 0)
            return false;
    }
    return true;
}
于 2009-06-15T15:41:26.400 回答