Java Day 19

YDC·2025년 7월 7일

우테코8기

목록 보기
19/23

Day 18 복습

.length()

문자열의 길이를 측정하는 문법

.charAt()

특정 인덱스 접근하는 문법

문자-> 아스키 코드 변환 방법

(Int)str

항목Stringchar
자료형문자열 (문자 여러 개)문자 하나
표현 예시"hello"'h'
메모리 구조객체 (Heap에 저장됨)기본형 (Stack에 저장됨)
저장하는 값0글자 이상 문자들의 조합문자 1개만 저장 가능
입력 방법sc.next() 또는 sc.nextLine()sc.next().charAt(0)
길이 확인str.length() → 문자 수항상 1 (단일 문자)
비교 방법str.equals("hello")ch == 'h'
아스키코드 출력System.out.println((int) str.charAt(0))System.out.println((int) ch)
기본값 (초기화)null'\u0000' (널 문자)

.sorted()란?

Stream안에 요소들을 오름차순 또는 지정한 기준대로 정렬하는 중간 연산자

groupingBy()란?

스트림의 요소들을 특정 기준(키)으로 그룹화해서 Map<기준, List<요소>> 형식으로 묶어줌

counting()이란?

그룹화된 각 항목의 개수를 셈 (기본적으로 .size()와 비슷한 역할을 대신함)

학습목표

1.백준3문제

  • 11720 숫자의 합
  • 10809 알파벳 찾기
  • 2675 문자열 반복

2.CS

  • 누구나 자료 구조와 알고리즘 4강빅오 코드 속도 올리기
  • 해시, 트리
  • HTTP 구조

3.JAVA

  • REST API 설계 및 URI 매핑
  • 기본 구조 만들기 (controller)

1.백준 3문제

1.11720 숫자의 합

문제

N개의 숫자가 공백 없이 쓰여있다. 이 숫자를 모두 합해서 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 숫자의 개수 N (1 ≤ N ≤ 100)이 주어진다. 둘째 줄에 숫자 N개가 공백없이 주어진다.

출력

입력으로 주어진 숫자 N개의 합을 출력한다.

예제 입력 1

1
1

예제 출력 1

1

예제 입력 2

5
54321

예제 출력 2

15

예제 입력 3

25
7000000000000000000000000

예제 출력 3

7

예제 입력 4

11
10987654321

예제 출력 4

46

풀이

package string;
import java.util.Scanner;
public class BOJ_DigitSumCalculator {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String s = sc.next();
        int sum = 0;
        for(int i=0;i<n;i++){
            sum += s.charAt(i) - '0';
        }
        System.out.print(sum);
    }
}

문자열로 입력된 숫자를 하나씩 분리하여 합산하는 연습. char → int 변환 (char - '0')개념을 익히기 위한 문제.

2.10809 알파벳 찾기

문제

알파벳 소문자로만 이루어진 단어 S가 주어진다. 각각의 알파벳에 대해서, 단어에 포함되어 있는 경우에는 처음 등장하는 위치를, 포함되어 있지 않은 경우에는 -1을 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 단어 S가 주어진다. 단어의 길이는 100을 넘지 않으며, 알파벳 소문자로만 이루어져 있다.

출력

각각의 알파벳에 대해서, a가 처음 등장하는 위치, b가 처음 등장하는 위치, ... z가 처음 등장하는 위치를 공백으로 구분해서 출력한다.
만약, 어떤 알파벳이 단어에 포함되어 있지 않다면 -1을 출력한다. 단어의 첫 번째 글자는 0번째 위치이고, 두 번째 글자는 1번째 위치이다.

예제 입력 1

baekjoon

예제 출력 1

1 0 -1 -1 2 -1 -1 -1 -1 4 3 -1 -1 7 5 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

풀이

package string;
import java.util.Arrays;
import java.util.Scanner;

public class BOJ_10809_AlphabetPositionFinder {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        int [] arr = new int[26];
        Arrays.fill(arr,-1);
        for(int i=0;i<s.length();i++){
            char ch = s.charAt(i);
            int idx = ch - 'a';
            if(arr[idx]==-1){
                arr[idx]=i;
            }
            for(int alp :arr){
                System.out.print(alp+" ");
            }
        }
    }
}

Arrays.fill 이란?

array를 채워주는 문법

알파벳 a~z의 최초 등장 위치를 기록하는 배열 활용 문제. char - 'a'로 인덱스 매핑, Arrays.fill()로 초기화

3.2675 문자열반복

문제

문자열 S를 입력받은 후에, 각 문자를 R번 반복해 새 문자열 P를 만든 후 출력하는 프로그램을 작성하시오. 즉, 첫 번째 문자를 R번 반복하고, 두 번째 문자를 R번 반복하는 식으로 P를 만들면 된다. S에는 QR Code "alphanumeric" 문자만 들어있다.
QR Code "alphanumeric" 문자는 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ$%*+-./: 이다.

입력

첫째 줄에 테스트 케이스의 개수 T(1 ≤ T ≤ 1,000)가 주어진다. 각 테스트 케이스는 반복 횟수 R(1 ≤ R ≤ 8), 문자열 S가 공백으로 구분되어 주어진다. S의 길이는 적어도 1이며, 20글자를 넘지 않는다. 

출력

각 테스트 케이스에 대해 P를 출력한다.

예제 입력 1

2
3 ABC
5 /HTP

예제 출력 1

AAABBBCCC
/////HHHHHTTTTTPPPPP

풀이

package string;
import java.util.Scanner;
public class BOJ_2675_StringRepeater {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        for (int i = 0; i < t; i++) {
            int r = sc.nextInt();
            String s = sc.next();
            String answer = "";
            for(int j=0;j<s.length();j++){
                char ch = s.charAt(j);
                for(int k=0;k<r;k++){
                    answer += ch;
                }
            }
            System.out.println(answer);
        }
    }
}

각 문자를 정해진 횟수만큼 반복 출력. 중첩 반복문과 문자 처리, 그리고 입출력 형식 조작을 익히게 하기 위한 기본적인 문자열 처리 문제

2.CS

1.누구나 자료 구조와 알고리즘 4강 빅오 코드 속도 올리기

버블정렬

정렬 알고리즘은 정렬되지 않은 배열이 주어졌을 때, 어떻게 오름차순으로 정렬할 수 있을까?를 해결 하는 알고리즘
그중에 매우 기본적인 알고리즘인 버블정렬은 첫번재와 두번를 비교함 왼쪽이 오른쪽보다 크면 교환(swap)함
그리고 두번째와 3번째를 비교함 이걸 계속 반복함 그걸 패스쓰루라고함 더이상 반복하지 않으면 정렬이 끝남

버블 정렬의 효율성

버블 정렬 알고리즘에 포함된 단계는 2종류임 비교 와 교환(swap)
비교는 원소 N개가 있을때 (N-1) + (N-2) + (N-3)… 번의 단계가 필요함
최악의 시나리오의 경우교환(swap)도 똑같은 단계가 필요함
따라서 버블 정렬은 원소 N개가 있을때 N^2번의 단계가 필요하고
빅오 표기법은 버블 정렬의 효율성을 O(N^2)라고 하고 이를 이차 시간이라고도 부름

이차 문제 와 선형 해결법

배열에서 중복 값이 있는지 확인하는 애플리케이션을 작성한다고 하면 for문 중첩으로 루프를 돌리는게 제일 먼저 떠오름

Ex) 자바스크립트
Function hasDuplicateValue(array){
	for(various I =0;i<array.length;i++){
		for(var j =0;j<array.length;j++){
			f(I!=just && array[I] == array[j]){
				Return true;}
		}
	}	
} 

하지만 이 구조를 빅 오로 표기하면 N^2의 알고리즘을 가짐 이는 상대적으로 느린 알고리즘임
이를 해결하기 위해서 중첩루프를 쓰지 않는 함수를 구현해 볼 수 있음 이는 O(N)임
결과적으로 O(N^2)보다 )O(N)이 훨씬 빠르므로 두번째 접근법을 사용하여 최적하는게 좋음
많은 데이터를 처리할수록 차이가 더 클 것임

Ex) 자바스크립트
Function hasDuplicateValue(array){
	Var existingNumber = [];
	for(var I = 0 ; I<array.length;i++){
		if(existingNumbers[array[I] === undefined]){
			existingNumbers[array[I]] = 1;
	}else{
		return true;
		}
	}
	return false;
}

빅오 표기법을 이해하면 느린코드를 식별하고 더 빠른 알고리즘을 골라낼 수 있음

2.해시,트리

해시란?

Key Value 형태로 데이터를 저장하는 자료구조
빠르게 찾고 싶을때 사용함 O(1)중복 key 불가능 함
아이디 찾기 , 캐시, 카운팅에 주로 사용됨

Ex)
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.get("apple"); // 결과: 1

트리란?

계층적 구조의 노드기반 자료구조
루트 - 자식 노드 형태로 뻗어감 중복 안됨
BST기준 O(logN)
정렬된 자료보관, 탐색 트리 에 사용됨
종류 설명
이진 트리 자식이 최대 2개
이진 탐색 트리(BST) 왼쪽 < 부모 < 오른쪽
힙(Heap) 최대값/최소값 빠르게 꺼내는 용도
트라이(Trie) 문자열 검색, 자동완성용
AVL, 레드블랙 트리 자동 균형 잡는 BST (실무에서 많이 씀)

3.HTTP 구조

HTTP란?

HyperTextTransferProtocol
클라이언트(브라우저,앱)와 서버가 서로 데이터를 주고받기 위한 약속된 통신 규칙

http 통신 흐름

클라이언트 -> 요청(Request) -> 서버
서버 -> 응답(Response) -> 클라이언트

http 요청 구조 (Request)

GET /todos HTTP/1.1 // 요청라인 : 메서드 + 경로 + 버전
Host: example.com
User-Agent: Chrome/...
Content-Type: application/json //헤더 : 부가정보
(빈 줄) // 본문과 헤더 구분
{"task":"청소하기","done":false} // 바디 :실제데이터

http 응답 구조(Response)

HTTP/1.1 200 OK // 상태라인 : 버전+상태 코드 + 메세지
Content-Type: application/json //헤더 부가 정보
Content-Length: 37
(빈 줄) // 본문과 헤더 구분
{"id":1,"task":"청소하기","done":false} //바디 :응답 데이터

Http 메소드

메서드설명REST 예시
GET데이터 조회GET /todos
POST새 데이터 생성POST /todos
PUT데이터 전체 수정PUT /todos/1
PATCH데이터 일부 수정PATCH /todos/1
DELETE삭제DELETE /todos/1

상태코드

코드의미예시
200 OK성공요청 정상 처리
201 Created생성됨POST 성공 시
400 Bad Request잘못된 요청파라미터 오류
401 Unauthorized인증 실패로그인 필요
403 Forbidden접근 금지권한 없음
404 Not Found없는 자원잘못된 URL
500 Internal Server Error서버 에러코드 오류 발생 시

3.JAVA

1.TODO 프로젝트 RESTFUL 설계 및 매핑

RestAPI란?

REpresentational State TransferApplication Programming Interface
HTTP 기반으로 동작하는
규칙이 정해진 방식의 URL과 메서드 설계
클라이언트가 자원(Resource) 에 요청(Request) 을 보내고, 서버가 응답(Response) 하는 구조

Rest ApI의 3요소

자원 : 데이터의 대상 (/todos,users/1)
행위 : 어떤 동작인지 (GET,POST,PUT,DELETE)
표현 : 주고받는 데이터 형식 ( Json,Xml등)

Restful API의 핵심 규칙

uri는 자원을 표현함 /todos,/todos/1 동사는 안씀 /getTodo,/addTodo
HTTP 메소드로 행위를 구분함 GET,POST,PUT,DELETE
요청 간 서버가 상태 저장을 하지 않음
일관된 구조를 사용함

자원의 정의

우리가 사용하는 자원은 Todo
Json 으로 되어있고
Id,Task,Dudate,Done 가 있음

URL 매핑

기능HTTP MethodURI설명
할 일 전체 조회GET/todos전체 목록 가져오기
특정 할 일 조회GET/todos/{id}ID로 단일 조회
할 일 추가POST/todos새 할 일 생성
할 일 수정PUT/todos/{id}전체 수정
완료 체크PATCH/todos/{id}/done완료 처리 (부분 수정)
할 일 삭제DELETE/todos/{id}삭제

2.기본구조 만들기 (controller)

**전체 흐름을 먼저 잡고 필요한 메서드는 나중에 만드는 탑다운 방식 사용

새로운 브랜치 생성 refactor/RESTAPI
API사용하기위한 기본 틀 생성

API는 요청이들어오면 응답을 해야되기 때문에
String을 사용함

메소드와 URL 기준은

기능HTTP MethodURI설명
할 일 전체 조회GET/todos전체 목록 가져오기
특정 할 일 조회GET/todos/{id}ID로 단일 조회
할 일 추가POST/todos새 할 일 생성
할 일 수정PUT/todos/{id}전체 수정
완료 체크PATCH/todos/{id}/done완료 처리 (부분 수정)
할 일 삭제DELETE/todos/{id}삭제

특정 할일 조회와 수정같은 url에 id가 함께 입력되는 부분에서 id를 빼내기 위해

extractId 메소드 생성

Main에서 호출할때
Method 와 url필요
입력시 오류 발생을 막기위해 띄어씌기를 없애는 trim사용

TodoController 클래스 생성

public class TodoController {
    private final TodoService service;

    public TodoController(TodoService service){
        this.service = service;
    }

    private int extractId(String uri) {
        try {
            String[] parts = uri.split("/");
            return Integer.parseInt(parts[2]);
        } catch (Exception e) {
            return -1;
        }
    }

public String handleRequest(String method,String url){
        if(method.equals("GET")&&url.equals("/todos")){
           return service.getAllTodos();
        } else if(method.equals("POST")&&url.equals("/todos")){
            return service.createTodo();
        } else if(method.equals("GET")&&url.startsWith("/todos/")){
            int id  = extractId(url);
            return service.getTodoById(id);
        } else if(method.equals("PUT")&&url.startsWith("/todos/")){
            int id = extractId(url);
            return service.updateTodo(id);
        } else if(method.equals("PATCH")&&url.startsWith("/todos/")&&url.endsWith("/done")){
            int id = extractId(url);
            return service.markDone(id);
        } else if(method.equals("DELETE")&&url.startsWith("/todos/")){
            int id = extractId(url);
            return service.deleteTodo(id);
        }

        return "404 Not Found";
}
}

테스트를 위해 임시로 TodoService 생성

public class TodoService {
    public String getAllTodos() {
        return "[{ \"id\": 1, \"task\": \"공부하기\", \"done\": false }]";
    }

    public String createTodo() {
        return "새로운 할 일이 생성되었습니다.";
    }

    public String getTodoById(int id) {
        return "ID " + id + "번 할 일 조회";
    }

    public String updateTodo(int id) {
        return "ID " + id + "번 할 일 수정 완료";
    }

    public String markDone(int id) {
        return "ID " + id + "번 할 일 완료 처리됨";
    }

    public String deleteTodo(int id) {
        return "ID " + id + "번 할 일 삭제됨";
    }
}

Main 코드

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        TodoService service = new TodoService();
        TodoController controller = new TodoController(service);

        System.out.println(" 무슨 일을 하실건가요?");
        System.out.println("ex): POST /todos");

        while (true) {
            System.out.print("\n>> ");
            String method = sc.next();
            String uri = sc.nextLine().trim();

            String response = controller.handleRequest(method, uri);
            System.out.println("📦 응답: " + response);
        }
    }
}

리뷰

정신을 차리고 다시 열심히 해보겠습니다
저번주에 N2시험을 봐야되서 잠시 일본어에 집중을 했습니다 ( 사실 좀 많이 놀았음 )
드디어 RESTFUL API에 손을 대기 시작했습니다 url과 메소드에 뭘 하는지 다 나와있어서
한눈에 보기도 편하고 Sprig가기전 마지막 연습겸 하고있습니다
자료구조 책을 보면서 빅오 표기법이라는걸 알게되고 중첩문은 단계가 많이 걸리는구나 등
알고리즘의 효율성에대해 더 생각하게 되었습니다
이제 우테코 지원까지 2달 최선을 다하겠습니다!

profile
초심자

0개의 댓글