자바 코드 관련하여 질문드립니다

조회수 285회
import java.util.Arrays;

public class hellojava {
  public static void main(String[] args) {
    int[] arr1 = new int[7];

    int sum=0,sum1=0, sum2 = 0;
    int a, b, c, d, e, f, g;  
    int i,j;
    int count = 0;  

    for (a = 1; a < 8; a++) {
      arr1[0] = a;
      for (b = 1; b < 8; b++) {

        arr1[1] = b;
        for (c = 1; c < 8; c++) {
          arr1[2] = c;
          for (d = 1; d < 8; d++) {
            arr1[3] = d;
            for (e = 1; e < 8; e++) {
              arr1[4] = e;
              for (f = 1; f < 8; f++) {
                arr1[5] = f;
                for (g = 1; g < 8; g++) {

                  arr1[6] = g;
                  sum = arr1[2] + arr1[1] + arr1[0] + arr1[3];
                  sum1 = arr1[1] + arr1[0] + arr1[4] + arr1[5];
                  sum2 = arr1[0] + arr1[3] + arr1[5] + arr1[6];

                  if (sum == sum1 && sum == sum2 && sum2 == sum1)
                    count += 1;
                }
              }
            }
          }
        }
      }
    }
    System.out.println(count);
  }
}

배열에 중복없이 1~7 까지의 숫자를 넣고 4개씩뽑아서 그합이 3군데 맞는 경우의 수를 찾고싶은데 중복을 어떻게 잡아야할줄 모르겠습니다 자바 1.8 버전입니다

  • 중복없는 부분집합 구하기를 검색해 보세요 송치원 2023.1.4 15:22

1 답변

  • 몇 가지 방법이 있는데, 아마 if (g == a || g == b || g == c || g == d || g == e || g == f) 같은 걸 짜고 싶지는 않으실 것 같습니다.

    코드를 최소한으로 수정하고 구현하는 방법은, boolean[] used = new boolean[8] 같은 배열을 만들고 for-루프 안에서 어떤 수를 사용했는지 아닌지를 체크하는 것이겠습니다.

    boolean[] used = new boolean[8];
    
    for (a = 1; a < 8; a++) {
      arr1[0] = a, used[a] = true; // a가 사용되었다고 체크
      for (b = 1; b < 8; b++) {
        if (used[b]) continue; // b가 이미 사용된 적 있다면 스킵
        arr1[1] = b, used[b] = true; // b가 사용되었다고 체크
        for (c = 1; c < 8; c++) {
          if (used[c]) continue; // c가 이미 사용된 적 있다면 스킵
          arr1[2] = c, used[c] = true; // c가 사용되었다고 체크
          for (d = 1; d < 8; d++) {
            // ...
          }
          used[c] = false; // c의 사용 상태가 누적되면 안 되므로, c의 사용 상태를 해제
        }
        used[b] = false; // b의 사용 상태를 해제
      }
      used[a] = false; // a의 사용 상태를 해제
    }
    
    

    더 나아가서, 7중 for-루프가 뭔가 아닌 거 같다는 생각이 들 수 있습니다. 혹은 이 문제를 더 많은 수들에 대해 해결하도록 확장해야 할 수 있습니다. 그럴 때 사용하는 방법론으로 재귀를 응용한 백트래킹이 있습니다. 링크에서 소개하는 연습 문제 1이 제시하신 문제와 비슷하니 확인해 보시면 좋을 것 같습니다.

    이 문제를 백트래킹으로 다시 구현하면 아래와 같이 됩니다.

    public class hellojava {
        // 경우의 수
        public static int count = 0;
    
        // i번째 수가 arr 안에 있나요? 그렇다면 true, 아니면 false
        public static boolean[] used = new boolean[8];
    
        public static int[] arr = new int[7];
    
        // index: arr의 몇 번째 인덱스를 채울 것인지
        public static void backtrack(int index) {
            // index == 7이라면, 즉,arr가 전부 채워졌다면 조건 체크
            if (index == 7) {
                int sum = arr[2] + arr[1] + arr[0] + arr[3];
                int sum1 = arr[1] + arr[0] + arr[4] + arr[5];
                int sum2 = arr[0] + arr[3] + arr[5] + arr[6];
    
                if (sum == sum1 && sum == sum2) {
                    // (sum == sum1 && sum == sum2)이면 (sum2 == sum1)이므로, (sum2 == sum1) 조건은 필요 없음
                    count += 1;
                }
    
                return;
            }
    
            // 아니라면, arr의 현재 인덱스에 수를 채워 줘야 한다
            for (int x = 0; x < 8; x++) {
                // 이미 arr 안에 x가 들어 있다면 무시한다
                if (used[x]) continue;
                // arr 안에 x가 있다고 표시한다
                used[x] = true;
                // index번째 인덱스에 수를 넣었으니 다음 인덱스를 보자
                backtrack(index + 1);
                // 다른 경우를 보기 위해 arr 안에 x가 있음을 표시한 것을 다시 해제한다
                used[x] = false;
            }
        }
    
        public static void main(String[] args) {
            backtrack(0);
            System.out.println(count);
        }
    }
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)