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

C++로 숫자 또는 문자 집합에서 무작위 파티션(분할) 생성하기

이 글에서는 주어진 정수 배열 또는 문자열을 입력받아, 이를 무작위(random) 파티션, 즉 크기가 제각각인 여러 그룹으로 나누어 출력하는 C++ 프로그램을 소개합니다.

파티션(partition)이란 전체 집합을 서로 겹치지 않는 부분 집합들로 나눈 것을 의미합니다. 이 프로그램은 rand() 함수를 활용해 각 파티션의 크기를 무작위로 결정하고, 원소들을 순서대로 그룹에 배정하는 방식으로 동작합니다.

알고리즘

프로그램의 전체적인 흐름은 다음과 같습니다.

시작
    정수 또는 문자를 입력받는다.
    선택지가 1일 경우 (정수 배열):
        n개의 정수 배열을 입력받는다.
        l = 0으로 초기화하여 배열을 순회할 인덱스로 사용한다.
        rand() 함수를 이용해 n에 대한 무작위 정수 파티션을 생성한다.
        각 파티션 i마다 인덱스 l부터 다음 i개의 정수를 출력한다.
    선택지가 2일 경우 (문자열):
        문자열을 ch[] 배열에 입력받는다.
        strlen()으로 문자열 길이를 구하고, l을 0으로 초기화한다.
        문자열 길이에 대한 무작위 정수 파티션을 생성한다.
        각 파티션 i마다 인덱스 l부터 다음 i개의 문자를 출력한다.
끝

예제 코드

사용자가 1을 입력하면 정수 배열을, 2를 입력하면 문자열을 대상으로 무작위 파티션을 생성합니다.

#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
int main() {
    int n, i, j, l, c;
    cout<<"정수 배열은 1, 문자열은 2를 입력하세요: ";
    cin>>c;
    // 선택지가 1인 경우:
    if(c== 1) {
        cout<<"\n정수 배열의 원소 개수를 입력하세요: ";
        cin>>n;
        int a[n];
        cout<<"\n배열의 원소를 입력하세요:\n";
        for(i = 0; i < n; i++) {
            cout<<i+1<<"번째 원소: ";
            cin>>a[i];
        }
        cout<<"\n주어진 배열의 무작위 파티션 결과:\n";
        l = 0;
        while(n > 0) {
            cout<<"\t[";
            i = rand()%n + 1;
            n = n-i;
            for(j = 0; j < i; j++) {
                cout<<a[l]<<" ";
                l++;
            }
            cout<<"]";
        }
    }
    // 선택지가 2인 경우:
    else {
        char ch[100];
        cout<<"문자열을 입력하세요: ";
        cin>>ch;
        n = strlen(ch);
        cout<<"\n주어진 문자열의 무작위 파티션 결과:\n";
        l = 0; // 배열을 순회하기 위해 l을 0으로 초기화
        while(n > 0) {
            cout<<"\t[ ";
            i = rand()%n + 1;
            n = n-i;
            for(j = 0; j < i; j++) {
                cout<<ch[l]<<" ";
                l++;
            }
            cout<<"]";
        }
    }
    return 0;
}

핵심 로직 설명

무작위 파티션의 핵심은 i = rand()%n + 1; 부분입니다. 현재 남은 원소 개수 n으로 난수를 나눈 나머지에 1을 더하면, 1부터 n 사이의 값이 생성됩니다. 이 값이 첫 번째 그룹의 크기가 되고, n = n - i;를 통해 남은 원소 개수를 줄여가며 같은 과정을 반복합니다. 이렇게 하면 모든 원소가 정확히 한 번씩 어떤 그룹에도 속하게 됩니다.

참고로 rand()만 사용하면 프로그램을 실행할 때마다 같은 결과가 나올 수 있습니다. 실행할 때마다 다른 분할 결과를 얻으려면 srand(time(NULL)); 코드를 main() 함수 시작 부분에 추가하는 것이 좋습니다.

실행 결과 1 — 정수 배열

정수 배열은 1, 문자열은 2를 입력하세요: 1
정수 배열의 원소 개수를 입력하세요: 10
배열의 원소를 입력하세요:
1번째 원소: 10
2번째 원소: 9
3번째 원소: 8
4번째 원소: 7
5번째 원소: 6
6번째 원소: 5
7번째 원소: 4
8번째 원소: 3
9번째 원소: 2
10번째 원소: 1
주어진 배열의 무작위 파티션 결과:
[10 9 ] [8 7 6 5 ] [4 3 2 ] [1 ]

총 10개의 원소가 크기 2, 4, 3, 1의 네 그룹으로 무작위하게 나뉘었습니다.

실행 결과 2 — 문자열

정수 배열은 1, 문자열은 2를 입력하세요: 2
문자열을 입력하세요: ABCDEFGHIJKLMNOPQRSTUVWXYZ
주어진 문자열의 무작위 파티션 결과:
[ A B C D E F G H I J K L M N O P ] [ Q R S T U V W X ] [ Y ] [ Z ]

26개의 알파벳 문자가 크기 16, 8, 1, 1의 네 그룹으로 분할된 것을 확인할 수 있습니다.

마무리

이 프로그램은 하나의 while 루프와 rand() 연산만으로 집합을 무작위 크기의 그룹으로 나누는 간단하면서도 실용적인 기법을 보여줍니다. 데이터 샘플링, 그룹 배정 시뮬레이션, 테스트 케이스 생성 등 다양한 상황에 응용할 수 있습니다.