2017-01-08 2 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는 A 어레이 배열에 포함된다. 복잡하게 도와주세요.

+0

내 대답이 철회되었습니다. 'B '의 각 요소는'A'에서와 같이 최소한 ("B"에서) "다중성"을 가져야한다는 것이 맞습니까? 예를 들어'A = {2}'인 경우'B = {2, 2}'가 "좋은"부분 집합이 아니라는 것이 맞습니까? 왜'int'를 반환하고'bool'을 반환하는 대신'1'과'0'을 사용합니까? –

+0

첫 번째 루프의 경우 범위를 * A.Count-B.Count *로 제한하십시오. 최적화가 필요합니까 (예 : A와 B가 큰 경우)? – Graffito

답변

0

(두 번째 대답은, 내 첫 번째를 삭제.)

아마 다음과 같이 할 수 있습니다 각 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 
    } 
} 

을 우리가 일치하는 항목을 찾을 수 있는지 확인하기 위해 valuesA에 추가로 이동 , 또는 우리가 멀리왔다 (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; 
} 

합니다. 나는 그것에 대해 생각합니다, 시작 인덱스가 i이면, end index가 subarray임을 압니다. 길이 - 그 다음에 인덱스가 1이고, 물론 인덱스는 < array.Length가되어야합니다.

관련 문제