Stack

 

스택은 후입선출 구조를 가지는 자료구조이다.

출력 시 가장 위에서부터 아래로, 내림차순으로 출력된다.

 

스택은 top으로 정한 곳을 통해서만 접근 가능하다.

top의 가장 위에 있는 자료는 가장 최근 들어온 자료이며

 

삽입되는 새 자료는 top이 가리키는 자료의 위에 쌓이게 된다.

스택에서 자료를 삭제할 때 top을 통해서 가능하다.

스택에서 top을 통해 삽입하는 연산을 push, 삭제하는 연산을 pop이라고 한다.

 

따라서 가장 마지막에 삽입된 자료가 가장 먼저 삭제된다.

import java.util.Stack;

public class StackExample {
    public static void main(String[] args) {
        // 정수형 데이터를 담을 스택 생성
        Stack<Integer> stack = new Stack<>();

        // 스택에 데이터 추가 (push)
        stack.push(10);
        stack.push(20);
        stack.push(30);

        // 스택의 맨 위 데이터 확인 (peek)
        System.out.println("Top element: " + stack.peek());

        // 스택에서 데이터 제거 및 출력 (pop)
        while (!stack.isEmpty()) {
            System.out.println("Popped element: " + stack.pop());
        }
    }
}
push(E item) 스택에 데이터를 추가한다. 새로운 데이터는 항상 스택의 맨 위에 추가된다
pop() 스택의 맨 위에서 데이터를 제거하고 반환한다
peek() 스택의 맨 위에 있는 데이터를 반환하지만 제거는 하지 않는다
Empty() 스택이 비어있는지의 여부를 판단한다
search(Object o) 스택에서 특정 객체의 위치(인덱스)를 찾아 반환한다. 맨 위가 첫번째다.

 

활용 예시

  • 웹 브라우저 방문기록: 가장 최근에 열린 페이지부터 보여준다
  • 역순 문자열 만들기: 가장 최근에 입력된 문자부터 출력한다
  • 실행 취소: 가장 최근에 실행된 것부터 실행을 취소한다
  • 후위 표기법 계산
  • 수식의 괄호 검사 (연산자 우선순위 표현을 위한 괄호 검사) 

Queue

 

한쪽 끝에서는 삽입, 다른 쪽에서는 삭제 작업이 양쪽으로 이루어지는

선입선출 구조를 가지는 자료구조이다. 

 

스택은 삽입삭제가 한쪽으로 이루어진다면 큐는 한쪽에서는 삽입, 다른 쪽에서는 삭제 작업이

이루어진다.

 

이때 삭제연산만 수행되는 곳을 프론트, 삽입연산만 이루어지는 곳을 리어로 정하여 각각의

연산작업만 수행된다.

 

이때, 리어에서 수행되는 삽입연산을 인큐

프론트에서 이루어지는 삭제연산을 디큐라고 부른다.

 

활용 예시

  • 데이터가 입력된 시간 순서대로 처리해야할 필요가 있는 상황에 이용한다.
  • 우선순위가 같은 작업 예약 ex) 프린터의 인쇄 대기열
  • 은행 업무
  • 콜센터 고객 대기시간
  • 프로세스 관리
  • 너비 우선 탐색(BFS, Breadth-First Search) 구현
  • 캐시 구현
import java.util.LinkedList;
import java.util.Queue;

public class QueueExample {
    public static void main(String[] args) {
        // 정수형 데이터를 담을 큐 생성
        Queue<Integer> queue = new LinkedList<>();

        // 큐에 데이터 추가 (offer)
        queue.offer(10);
        queue.offer(20);
        queue.offer(30);

        // 큐의 맨 앞 데이터 확인 (peek)
        System.out.println("Front element: " + queue.peek());

        // 큐에서 데이터 제거 및 출력 (poll)
        while (!queue.isEmpty()) {
            System.out.println("Polled element: " + queue.poll());
        }
    }
}
offer(E e) 큐에 데이터 추가
poll() 큐의 맨 앞에서 데이터를 제거하고 반환
peek() 큐의 맨 앞에 있는 데이터를 반환하지만 
isEmpty() 큐가 비어있는지의 여부 판단
size()  큐에 저장된 데이터의 개수 반환

List

 

여러 요소들을 순서대로 저장하는 자료구조인데 순서가 있고, 중복을 허용한다는 특징이 있다.

스택, 큐 또한 크게 본다면 리스트라 할 수 있다.

 

순차 리스트는 배열로 구현한 리스트로서 구현이 쉽고 속도가 빠르다.

하지만 배열 특성상 동적으로 크기를 줄이기 어렵다.

 

Singly LinkedList

  • 각 노드가 데이터와 다음 노드를 가리키는 포인터로 이루어져 있다.
  • 마지막 노드는 다음 노드를 가리키는 포인터가 null 혹은 nil이다
  • 데이터의 추가와 삭제가 다른 자료구조에 비해 비교적 쉽다

Doubly LinkedList

  • 각 노드가 데이터와 이전 노드와 다음 노드를 가리키는 포인터로 이루어져있다.
  • 이전 노드와 다음 노드를 모두 쉽게 접근할 수 있어 데이터의 삽입, 삭제, 검색이 용이하다
  • 각 노드가 많은 메모리를 사용한다.
// LinkedList의 노드를 나타내는 클래스
class ListNode {
    int val;        // 노드가 저장하는 데이터
    ListNode next;  // 다음 노드를 가리키는 포인터

    // 생성자
    ListNode(int val) {
        this.val = val;
        this.next = null;
    }
}

// LinkedList 자료구조를 나타내는 클래스
class MyLinkedList {
    ListNode head;  // 첫 번째 노드를 가리키는 포인터

    // 생성자: 빈 LinkedList 생성
    public MyLinkedList() {
        this.head = null;
    }
    
    // 맨 앞에 노드 삽입
    public void addAtHead(int val) {
        ListNode newNode = new ListNode(val);
        newNode.next = head;
        head = newNode;
    }
    
    // 특정 위치 뒤에 노드 삽입
    public void addAtIndex(int index, int val) {
        if (index < 0) {
            addAtHead(val);
            return;
        }
        
        ListNode newNode = new ListNode(val);
        ListNode current = head;
        int count = 0;
        
        while (current != null && count < index - 1) {
            current = current.next;
            count++;
        }
        
        if (current == null) {
            return;
        }
        
        newNode.next = current.next;
        current.next = newNode;
    }
    
    // 맨 뒤에 노드 삽입
    public void addAtTail(int val) {
        ListNode newNode = new ListNode(val);
        if (head == null) {
            head = newNode;
            return;
        }
        
        ListNode current = head;
        while (current.next != null) {
            current = current.next;
        }
        
        current.next = newNode;
    }
    
    // 특정 위치의 노드 삭제
    public void deleteAtIndex(int index) {
        if (index < 0 || head == null) {
            return;
        }
        
        if (index == 0) {
            head = head.next;
            return;
        }
        
        ListNode current = head;
        int count = 0;
        
        while (current != null && count < index - 1) {
            current = current.next;
            count++;
        }
        
        if (current == null || current.next == null) {
            return;
        }
        
        current.next = current.next.next;
    }
    
    // LinkedList 출력
    public void printList() {
        ListNode current = head;
        while (current != null) {
            System.out.print(current.val + " ");
            current = current.next;
        }
        System.out.println();
    }
}

// LinkedList 사용 예시
public class Main {
    public static void main(String[] args) {
        MyLinkedList linkedList = new MyLinkedList();
        
        linkedList.addAtHead(1);
        linkedList.addAtTail(3);
        linkedList.addAtIndex(1, 2);   // 1 -> 2 -> 3
        
        linkedList.printList();  // 출력: 1 2 3
        
        linkedList.deleteAtIndex(1);   // 1 -> 3
        linkedList.printList();  // 출력: 1 3
    }
}
add(E element) 리스트에 요소 추가
get(int index) 리스트에 지정된 인덱스 반환
set(int index, E element) 리스트에 지정된 인덱스 요소 설정
remove(int index) 리스트에 지정된 인덱스 요소 제거
size() 리스트에 저장된 요소의 개수 반환
isEmpty() 리스트가 비어있는지의 여부
contains(Object o) 특정 객체가 포함되어있는지의 여부
indexOf(Object o) 특정 객체의 인덱스 반환. 없으면 -1을 반환한다
clear() 리스트의 모든 요소 제거

 

스택, 큐, 리스트

자료구조 공통점 차이
리스트(List) 선형 자료구조, 순서가 있음 읽기, 삽입, 삭제를 리스트 어느 곳에서나 가능
스택(Stack) 삽입과 삭제를 리스트의 한쪽(top)에서 행함
큐(Queue) 삽입은 리스트의 레어에서 하고, 삭제는 삽입의 반대쪽 front 에서 행함

 

'자료구조 > 알고리즘 기초수학' 카테고리의 다른 글

StringBuilder와 StringTokenizer 비교  (0) 2024.07.18
Hash Table / Deque  (5) 2024.07.16
이항계수, 동적계획법  (0) 2024.07.06
유클리드 호제법  (0) 2024.07.04
에라토스테네스의 체  (1) 2024.07.02

이항계수.. 고등학교 수학에서도 어려웠는데

백준 문제에서 나왔을때 뜨억!! 하고 놀랐다

 

굳어버린 머리를 일깨워서 다시 정리해보면

이항정리가 어려웠던 것 같기도 하고..? ..??

아무튼 이항계수는 집합에서 원소를 선택하는 경우의 수이다. 

이항계수는 다음과 같은 특징을 가진다.

  • 순서가 중요하지 않음
  • 중복 선택 불가
  • 팩토리얼을 이용하여 계산

 

 

프로그래밍 사용 예시

확률 계산 사건이 일어날 확률 계산 ex) 주사위를 던져 3번 이상 5가 나올 확률 계산
통계 분석 특정 조건을 만족하는 데이터 선택, 가능한 조합의 수 계산
동적계획법 중복 계산을 피하기 위해 이항 계수를 미리 사용하여 값을 미리 계산한다

 

동적계획법

복잡한 문제를 간단한 하위 문제로 나누어 풀고 그 결과를 저장해 동일한 하위문제에 재활용하는 알고리즘 설계 기법이다.

최적화 문제나 최단 경로 문제를 푸는데 사용된다.

 

주요 특징

1. 메모이제이션

계산한 결과를 배열이나 다른 자료구조에 저장에 두었다가 필요할 때 가져와 사용한다. 

이를 통해 중복 계산을 피하고 실행 시간을 단축시킨다.

 

2. 최적 부분 구조

큰 문제의 최적해를 그 하위 문제들의 최적해를 합친 것으로 구성한다. 이 식이 충족될 때 까지

동적 계획법을 적용시킨다.

 

3. 점화식

문제를 작은 하위 문제로 분할하고 하위 문제들 간의 관계를 수식으로 표현한다.

동적 계획법에서는 점화식을 사용하여 문제를 해결한다.

 

자바 코드 예시

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BinomialCoefficientExample {

    // 정수 n의 팩토리얼 계산 함수
    public static long factorial(int n) {
        if (n == 0 || n == 1) {
            return 1; // 0 또는 1의 팩토리얼은 1이므로 바로 반환
        }
        long result = 1;
        for (int i = 2; i <= n; i++) {
            result *= i; // 2부터 n까지의 곱을 계산하여 팩토리얼 구함
        }
        return result; // 결과 반환
    }

    // 이항 계수 계산 함수
    public static long binomialCoefficient(int n, int k) {
        if (k < 0 || k > n) {
            return 0; // k가 범위를 벗어나면 계산 불가능하므로 0 반환
        }
        // n! / (k! * (n-k)!)
        long numerator = factorial(n); // 분자 계산: n!
        long denominator = factorial(k) * factorial(n - k); // 분모 계산: k! * (n-k)!
        return numerator / denominator; // 이항 계수 반환
    }

    public static void main(String[] args) throws IOException {
        // BufferedReader를 사용하여 입력을 받음
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        //n과 k를 입력받음
        int n = Integer.parseInt(br.readLine());
        int k = Integer.parseInt(br.readLine());

        // 이항 계수 계산
        long result = binomialCoefficient(n, k);
        
        System.out.println(result);
        br.close();
    }
}

'자료구조 > 알고리즘 기초수학' 카테고리의 다른 글

Hash Table / Deque  (5) 2024.07.16
선형 자료구조 스택, 큐, 리스트  (0) 2024.07.08
유클리드 호제법  (0) 2024.07.04
에라토스테네스의 체  (1) 2024.07.02
알고리즘 / 문자열  (1) 2024.07.01

유클리드 호제법은 두 수의 최대공약수를 빠르게 구하는 알고리즘이다.

최대공약수(GCD)  로 나눈 몫을 𝑄라 하고, 나머지를 𝑅이라 할때, 이다.
최소공배수(LCM) A와 B라는 다른 수가 주어졌을때, 주어진 두 개의 수를 곱한 값을 GCD로 나눈 값이다.

 

조금 머리가 아프다...

수능에는 안 나오지만 컴퓨터 공학를 이용한 계산에 쓰이는 정수론에 가장 많이 쓰인다고 한다.

자세한 글과 증명법은 https://dimenchoi.tistory.com/46 을 참고하면 좋다.

 

중학수학에서 두 수 사이의 최대공약수는 소인수분해를 한 후

그 소인수들의 곱으로 구할 수 있었지만

효율적인 방법은 아니다.

 

왜냐하면 우선 소인수분해를 위해 소수를 먼저 찾아야 하고

찾은 소수가 두 개의 수를 나눌 수 있는지 확인을 하는 절차를 거쳐야 하기 때문에

수가 크면 계산이 복잡해지는 단점이 있기 때문에 이를 보완하기 위해 나온 방법이다.

 

자바 코드로 살펴보겠다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class LCMCalculator {

       public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 사용자로부터 첫 번째 정수 입력 받기
        System.out.print("첫 번째 정수를 입력하세요: ");
        int a = Integer.parseInt(br.readLine());

        // 사용자로부터 두 번째 정수 입력 받기
        System.out.print("두 번째 정수를 입력하세요: ");
        int b = Integer.parseInt(br.readLine());

        // 최대공약수 계산
        int gcd = findGCD(a, b);

        // 최소공배수 계산
        int lcm = findLCM(a, b, gcd);

        System.out.println("두 정수의 최대공약수는 " + gcd + "입니다.");
        System.out.println("두 정수의 최소공배수는 " + lcm + "입니다.");
        br.close();
    }

    /**
     * 두 정수의 최대공약수(GCD)를 구하는 함수
     * @param a 첫 번째 정수
     * @param b 두 번째 정수
     * @return a와 b의 최대공약수
     */
    public static int findGCD(int a, int b) {
        // 유클리드 호제법을 사용하여 최대공약수 구하기
      // a와 b 중에서 큰 값을 a로, 작은 값을 b로 설정하여 시작
        while (b != 0) {
            int temp = b; // b를 임시 변수 temp에 저장
            b = a % b;    // a를 b로 나눈 나머지를 b에 저장 (나머지 연산)
            a = temp;     // temp에 저장된 값을 a에 대입하여 반복
        }
        return a; // b가 0이 되면 반복문을 종료하고 a가 최대공약수가 됨
    }

    /**
     * 두 정수의 최소공배수(LCM)를 구하는 함수
     * @param a 첫 번째 정수
     * @param b 두 번째 정수
     * @param gcd a와 b의 최대공약수
     * @return a와 b의 최소공배수
     */
    public static int findLCM(int a, int b, int gcd) {
        // 최소공배수는 두 수의 곱을 최대공약수로 나눈 값과 같다
        return (a * b) / gcd;
    }
}

 

 

 

 

 

'자료구조 > 알고리즘 기초수학' 카테고리의 다른 글

Hash Table / Deque  (5) 2024.07.16
선형 자료구조 스택, 큐, 리스트  (0) 2024.07.08
이항계수, 동적계획법  (0) 2024.07.06
에라토스테네스의 체  (1) 2024.07.02
알고리즘 / 문자열  (1) 2024.07.01

에라토스테네스의 체는 소수 판별 알고리즘이다.
어려운 문제로 갈수록, 에라토스테네스의 체 알고리즘만 쓰는 경우는 드물고 보조적인 알고리즘으로 많이 쓰인다고 한다.


모든 자연수는 소수와 소수의 곱으로 이루어져 있다.

 

약수 어떤 수를 나눴을때 나머지가 0인 수
소수 양의 약수를 1과 자기 자신만 가지는 자연수
합성수 1과 자기 자신 이외의 수를 약수로 가지는 자연수. 약수가 3개 이상이다.


약수의 개수에 따른 자연수의 분류: 1, 소수, 합성수

20 이하의 소수에는 2, 3, 5, 7, 11, 13, 17, 19가 있다.
자연수 중에서 배수는 합성수이다.

어떻게 알았을까?

 

에라토스테네스의 체로 쉽게 알 수 있다.


1부터 100까지의 수가 있을때, 
1부터 하나씩 검사해보면 배수는 지워진다.

 

수식으로 표현하면

  • i를 제외한 i의 배수를 소수에서 제외한다.
  • i에 1을 더한다.
  • 이걸 반복한다

 

그럼 이걸 프로그래밍에 사용한다면
1. 소수를 판별할 범위만큼 배열을 할당한다
2. 2부터 시작하여 특정 수의 배수에 해당하는 수를 지운다
3. 2부터 시작하여 남아있는 수를 출력한다.

 

package week00;

import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {
       //에라토스테네스의 체
        int n = 100; // 찾고자 하는 범위 (1 이상의 자연수)
        boolean[] isPrime = new boolean[n + 1]; // 소수 여부를 저장할 배열

        // 배열 초기화: 모든 수를 소수로 간주하고 true로 설정
        for (int i = 2; i <= n; i++) {
            isPrime[i] = true;
        }

        // 에라토스테네스의 체 알고리즘 수행
        for (int p = 2; p * p <= n; p++) {
            // p가 소수인 경우에만 p의 배수들을 소수가 아닌 것으로 표시
            if (isPrime[p]) {
                for (int i = p * p; i <= n; i += p) {
                    isPrime[i] = false;
                }
            }
        }

        // 결과 출력
        System.out.print("소수 목록: ");
        for (int i = 2; i <= n; i++) {
            if (isPrime[i]) {
                System.out.print(i + " ");
            }
        }
    }
}

 

잘 출력되는 것을 확인할 수 있다.

'자료구조 > 알고리즘 기초수학' 카테고리의 다른 글

Hash Table / Deque  (5) 2024.07.16
선형 자료구조 스택, 큐, 리스트  (0) 2024.07.08
이항계수, 동적계획법  (0) 2024.07.06
유클리드 호제법  (0) 2024.07.04
알고리즘 / 문자열  (1) 2024.07.01

1. 알고리즘 / 자료구조

자료구조

데이터를 효율적으로 조직화하고 저장하는 방법을 제공하는 방법론이나 체계

자료구조에는 다양한 종류가 있으며 각각의 특성에 맞춰 데이터의 삽입, 삭제, 탐색 등의 연산을 지원한다.

 

배열(Array)

  • 일련의 원소들을 메모리 상에 연속적으로 저장하는 자료구조이다.
  • 인덱스를 사용하여 특정 위치의 원소에 접근할 수 있다.
  • 빠른 접근 속도를 제공하지만 크기를 변경 할 수 없다.

연결 리스트(Linked List)

  • 각 원소가 자신의 다음 원소를 가리키는 포인터를 가진 자료구조이다.
  • 삽입, 삭제 연산이 빠르지만 임의의 원소에 접근하기 위해선 순차적으로 탐색해야 한다.
  • 단일 연결 리스트, 이중 연결 리스트, 원형 연결 리스트 등이 있다.

스택(Stack)

  • 후입선출(LIFO, Last-In-First-Out) 구조를 가지는 자료구조이다.
  • Push(삽입)과 Pop(삭제) 연산만을 허용한다.
  • 함수 호출 스택, 괄호 매칭, 뒤로 가기 기능 등에서 사용된다.

큐(Queue)

  • 선입선출(FIFO, First-In-First-Out) 구조를 가지는 자료구조이다.
  • Enqueue(삽입)와 Dequeue(삭제) 연산을 지원한다.
  • 대기열 관리, BFS(너비 우선 탐색) 등에서 사용된다.

트리(Tree)

  • 계층적 구조를 나타내는 비선형 자료구조이다.
  • 노드들이 부모-자식 관계로 연결되어 있으며, 하나의 루트 노드를 가진다.
  • 이진 트리, 이진 탐색 트리, AVL 트리, 레드-블랙 트리 등 다양한 종류가 있다.
  • 데이터의 효율적인 탐색, 정렬, 삽입, 삭제를 위해 사용된다.

해시 테이블(Hash Table)

  • 키-값 쌍을 저장하는 자료구조로, 키를 해시 함수를 통해 인덱스로 변환하여 저장한다.
  • 평균적으로 상수 시간에 삽입, 삭제, 조회 연산을 수행할 수 있다.
  • 검색 속도가 빠르지만 충돌 해결과 해시 함수의 선택이 중요하다.

그래프(Graph)

  • 정점(Vertex)과 간선(Edge)으로 구성된 자료구조이다.
  • 방향성에 따라 방향 그래프와 무방향 그래프로 나뉜다.
  • BFS, DFS와 같은 탐색 알고리즘을 적용하여 경로 찾기, 네트워크 모델링 등에 사용된다.

자료구조의 선택 기준

연산의 종류 어떤 종류의 연산이 주로 수행되어야 하는지 고려한다
시간 복잡도 각 연산의 시간 복잡도를 고려한다
메모리 사용량 자료구조가 사용하는 메모리 공간을 고려한다
구현의 용이성 특정 자료구조를 구현하는 데 필요한 복잡성을 고려한다.
데이터의 특성 데이터의 크기, 정렬 여부, 중복 여부를 고려한다.

알고리즘 (Algorithm)

컴퓨터가 따라할 수 있도록 문제를 해결하는 절차나 방법을 컴퓨터에게 설명해주는 과정이다.

입력을 받아 원하는 출력을 만들어내기 위한 계산적 과정인데, 문제 해결시 정확하고 효율적인 결과값을 내기 위한

절차적 방법이다.

 

알고리즘은 주어진 문제를 해결하기 위해 단계별로 수행되며, 각 단계는 기본 연산으로 이루어진다.

기본 연산은 간단하고 명확하게 정의된 연산이다.

 

시간 복잡도, 공간 복잡도란?

정확성과 효율성을 보장하기 위한 알고리즘의 조건 중 하나이다.

시간 복잡도 알고리즘이 실행되는데 걸리는 시간의 양. 입력의 크기에 따라 연산의 수가 어떻게 증가하는지 나타낸다.
공간 복잡도 알고리즘이 실행되는 동안 사용되는 메모리의 양. 데이터 구조의 크기나 임시 저장소 등
정확성 알고리즘이 항상 올바른 출력을 생성하는지 확인한다.
효율성 알고리즘이 최적의 해답을 찾아내는지의 여부를 평가한다.

 

1. 정확성

알고리즘이 주어진 문제를 정확하게 해결하는가

모든 입력에 대해 올바른 결과를 출력해야 하며 예외 상황을 고려하여 처리해야 한다.

알고리즘의 모든 단계에서 의도한 결과를 얻을 수 있어야 한다.

 

2. 효율성

알고리즘이 문제를 해결하는데 소요되는 자원을 효율적으로 사용하는가

시간 효율성은 알고리즘이 입력 크기에 따라 실행 시간이 어떻게 증가하는지를 나타내며 빅오 표기법으로 표현한다.

공간 효율성은 알고리즘이 실행 중에 사용하는 메모리의 양을 나타내며 공간 복잡도로 평가된다.

 

3. 입력

알고리즘은 주어진 입력에 따라 정의되어야 한다.

입력의 형식과 범위, 제약 조건 등을 명확하게 정의해야 한다.

 

4. 출력

알고리즘은 명확한 출력을 만들어야 한다.

출력의 형식과 예상되는 값의 범위 등을 명확히 정의해야 한다.

 

5. 유한성

알고리즘은 정해진 단계 후 종료되어야 한다.

무한 반복이나 루프를 피하고 반복적인 작업시 항상 종료 조건을 가지고 있어야 한다.

 

6. 일반성

알고리즘은 주어진 문제의 모든 입력에 적용 가능해야 한다.

특정한 조건에서만 작동하지 않고 모든 경우에 작동해야 한다.

빅오 표기법

알고리즘 최악의 성능을 평가한다. 최상, 평균을 표기하는 표기법도 있지만 빅오 표기법이 가장 많이 사용하는 표기법이다.

시간 복잡도를 나타내는 표기법이다.

 

주어진 알고리즘이 입력 크기에 따라 얼마나 빠르게 실행되는지를 표현한다.

 

상수항을 무시 알고리즘이 O(N+5)의 복잡도를 가졌으면 상수를 생략해 O(N)으로 표기한다
계수도 무시 알고리즘이 O(3N)의 복잡도를 가졌으면 계수를 생략해 O(N)으로 표기한다
최고차항만 표기 어떤 알고리즘이 O(3N^3+2N^2+N+5)의 복잡도를 가졌으면 O(N^3)으로 표기한다.

 

O(1) 상수 시간

입력 크기에 관계없이 항상 일정한 시간이 걸리는 알고리즘

stack push, pop

 

O(log N) 로그 시간

입력 크기의 로그에 비례하여 실행 시간이 증가하는 알고리즘

 

O(N) 선형 시간

입력 크기에 직접적으로 비례하여 실행 시간이 증가하는 알고리즘

 

O(N^2) 이차 시간

입력 크기의 제곱에 비례하여 실행 시간이 증가하는 알고리즘

2중 For문, 삽입/거품/선택 정렬

 

O(2^N) 지수 시간

입력 크기에 대해 지수적으로 실행 시간이 증가하는 알고리즘

피보나치 수열

 

빅오 표기법을 갖는 알고리즘들은 다음과 같이 시간 복잡도를 가진다.

선형 탐색 배열에서 특정 원소를 찾는데 배열의 크기에 비례한 시간이 걸린다
이진 검색 정렬된 배열에서 원소를 찾는 데에는 배열의 크기의 로그에 비례한 시간이 걸린다
퀵 정렬 배열을 정렬하는 데에는 배열의 크기와 로그에 선형적인 시간이 걸린다.

 

3. 다음 기능을 가진 함수를 본인 언어로 정리하시오

문자열 인덱싱 / 슬라이싱

인덱싱: 문자열 특정 위치의 문자를 가져온다.

 

String str = "Hello";
char ch = str.charAt(0); // 'H' 반환

 

슬라이싱: 문자열의 일부를 잘라내어 가져온다.

String str = "Hello";
String sliced = str.substring(1, 4); // "ell" 반환 (인덱스 1부터 3까지)

특정 문자가 있는지 확인

String str = "Hello";
boolean containsChar = str.contains("e"); // true 반환

 

문자열이 같은지 비교

String str1 = "Hello";
String str2 = "Hello";
boolean isEqual = str1.equals(str2); // true 반환

 

 

문자열 길이 반환

String str = "Hello";
int length = str.length(); // 5 반환

 

특정 문자의 인덱스 값 찾기

String str = "Hello";
int index = str.indexOf('l'); // 2 반환 (첫 번째 'l'의 인덱스)

 

문자열을 구분자 기준으로 나누고 합치기

String str = "apple,banana,cherry";
String[] parts = str.split(",");
// parts 배열: ["apple", "banana", "cherry"]

String joined = String.join("-", parts);
// joined: "apple-banana-cherry"

 

문자열 대소문자 변환

String str = "Hello";
String lowerCase = str.toLowerCase(); // "hello" 반환
String upperCase = str.toUpperCase(); // "HELLO" 반환

 

기존 값을 다른 값으로 치환

String str = "Hello";
String replaced = str.replace('l', 'x'); // "Hexxo" 반환

 

양쪽 끝에서 특정 문자 (혹은 공백) 제거

String str = "  Hello  ";
String trimmed = str.trim(); // "Hello" 반환 (양쪽 공백 제거)

 

아스키코드로 변환 혹은 대소 비교

char ch = 'a';
int asciiValue = (int) ch; // 97 반환 (아스키 코드 값)

char ch1 = 'A';
char ch2 = 'B';
boolean isGreater = ch1 > ch2; // false 반환 (대소 비교)

 

'자료구조 > 알고리즘 기초수학' 카테고리의 다른 글

Hash Table / Deque  (5) 2024.07.16
선형 자료구조 스택, 큐, 리스트  (0) 2024.07.08
이항계수, 동적계획법  (0) 2024.07.06
유클리드 호제법  (0) 2024.07.04
에라토스테네스의 체  (1) 2024.07.02

+ Recent posts