1

myArray{a,b,c}とのような2つの配列を集計しようとしていますurArray{a,b,c,c}

両方の要素に同じ要素があるかどうかを確認したかったのです。たとえば、上記の条件では、2 番目の配列にurArray余分な 'c' があります。

また、コードは、同じ要素を持っているかどうかに関係なく、要素の順序が重要でない場合、 2 つの配列セットを同等にできるはずです。両方の配列に同じ要素が必要です。つまり、一方に 2 つの「c」がある場合、もう一方にも 2 つの「c」が必要です。そうでない場合、条件は false になります。

だから私がしたことは:

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# コードです。基本的には、最も信頼性の高い並べ替え/比較シーケンス形式の実装です。このコードは、両方のシーケンスをソートし、同等性を比較します。myArray不必要な並べ替えを避けるために、最初にとurArrayが同じ長さであることを確認することで、わずかに最適化できます。

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

2 つの配列を並べ替えてから、要素を順番に比較できます。比較される 2 つの要素が異なる場合はいつでも、配列には異なる要素が含まれます。

于 2009-06-15T13:54:58.620 に答える
3

これは、私が抱えていたのと同じ問題のようです: 2 つのコレクションの等価性を比較する

于 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 に答える
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

配列に一意の要素しか含まれていない場合は、それらから 2 つの 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 に答える