2017-01-08 9 views
1

したがって、配列に別の配列の要素が同じ順序で含まれているかどうかを確認する必要があります。両方の配列がソートされ、要素を複製することができます。配列が別の配列内にあるかどうかを確認しますが、順序は同じです。要素は同じです。

私はこのようなことを考え出しましたが、状況によってはあまりにも複雑です。例えば

public static int function(int[] A, int[] B) 
    { 
     int indexB = 0; 
     int matched = 0; 
     for(int j=0;j<A.Count();j++) 
     { 
      indexB=0; 
      matched=0;    
       for (int i = j; i < B.Count()+j; i++) 
       { 
        if (A[i] == B[indexB]) 
        { 
         matched++; 
         indexB++; 
        } 
        else 
        { 
         break; 
        } 
       } 
       if (matched == B.Count()) 
       { 
        return 1; 
       } 
     } 
     return 0; 
    } 

 int[] A = { 1, 2, 2, 2, 3, 4, 4, 4, 5, 8, 10 }; 
     int[] B = { 2, 2, 3, 4, 4, 4}; 

Bアレイは、アレイ内に含まれることになります。複雑さに私を助けてください。

+0

私の答えを撤回しました。 「B」の各要素は、「A」にあるように少なくとも(Bで)同じ多重度を持たなければならないのは正しいですか?たとえば 'A = {2}'ならば、 'B = {2,2} 'は「良い」サブセットではないということは正しいですか?なぜ 'int'を返し、' bool'を返す代わりに '1'と' 0'を使うのですか? –

+0

最初のループでは、範囲を* A.Count-B.Count *に制限します。最適化が必要ですか(たとえば、AとBが巨大な場合)? – Graffito

答えて

0

(第二答え、私の最初のものを削除した。)

たぶん、あなたはこのように行うことができます:我々は試合を見つけることができるかどうかを確認するためにvaluesAでさらに上を移動各bに対して

public static bool Function(IEnumerable<int> valuesA, IEnumerable<int> valuesB) 
{ 
    using (var enumA = valuesA.GetEnumerator()) 
    { 
    foreach (var b in valuesB) 
    { 
     while (true) 
     { 
     if (!enumA.MoveNext()) 
      return false; // ran out of A values 
     var a = enumA.Current; 
     if (a == b) 
      break; // match, go to next b 
     if (a > b) 
      return false; // not found 
     } 
    } 
    return true; // all b in valuesB accounted for 
    } 
} 

、または我々は遠くに来た(a > bは、これらの配列が昇順にソートされているという事実を利用しようとしている)!

テストされていません。

備考:配列よりも一般的なIEnumerable<>を使用してください。 .Count().ElementAt(index)を避けます。 Functionよりも良いメソッド名が必要です。

0

私はこれは少し単純だと思う:

public static int function(int[] A, int[] B) 
{ 
    int j = 0; 
    for (int i = 0; i < A.Length; i++) 
    { 
     if (A[i] == B[j]) 
     { 
      j++; 
     } 
     if (j == B.Length) 
     { 
      break; 
     } 
    } 
    return j == B.Length ? 1 : 0; 
} 
0

あなたはこのようなものを使用することができます:それは名前を私のためにそれが容易になっているため

public static bool ContainsSubarray(this int[] array, int[] subarray, bool areSorted = false) 
{ 
    if (subarray.Length == 0) 
     return true; 

    int start = Array.IndexOf(array, subarray[0]); 
    if (start < 0) 
     return false; 

    for (int i = start; i + subarray.Length - 1 < array.Length; ++i) 
    { 
     if (areSorted && array[i] != subarray[0]) 
      return false; 

     if (array.Skip(i).Take(subarray.Length).SequenceEqual(subarray)) 
      return true; 
    } 

    return false; 
} 

は、私はそれを拡張メソッドを作りました。 !=の使用は、>または<ではなく重要であることに注意してください。なぜなら、配列のソート方法の特定を避けるからです。 Array.BinarySearchは必ずしも最初に一致する要素を返すわけではないので、ソートされた場合にはより早く開始点を見つけるために使用することができませんでした。

しかし、あなたは単純に何かしたい場合:私は、ループ条件を構造化する方法に苦労し

public static bool ContainsSubarray(this int[] array, int[] subarray) 
{ 
    for (int i = 0; i + subarray.Length - 1 < array.Length; ++i) 
    { 
     if (array.Skip(i).Take(subarray.Length).SequenceEqual(subarray)) 
      return true; 
    } 

    return false; 
} 

を。私はそれが好きだと思う、開始インデックスが私なら、私は最後のインデックスがサブアレイであることを知っています。長さ - その後1インデックス、そしてもちろんエンドインデックスは< array.Lengthである必要があります。

関連する問題