원소나열법
A ={1,2,3,4,5}, B={2,4,6,8,10}
조건제시법
A = {A | A는 정수, 1≤ A ≤ 5},
B = {2B | B는 정수, 1≤ B ≤ 5}
벤 다이어그램
간단한 사용법
HashSet set1 = new HashSet();
set1.add(1);
set1.add(1);
set1.add(1);
System.out.println("set1 = " + set1); //HashSet은 중복 허용 x -> 1 만 출력
set1.add(2);
set1.add(3);
System.out.println("set1 = " + set1); // set1 = [1, 2, 3]
set1.remove(1); //인덱스가 아닌 해당 값 삭제
System.out.println("set1 = " + set1); // set1 = [2, 3]
System.out.println(set1.size()); // 2
System.out.println(set1.contains(2)); // true
HashSet을 이용한 여러가지 집합 구현
HashSet a = new HashSet(Arrays.asList(1, 2, 3, 4, 5));
HashSet b = new HashSet(Arrays.asList(2, 4, 6, 8, 10));
// 교집합
// 두 집합이 공통으로 포함하는 원소로 이루어진 집합
a.retainAll(b); // a = [2, 4]
// 합집합
// 어느 하나에라도 속하는 원소들을 모두 모은 집합
a.allAll(b); // a = [1, 2, 3, 4, 5, 6, 8, 10]
// 차집합
// A(or B)에만 속하는 원소들의 집합, A-B
a.removeAll(b); // a = [1, 3, 5]
// + 여집합
// 전체집합 중 A의 원소가 아닌 것들의 집합
class Myset {
//ArrayList
ArrayList<Integer> list;
//생성자1
MySet() {
this.list = new ArrayList<Integer>();
}
//생성자2
MySet(int[] arr) {
this.list = new ArrayList<Integer>();
for(int item: arr){
this.list.add(item);
}
}
// 원소 추가 (중복 X)
public void add(int x){
for(int item: this.list) {
if(item == x) {
return;
}
}
this.list.add(x);
}
// 교집합 (교집된 Set을 새로 반환)
public MySet retainAll(MySet b) {
MySet result = new MySet();
for(int itemA: this.list) {
for(int itemB: b.list) {
if (itemA == itemB) {
result.add(itemA);
}
}
}
return result;
}
// 합집합
public MySet addAll(MySet b) {
MySet result = new MySet();
for(int itemA: this.list) {
result.add(itemA);
}
for(int itemB: b.list) {
result.add(itemB);
}
return result;
}
// 차집합
public MySet removeAll(MySet b){
MySet result = new MySet();
for(int itemA: this.list) {
boolean containFlag = false;
for(int itemB: b.list) {
if(itemA == item) {
containFlag = true;
break;
}
}
if(!containFlag) {
result.add(itemA);
}
}
return result;
}
어떤 사건에서 일어날 수 있는 경우의 가짓수
기본 선언
int[] dice1 = {1, 2, 3, 4, 5, 6};
int[] dice2 = {1, 2, 3, 4, 5, 6};
int nA = 0;
int nB = 0;
int nAandB = 0;
: 사건 A 또는 사건 B가 일어날 경우의 수
=(사건 A가 일어날 경우) + (사건 B가 일어날 경우) - (사건A와 사건B의 교집합)
ex ) 두 개의 주사위를 던졌을 때 합이 3 또는 4의 배수일 경우의 수
// 기본 풀이
for(int item1: dice1){
for(int item2: dice2) {
if((item1+item2)% 3 == 0) {
nA +=1;
}
if((item1+item2)% 4 == 0) {
nB +=1;
}
if((item1+item2)% 12 == 0) {
nAandB +=1;
}
}
}
int result = nA + nB - nAandB // 20
// HashSet 이용
HashSet<ArrayList> allCase = new HashSet<>();
for(int item1: dice1) {
for(int item2: dice2) {
if((item1 + item2) % 3 == 0 || (item1+item2) % 4 == ){
ArrayList list = new ArrayList(Arrays.asList(item1,item2);
allCase.add(list); // 자동으로 중복 제거
}
}
}
allCase. size(); // 20
: 사건 A와 사건 B가 동시에 일어날 경우의 수
=(사건 A가 일어날 경우) * (사건 B가 일어날 경우)
ex) 두 개의 주사위 a,b를 던졌을 때 a는 3의 배수, b는 4의 배수인 경우의 수
for(int item1: dice1){
if(item1 % 3 == 0){
nA++;
}
}
for(int item1: dice2){
if(item1 % 4 == 0){
nB++;
}
}
int result = nA*nB; // 2
public ArrayList getDivisor(int num){
ArrayList result = new ArrayList();
for(int i =1;i<=(int)num/2; i++) { // 절반까지만 돌리는 이유는 절반이상이 되는순간 나누어 떨어지는 수가 없을것이기 때문에..
if(num%i==0) {
result.add(i);
}
}
result.add(num); // 자기 자신도 약수에 포함
return result;
}
‼️ 최소 공배수 = 각 값들의 곱에 최대공약수로 나눈 값
//최대 공약수
//GCD : the Greatest Common Denominator
public int getGCD(int numA, int numB) {
int gcd = -1;
ArrayList divisorA = this.getDivisor(numA); // A 약수
ArrayList divisorB = this.getDivisor(numB); // B 약수
for(int itemA : (ArrayList<Integer>divisorA) {
for(int itemB : (ArrayList<Integer>divisorB) {
if(itemA == itemB) {
if(itemA > gcd) {
gcd = itemA;
}
}
}
}
return gcd;
}
// 최소 공배수
// LCM : the Lowest Common Multiple
public int getLCM(int numA, int numB) {
int lcm = -1;
int gcd = this.getGCD(numA, numB); // 최대 공약수
if(gcd != -1) { // 예외적인 상황을 위해(최대 공약수가 없는 경우)
lcm = numA * numB / gcd;
}
return lcm;
}
: 1에서 n까지 모든 자연수의 곱 (n!)
// 5!
int n=5;
int result =1;
for(int i=1;i<= n;i++) {
result *= i;
}
: 순서를 정해서 서로 다른 n개의 중에 r개를 선택하는 경우의 수 (중복 x)
// 5명을 3줄로 세우는 경우의 수
n = 5;
int r = 3;
result =1;
for(int i=n; i >= n-r+1; i--) {
result *= i;
}
: 순서를 정해서 서로 다른 n개의 중에 r개를 선택하는 경우의 수 (중복 허용)
// 서로 다른 4개의 수 중에서 2개를 뽑는 경우의 수
n=4;
r=2;
result =1;
// 1. for문 사용
for(int i=0; i<r;i++) {
result *= n;
}
// 2. Math 클래스 사용
Math.pow(n,r);
: 원 모양의 테이블에 n개의 원소를 나열하는 경우의 수
// 원 모양의 테이블에 3명을 앉히는 경우의 수
n = 3
result = 1;
for(int i=1; i<n; i++) {
result *= i;
}
1, 2, 3, 4를 이용하여 세자리 자연수를 만드는 방법 (순서 0, 중복 X)의 각 결과를 출력
첫번째 방법
// 배열의 순서를 바꿔가며 앞의 3개의 숫자를 뽑아 세자리 자연수를 만드는 방법
// n은 배열의 개수
// r은 만드려는 자리수
// depth은 현재 자리수
void permutation(int[] arr, int depth, int n, int r){
//재귀함수 탈출 조건 -> 출력
if(depth == r){
for(int i =0;i<r;i++){
System.out.print(arr[i]) + " " );
}
System.out.println();
return;
}
for( int i= depth; i<n; i++) {
swap(arr, depth, i); // 자리를 바꿔줌
permutation(arr, depth+1, n, r); // 재귀함수
swap(arr, depth, i); // 다시 원래 자리로
}
}
// 자리를 바꿔주는 함수
void swap(int[] arr, int depth, int idx){
int tmp = arr[depth];
arr[depth] = arr[idx];
arr[idx] = tmp;
}
두번째 방법
void permutation(int[] arr, int depth, int n, int r, boolean[] visited, int[] out) {
//재귀함수 탈출 조건 -> 출력
if(depth == r){
System.out.println(Arrays.toString(out));
return;
}
for(int i= 0; i<n; i++) {
if(visited[i] != true) {
visited[i] = true;
out[depth] = arr[i];
permutation(arr, depth +1, n, r, visited, out);
visited[i] = false;
}
}
permutation
을 사용하여 특정한 조건이 맞는지 확인하고싶다면? → ArrayList를 매개변수로 추가하여 결과를 계속 저장한다.void permutation(int[] arr, int depth, int n, int r, boolean[] visited, int[] out, ArrayList<String> list) {
//재귀함수 탈출 조건
if(depth == r){
//System.out.println(Arrays.toString(out));
list.add(new String(out));
return;
}
for(int i= 0; i<n; i++) {
if(visited[i] != true) {
visited[i] = true;
out[depth] = arr[i];
permutation(arr, depth +1, n, r, visited, out);
visited[i] = false;
}
}
→ 저장된 list를 이용하여 검증// 타입이나 길이는 예시, 변경가능
boolean[] visited = new boolean[s.length()];
char[] out = new char[s.length()];
ArrayList<String> list = new ArrayList<>();
permutation(array,0,length, length, visited, out, list);
for(String s:list){
// 검증
}
서로 다른 n개 중에서 r개를 선택하는 경우의 수 (순서 X, 중복 X)
= n! / (n-r)!*r!
// 조합
// 서로 다른 4명 중 주번 2명 뽑는 경우의 수
int n=4;
int r=2;
int pResul=1;
for(int i=n; i>=n-r+1; i--) {
pResult *= i;
}
int rResul=1;
for(int i=1; i>=r; i++) {
rResult *= i;
}
int result = pResult/rResult;
서로 다른 n개 중에서 r개를 선택하는 경우의 수 (순서 X, 중복 0)
static int getCombination(int n, int r) {
int pResul=1;
for(int i=n; i>=n-r+1; i--) {
pResult *= i;
}
int rResul=1;
for(int i=1; i>=r; i++) {
rResult *= i;
}
return pResult/rResult;
}
// 중복조합 = getCombination(n+r-1, r));
1, 2, 3, 4를 이용하여 세자리 자연수를 만드는 방법 (순서 X, 중복 X)의 각 결과를 출력
void combination(int[] arr, boolean[] visited, int depth, int n, int r){
if(r == 0){
for(int i=0; i<n; i++) {
if(visited[i]) {
System.out.println(arr[i] + " ");
}
}
System.out.println();
return;
}
if(depth == n) {
return;
}
visited[depth] = true;
combination(arr, visited, depth +1, n, r-1);
visited[depth] = false;
combination(arr, visitied, depth +1, n, r);
}
// combination(arr, visited, 0, 4, 3);
: 어떤 수열의 일반항을 그 이전의 항들을 이용하여 정의한 식
ex) 피보나치 수열 → 1, 1, 2, 3, 5, 8, 13, …. F1 = F2 =1, F(N+2) = F(N+1) + F(N)
// 첫번째 문제
// 1, 3, 9, 27, ... 의 n번째 수
int n = 4;
int result = 1;
for(int i=0; i<n; i++){
if(i==0){
result =1;
}else{
result *= 3;
}
}
// 두번째 문제
//1, 2, 3, 4, 5, 6 의 n번째 까지의 합
int n = 5;
result = 0;
for(int i=0; i<n; i++){
result += i;
}
// 세번째 문제
// 피보나치 수열의 n번째 수
n = 6;
result = 0;
int a1 = 1;
int a2 = 1;
if(n < 3) {
result =1;
} else {
for(int i=2; i<n; i++){
result = a1+a2;
a1 = a2;
a2 = result;
}
}
: 어떤 함수가 자신을 다시 호출하여 작업을 수행하는 방식
// 첫번째 문제 재귀함수로 구현
static int recursion1(int n) {
if( n == 1){
return 1;
}
return 3 * recursion1(n-1);
}
// 두번째 문제 재귀함수로 구현
static int recursion2(int n) {
if( n == 1){
return 1;
}
return n + recursion2(n-1);
}
// 세번째 문제 재귀함수로 구현
static int recursion3(int n) {
if(n < 3){
return 1;
}
return recursion3(n-2) + recursion3(n-1);
}
static int factorial(int n) {
if(n == 1){
return 1;
}
return n * factorial(n-1);
}
static int gcd(int a, int b) {
if(a%b==0){
return b;
}
return gcd(b, a%b);
}
// 1. 제곱, 제곱근, 지수
System.out.println(Math.pow(2,3)); // 8
System.out.println(Math.pow(2, -3)); // 1/8 = 0.125
System.out.println(Math.pow(-2, -3)); // -1/8 = -0.125
System.out.print(Math.pow(2,30)); // 1.073741824E9
System.out.print("%.0f\n", Math.pow(2,30)); // 1073741824
// 2. 제곱근
System.out.print(Math.sqrt(16)); //4
System.out.print(Math.pow(16, 1.0/2)); //4
System.out.print(Math.pow(16, 1.0/4)); //2
// + 절대 값
System.out.print(Math.abs(5)); //5
System.out.print(Math.abs(-5)); //5
// 3. 로그
System.out.print(Math.E); // 2.718281828459045
System.out.print(Math.log(2.718281828459045)); //1.0
System.out.print(Math.log10(1000)); //3.0
System.out.print(Math.log(4)/Math.log(2)); //2.0