Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C# HashSet을 활용해 세 개의 배열에서 공통 요소 찾기

개요

C#에서 여러 배열에 걸쳐 공통으로 존재하는 요소를 찾아야 할 때가 있습니다. 이 글에서는 세 개의 정수 배열을 HashSet으로 변환한 뒤, 세 개의 포인터를 이용해 공통 요소를 효율적으로 찾는 방법을 예제와 함께 알아봅니다.

1단계: 세 개의 배열 선언

먼저 비교할 세 개의 정수 배열을 준비합니다.

int[] arr1 = { 99, 57, 63, 98 };
int[] arr2 = { 43, 99, 33, 57 };
int[] arr3 = { 99, 57, 42 };

2단계: 배열을 HashSet으로 변환

각 배열을 HashSet에 담으면 중복된 값이 자동으로 제거되어 이후 비교 작업이 훨씬 단순해집니다.

// 첫 번째 HashSet
var h1 = new HashSet<int>(arr1);
// 두 번째 HashSet
var h2 = new HashSet<int>(arr2);
// 세 번째 HashSet
var h3 = new HashSet<int>(arr3);

전체 예제 코드

다음은 세 개의 배열에서 공통 요소를 찾아 출력하는 전체 코드입니다.

using System;
using System.Collections.Generic;
using System.Linq;

public class Program {
   public static void Main() {
      int[] arr1 = { 99, 57, 63, 98 };
      int[] arr2 = { 43, 99, 33, 57 };
      int[] arr3 = { 99, 57, 42 };

      // 첫 번째 HashSet
      var h1 = new HashSet<int>(arr1);
      // 두 번째 HashSet
      var h2 = new HashSet<int>(arr2);
      // 세 번째 HashSet
      var h3 = new HashSet<int>(arr3);

      // 첫 번째 집합 출력
      int[] val1 = h1.ToArray();
      Console.WriteLine("Set one...");
      foreach(int val in val1) {
         Console.WriteLine(val);
      }

      // 두 번째 집합 출력
      int[] val2 = h2.ToArray();
      Console.WriteLine("Set two...");
      foreach(int val in val2) {
         Console.WriteLine(val);
      }

      // 세 번째 집합 출력
      int[] val3 = h3.ToArray();
      Console.WriteLine("Set three...");
      foreach(int val in val3) {
         Console.WriteLine(val);
      }

      int i = 0, j = 0, k = 0;
      Console.WriteLine("Common elements...");
      while (i < val1.Length && j < val2.Length && k < val3.Length) {
         if (val1[i] == val2[j] && val2[j] == val3[k]) {
            Console.Write(val1[i] + " ");
            i++;
            j++;
            k++;
         }
         // x < y 인 경우
         else if (val1[i] < val2[j])
            i++;
         // y < z 인 경우
         else if (val2[j] < val3[k])
            j++;
         else
            k++;
      }
   }
}

실행 결과

Set one...
99
57
63
98
Set two...
43
99
33
57
Set three...
99
57
42
Common elements...
99 57

코드 동작 원리

세 개의 배열을 각각 HashSet으로 변환하면 중복이 제거됩니다. 이후 세 개의 인덱스(i, j, k)를 사용해 세 배열을 동시에 순회하며 다음 규칙으로 값을 비교합니다.

  • 세 값이 모두 같으면 공통 요소이므로 출력하고 세 인덱스를 모두 증가시킵니다.
  • val1의 값이 val2보다 작으면 i를 증가시켜 val1의 값을 앞당깁니다.
  • val2의 값이 val3보다 작으면 j를 증가시킵니다.
  • 그 외의 경우에는 k를 증가시킵니다.

이 방식은 한 번의 순회만으로 세 배열을 비교할 수 있어 매우 효율적입니다. 다만 HashSet은 저장 순서를 보장하지 않으므로, 안정적인 결과를 보장하려면 비교 전에 각 배열을 정렬(예: OrderBy)해 두는 것이 좋습니다.

더 간단한 방법: LINQ Intersect 활용

.NET의 LINQ를 사용하면 위 과정을 한 줄로 처리할 수도 있습니다.

var common = h1.Intersect(h2).Intersect(h3);
Console.WriteLine(string.Join(" ", common)); // 출력: 99 57

Intersect 메서드는 두 집합의 교집합을 반환하므로, 이를 연달아 적용하면 세 집합의 공통 요소를 손쉽게 구할 수 있습니다. 코드 가독성과 유지보수 측면에서 실무에서는 이 방식이 더 권장됩니다.