diff --git a/README.md b/README.md index 08c3c9f..b8ead5c 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,54 @@ -![20240229152145.png](..%2F20240229152145.png) +# 백엔드 도우미 프로젝트 -## 개발 목적 -백엔드 오르미 부트캠프 학생들을 위해 코딩테스트 관련 주제를 설명 및 질문을 받을 수 있는 페이지를 제공하며 -퀴즈와 정답을 출제할 수 있는 페이지를 제공하여 백엔드 개발자가 되는데 도움이 되고자 만들었습니다. +## 📋 프로젝트 소개 +

ESTsoft 백엔드 개발자 오르미 4기에서 프로젝트를 진행하고 있는 도우미입니다.

+

Bend Doumi는 코딩 테스트 준비와 지식 공유를 위한 커뮤니티입니다.

+

알고리즘이 설명되어 있는 알고리즘 페이지와 코딩 테스트 관련 문제를 질문할 수 있는 코딩 테스트 준비 페이지와 +
+ 자신이 알고 있는 지식에 대해 질문과 답을 등록하여 다른 이용자들이 퀴즈 형식으로 학습할 수 있게 함으로써, 지식을 테스트하고 공유하는 + 퀴즈 페이지가 있습니다.
+ 여기서는 모두가 질문하고,가르치면서 함께 배우고 성장할 수 있습니다. + +

-## 개발 기간 -2월 ~ 3월(1 ~ 2개월) +## 🚩 프로젝트 목표 +클린 코드 작성을 통해 코드의 가독성과 유지 보수성을 향상시켜 개발 과정을 원활하게 만드는 것을 목표로 개발하였습니다. -## 개발 인원 -4명 \ No newline at end of file +GitHub을 활용하여 프로젝트를 관리하고 코드를 공유하며, 코드 리뷰를 진행함으로써 팀원들 간의 프로젝트 이해도를 향상시켰습니다. + +

+ +## 📆 프로젝트 진행기간 +- 2024-02-13 ~ 2024-03-20 + +

+ +## 👨🏻‍💻 개발 인원 : 3명 +강한주, 강성훈, 정지원 + +

+ +## 🔗 배포 주소 +http://bend-doumi.com:8080/ + +## ⚙️Skills + +### Languages +[![My Skills](https://skillicons.dev/icons?i=spring,java,js,html,css)](https://skillicons.dev) + +### Tools +[![My Skills](https://skillicons.dev/icons?i=idea,gradle,github,figma)](https://skillicons.dev) + +### DataBase +[![My Skills](https://skillicons.dev/icons?i=mysql)](https://skillicons.dev) + +### OS +[![My Skills](https://skillicons.dev/icons?i=windows,ubuntu)](https://skillicons.dev) + +### Deploy +[![My Skills](https://skillicons.dev/icons?i=aws,githubactions)](https://skillicons.dev) + +### 🔌 API +- toast UI API + +## ✅ 기능 구현 목록 diff --git a/src/main/java/com/example/doumiproject/controller/AlgorithmController.java b/src/main/java/com/example/doumiproject/controller/AlgorithmController.java index c590517..4b6227f 100644 --- a/src/main/java/com/example/doumiproject/controller/AlgorithmController.java +++ b/src/main/java/com/example/doumiproject/controller/AlgorithmController.java @@ -11,11 +11,12 @@ @Controller public class AlgorithmController { + @GetMapping("/doumiAlgorithm") @Operation(summary = "알고리즘 메인 페이지를 조회할 수 있는 API") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "알고리즘 메인 HTML을 반환", - content = @Content(mediaType = "text/html")) + @ApiResponse(responseCode = "200", description = "알고리즘 메인 HTML을 반환", + content = @Content(mediaType = "text/html")) }) public String index() { @@ -29,7 +30,17 @@ public String timecomplexity() { } @GetMapping("/codingtest/stack") - public String stack(){ + public String stack() { return "algorithm/stackAndQueue"; } + +// @GetMapping("/codingtest/bruteforce") +// public String bruteforce() { +// return "algorithm/bruteforce"; +// } + + @GetMapping("/codingtest/sets&maps") + public String setsAndMaps() { + return "algorithm/setsAndMaps"; + } } diff --git a/src/main/java/com/example/doumiproject/controller/UserController.java b/src/main/java/com/example/doumiproject/controller/UserController.java index ce6e6b6..6869f04 100644 --- a/src/main/java/com/example/doumiproject/controller/UserController.java +++ b/src/main/java/com/example/doumiproject/controller/UserController.java @@ -4,6 +4,7 @@ import com.example.doumiproject.dto.PostDto; import com.example.doumiproject.entity.Comment; import com.example.doumiproject.entity.User; +import com.example.doumiproject.exception.user.NotValidateUserException; import com.example.doumiproject.service.CodingTestService; import com.example.doumiproject.service.CommentService; import com.example.doumiproject.service.QuizService; @@ -31,6 +32,7 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -158,7 +160,7 @@ public String myPage(@PathVariable("userId") Long userId, HttpSession session, M content = @Content(mediaType = "text/html")) }) public String getCodingTestPost(@PathVariable("userId") Long userId, HttpSession session, - @RequestParam(defaultValue = "1", value = "page") int page, Model model) { + @RequestParam(defaultValue = "1", value = "page") int page, Model model) { int totalPages = codingTestService.getTotalPagesForMyPage(userId, "COTE", pageSize); List userCoteList = codingTestService.findByUserId(userId, page, pageSize); @@ -175,7 +177,7 @@ public String getCodingTestPost(@PathVariable("userId") Long userId, HttpSession content = @Content(mediaType = "text/html")) }) public String getQuizPost(@PathVariable("userId") Long userId, HttpSession session, - @RequestParam(defaultValue = "1", value = "page") int page, Model model) { + @RequestParam(defaultValue = "1", value = "page") int page, Model model) { int totalPages = quizService.getTotalPagesForMyPage(userId, "QUIZ", pageSize); @@ -193,7 +195,7 @@ public String getQuizPost(@PathVariable("userId") Long userId, HttpSession sessi content = @Content(mediaType = "text/html")) }) public String getCommentPost(@PathVariable("userId") Long userId, HttpSession session, - @RequestParam(defaultValue = "1", value = "page") int page, Model model) { + @RequestParam(defaultValue = "1", value = "page") int page, Model model) { int totalPages = commentService.getTotalPagesForMyPage(userId, pageSize); @@ -204,7 +206,8 @@ public String getCommentPost(@PathVariable("userId") Long userId, HttpSession se return "myPage/myPageComment"; } - private void setPaginationAttributes(Model model, int page, int totalPages, Long userId, List contents) { + private void setPaginationAttributes(Model model, int page, int totalPages, Long userId, + List contents) { if (page < 1) { page = 1; @@ -220,4 +223,17 @@ private void setPaginationAttributes(Model model, int page, int totalPages, Long model.addAttribute("totalPages", totalPages); model.addAttribute("userId", userId); } + + @DeleteMapping("/user/{id}/delete") + public ResponseEntity withdraw(@PathVariable Long id, HttpSession session) { + long userId = (long) session.getAttribute("userId"); + + if (userId != id) { + throw new NotValidateUserException(); + } + + userService.deleteUser(userId); + + return ResponseEntity.ok().build(); + } } diff --git a/src/main/java/com/example/doumiproject/repository/JdbcTemplateUserRepository.java b/src/main/java/com/example/doumiproject/repository/JdbcTemplateUserRepository.java index b4359ee..d293a4a 100644 --- a/src/main/java/com/example/doumiproject/repository/JdbcTemplateUserRepository.java +++ b/src/main/java/com/example/doumiproject/repository/JdbcTemplateUserRepository.java @@ -61,7 +61,7 @@ public User findByUserId(String userId) { public List findAllUser() { return null; } - + @Override public List findAllUserCommentPosts(Long userId) { String sql = "SELECT user_id,post_id,type,contents,updated_at FROM comment WHERE user_id = ?"; @@ -77,4 +77,11 @@ public List findAllUserCommentPosts(Long userId) { }); } + @Override + public void deleteUser(Long userId) { + String sql = "DELETE FROM user WHERE id = ?"; + + jdbcTemplate.update(sql, userId); + } + } diff --git a/src/main/java/com/example/doumiproject/repository/UserRepository.java b/src/main/java/com/example/doumiproject/repository/UserRepository.java index deaab89..bb10f8b 100644 --- a/src/main/java/com/example/doumiproject/repository/UserRepository.java +++ b/src/main/java/com/example/doumiproject/repository/UserRepository.java @@ -29,4 +29,7 @@ default RowMapper userRowMapper() { return user; }); } -} + + void deleteUser(Long userId); + +} \ No newline at end of file diff --git a/src/main/java/com/example/doumiproject/service/UserService.java b/src/main/java/com/example/doumiproject/service/UserService.java index 6bd2d6f..fcb6b02 100644 --- a/src/main/java/com/example/doumiproject/service/UserService.java +++ b/src/main/java/com/example/doumiproject/service/UserService.java @@ -66,4 +66,9 @@ public List getAllUserCommentPosts(Long userId) { List userCommentPosts = userRepository.findAllUserCommentPosts(userId); return userCommentPosts; } + + + public void deleteUser(Long userId) { + userRepository.deleteUser(userId); + } } diff --git a/src/main/resources/static/Js/myPage.js b/src/main/resources/static/Js/myPage.js index dc9c366..76298b8 100644 --- a/src/main/resources/static/Js/myPage.js +++ b/src/main/resources/static/Js/myPage.js @@ -1,61 +1,29 @@ -function clickToGoMyCodingtestPost() { - let id = document.getElementById('myPage_userName').getAttribute( - 'data-userid'); - switchHighlight('coteType'); - $.ajax({ - //JS에 백틱을 써서 템플릿 리터럴을 사용했다 - url: `/user/${id}/codingtest/posts`, - type: "GET", - success: function (data) { - $('.show_user_wrote .table_container .postList').html(data); - console.log(data); - }, - error: function (error) { - console.log(error); - } - }); -} - -function clickToGoMyQuizPost() { - let id = document.getElementById('myPage_userName').getAttribute( - 'data-userid'); - switchHighlight('quizType'); - $.ajax({ - url: `/user/${id}/quiz/posts`, - type: "GET", - success: function (data) { - $('.show_user_wrote .table_container .postList').html(data); - console.log(data); - }, - error: function (error) { - console.log(error); - } - }); -} +function clickToGoLeaveMembership(event) { + event.preventDefault(); -function clickToGoMyCommentPost() { - let id = document.getElementById('myPage_userName').getAttribute( - 'data-userid'); - switchHighlight('commentType'); - $.ajax({ - url: `/user/${id}/comment/posts`, - type: "GET", - success: function (data) { - $('.show_user_wrote .table_container .postList').html(data); - console.log(data); - }, - error: function (error) { - console.log(error); - } - }); -} + const isConfirmed = confirm("Bend Doumi에서 탈퇴하시겠습니까?"); -function switchHighlight(selectedId) { - let items = ['coteType', 'quizType', 'commentType']; + if (isConfirmed) { + // 사용자 ID 가져오기 + let id = document.getElementById('myPage_userName').getAttribute( + 'data-userid'); - items.forEach(function (id) { - document.getElementById(id).style.color = ''; // 원래 색상으로 초기화 - }); - - document.getElementById(selectedId).style.color = '#04B45F'; + fetch(`/user/${id}/delete`, { + method: 'DELETE', + }) + .then(response => { + if (response.ok) { + alert("탈퇴 처리가 완료되었습니다."); + window.location.replace('/user/login'); + } else { + alert("탈퇴 처리 중 오류가 발생했습니다."); + } + }) + .catch(error => { + console.error('탈퇴 요청 실패:', error); + alert("탈퇴 처리 중 문제가 발생했습니다."); + }); + } else { + alert("탈퇴 절차가 취소되었습니다."); + } } diff --git a/src/main/resources/static/css/codingtest/doumiAlgorithm.css b/src/main/resources/static/css/codingtest/doumiAlgorithm.css index 8f272bc..550a351 100644 --- a/src/main/resources/static/css/codingtest/doumiAlgorithm.css +++ b/src/main/resources/static/css/codingtest/doumiAlgorithm.css @@ -16,7 +16,7 @@ body { /*header 파트*/ .move_to_algorithm { - /*color: #04B45F;*/ + color: #04B45F; } diff --git a/src/main/resources/static/css/codingtest/index.css b/src/main/resources/static/css/codingtest/index.css index 60e3f32..e00de25 100644 --- a/src/main/resources/static/css/codingtest/index.css +++ b/src/main/resources/static/css/codingtest/index.css @@ -15,8 +15,8 @@ body { } /*header 파트*/ -.move_to_algorithm { - /*color: #04B45F*/ +.move_to_codingtest { + color: #04B45F } /*main 파트*/ diff --git a/src/main/resources/static/css/fragments/footer.css b/src/main/resources/static/css/fragments/footer.css index 28d7661..d229910 100644 --- a/src/main/resources/static/css/fragments/footer.css +++ b/src/main/resources/static/css/fragments/footer.css @@ -1,44 +1,44 @@ html, body { - height: 100%; + min-height: 100vh; } body { - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; } main { - flex: 1; - width: 100%; + flex: 1; + width: 100%; } -footer{ - width: 100%; - padding: 70px 0 40px 0; - /*border-top: 1px solid #C4C4C4;*/ +footer { + width: 100%; + padding: 70px 0 40px 0; + /*border-top: 1px solid #C4C4C4;*/ } -.footer-wrapper{ - display: flex; - justify-content: space-between; - max-width: 900px; - margin: 0 auto; +.footer-wrapper { + display: flex; + justify-content: space-between; + max-width: 900px; + margin: 0 auto; } -.boot-camp-info{ - font-size: 13px; - font-weight: 500; - display: flex; - align-items: center; +.boot-camp-info { + font-size: 13px; + font-weight: 500; + display: flex; + align-items: center; } -.footer-img{ - width: 40px; +.footer-img { + width: 40px; } -.helper{ - font-size: 13px; - display: flex; - align-items: center; +.helper { + font-size: 13px; + display: flex; + align-items: center; } diff --git a/src/main/resources/static/css/myPage.css b/src/main/resources/static/css/myPage.css index 90be42c..53105c0 100644 --- a/src/main/resources/static/css/myPage.css +++ b/src/main/resources/static/css/myPage.css @@ -40,6 +40,28 @@ body { cursor: pointer; } +.user_delete_btn { + padding: 10px; + font-size: 1rem; + line-height: 1.5; + color: #363636; + cursor: pointer; + text-align: center; + background-color: #FFFFFF; + border: 1px solid #dbdbdb; + border-radius: 10px; +} + +.user_delete_btn { + color: #FFFFFF; + background-color: #04B45F; +} + +.user_delete_btn:hover { + background-color: #04B45F; + filter: brightness(90%); +} + /*게시판*/ .show_user_wrote { padding: 1.0rem 0.75rem; diff --git a/src/main/resources/static/css/quiz/index.css b/src/main/resources/static/css/quiz/index.css index c907878..71bdf0c 100644 --- a/src/main/resources/static/css/quiz/index.css +++ b/src/main/resources/static/css/quiz/index.css @@ -16,7 +16,7 @@ body { /*header 파트*/ .move_to_quiz { - /*color: #04B45F*/ + color: #04B45F } /*main 파트*/ @@ -106,7 +106,7 @@ body { .title { width: 40%; margin-right: 10px; - + white-space: nowrap; overflow: hidden; text-overflow: ellipsis; diff --git a/src/main/resources/templates/algorithm/bruteforce.html b/src/main/resources/templates/algorithm/bruteforce.html index 98a14bb..475423f 100644 --- a/src/main/resources/templates/algorithm/bruteforce.html +++ b/src/main/resources/templates/algorithm/bruteforce.html @@ -120,6 +120,7 @@

브루트 포스는 알고리즘을 배우는 초기 단계에서 매우 유 + diff --git a/src/main/resources/templates/algorithm/doumiAlgorithm.html b/src/main/resources/templates/algorithm/doumiAlgorithm.html index e4b8828..939324e 100644 --- a/src/main/resources/templates/algorithm/doumiAlgorithm.html +++ b/src/main/resources/templates/algorithm/doumiAlgorithm.html @@ -6,7 +6,8 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> DoumiCoteMain - + @@ -44,6 +45,22 @@
도우미
2024-03-16
+ + + + + + + + +
  • +
    3
    + +
    도우미
    +
    2024-03-16
    +
  • diff --git a/src/main/resources/templates/algorithm/setsAndMaps.html b/src/main/resources/templates/algorithm/setsAndMaps.html index 2f44194..7de5bf1 100644 --- a/src/main/resources/templates/algorithm/setsAndMaps.html +++ b/src/main/resources/templates/algorithm/setsAndMaps.html @@ -3,14 +3,23 @@ Doumi - + + + + +
    -
    @@ -50,7 +59,7 @@

    집합(Set)의 특징과 사용법

    public class SetExample { public static void main(String[] args) { - Set<Integer> numberSet = new HashSet<>(); + Set<Integer> numberSet = new HashSet<>(); numberSet.add(1); numberSet.add(2); numberSet.add(3); @@ -88,7 +97,7 @@

    맵(Map)의 특징과 사용법


    public class MapExample { public static void main(String[] args) { - Map<String, Integer> ageMap = new HashMap<>(); + Map<String, Integer> ageMap = new HashMap<>(); ageMap.put("Alice", 30); ageMap.put("Bob", 25); ageMap.put("Charlie", 35); @@ -157,7 +166,7 @@

    맵(Map)의 특징과 사용법


    // 상근이가 가지고 있는 숫자 카드의 개수 N int N = scanner.nextInt(); - Set<Integer> cardSet = new HashSet<>(); + Set<Integer> cardSet = new HashSet<>(); // 상근이의 숫자 카드 입력 받기 for (int i = 0; i < N; i++) { @@ -222,6 +231,8 @@

    맵(Map)의 특징과 사용법


    +
    + diff --git a/src/main/resources/templates/algorithm/stackAndQueue.html b/src/main/resources/templates/algorithm/stackAndQueue.html index 6ba43f7..2cd8f93 100644 --- a/src/main/resources/templates/algorithm/stackAndQueue.html +++ b/src/main/resources/templates/algorithm/stackAndQueue.html @@ -1,178 +1,185 @@ - - Doumi - - - - - - - - - - - + + Doumi + + + + + + + + + + +
    -
    - -

    스택과 큐

    - -
    -
    -

    알고리즘 게시판 본문 내용

    -
    - -

    - - 안녕하세요! 도우미입니다!
    - 오늘은 스택과 큐 개념 및 스택, 큐 알고리즘을 이용한 문제 예제들을 소개해드릴까 합니다.
    - 스택과 큐는 코딩테스트에서 굉장히 자주 쓰이는 자료구조입니다. -

    - 우선 스택과 큐의 개념에 대해서 설명해드릴게요.

    - -

    Stack

    - 스택 알고리즘 그림 -
    스택(stack)이란 쌓아 올린다는 것을 의미합니다.

    - 스택은 가장 마지막에 저장된 데이터가 가정 먼저 삭제되는 후입선물(LIFO, Last In First Out)구조 입니다. 그렇기 때문에 한쪽 방향에서만 데이터의 - 삽입과 삭제가 가능합니다.

    - - 간단한 예시로는 포개 둔 일회용 종이컵을 하나하나 꺼내서 사용하는 것으로 예시를 들 수 있을 것 같네요.


    - -

    Stack의 메서드


    - - - - - - - - - - - - - - - - - - - - - - - - - -
    메서드설명
    Boolean empty()Stack이 비어있는지 알려줍니다.
    Object peek()스택의 맨 위에 저장된 객체를 반환합니다. 그림상에서는 요소 4가 해당됩니다. (비었다면 EmptyStackException발생)
    Object push(Object o)데이터를 삽입하는 연산입니다. 삽입된 데이터는 삭제 시 가장 먼저 삭제 될 데이터가 됩니다. (비었다면 EmptyStackException발생)
    Object pop()데이터를 삭제하는 연산입니다. 가장 최근에 저장된 데이터가 삭제됩니다.
    Int search(Object o)스택에 주어진 객체(o)를 찾아서 그 위치를 반환합니다. 못 찾으면 -1을 반환합니다. (배열과 달리 위치는 0이 아닌 1부터 시작합니다.)
    - -


    -

    Queue

    - 큐 알고리즘 그림 -
    Queue의 사전적 의미는 줄, 또는 줄을 서서 기다리는 것을 의미합니다.

    - 일상생활에서 맛집에 줄을 서서 기다리는 것, 은행에서 먼저 온 순서대로 업무를 처리하는 것과 같이 선입선출(FIFO)방식의 자료구조를 말합니다.
    - 스택과 달리 한 쪽에서는 데이터 삽입, 다른 한쪽에서는 데이터의 삭제만 가능합니다.

    - 큐는 데이터의 추가/삭제가 쉬운 LinkedList로 구현하는 것이 더 적합합니다.
    -
    Queue queue=new LinkedList();
    -

    -

    Queue의 메서드


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    메서드설명
    Boolean add(Object o)저장된 객체를 Queue에 추가합니다. (저장공간이 부족하면 IllegalStateException 발생)
    Object remove()Queue에서 객체를 꺼내 반환합니다. 그림상에서는 1이 반환됩니다. (비었으면 NoSuchElementException 발생)
    Object element()삭제 없이 요소를 읽어옵니다. (peek와 달리 Queue가 비었을 때 NoSuchElementException 발생)
    Boolean offer(Object o)Queue에 객체를 저장합니다.
    Object poll()Queue에서 객체를 꺼내서 반환합니다. (저장된 건 삭제) 비어 있으면 null이 반환됩니다.
    Object peek()삭제 없이 요소를 읽어옵니다. 비어있으면 null이 반환됩니다.
    -
    - 이 메서드를 보면 서로 비슷한데 뭔 차이지 싶을 겁니다.
    - 자세히 정리해보자면 다음과 같습니다.

    - - - - - - - - - - - - - - - - - - - - - - -
    예외발생메서드값출력
    추가add()offer()
    삭제remove()poll()
    읽기element()peek()
    -
    - 두 비슷한 메서드들은 문제가 발생했을 시 예외를 발생시키느냐, null 또는 false를 반환하느냐의 차이입니다.
    - 큐에 값을 추가하는데 큐가 꽉 찼을 시 add()는 예외를 발생시키고, offer는 추가 실패를 의미하는 false를 반환합니다. -

    - 큐와 스택은 삽입과 삭제에는 O(1), 탐색에는 O(n)의 시간 복잡도를 가집니다.



    - -

    우선순위 큐(Priority Queue)

    - 우선 순위 큐 알고리즘 그림
    - 우선 순위 큐의 각 요소는 값과 우선 순위, 총 2개의 데이터를 가지고 있습니다.
    - 선형 큐와는 달리 저장한 순서에 관계없이 우선순위(priority)가 높은 요소일수록 먼저 삭제되는 특징을 가지고 있습니다.
    - 우선순위가 같은 데이터일 경우 삽입 순서를 따릅니다.

    - - PriorityQueue는 null은 저장할 수 없으며, null을 저장할 시 NullPointerException이 발생합니다
    - PrioryityQueue는 저장공간을 배열을 사용하며, 각 요소를 “힙(heap)”이라는 자료구조의 형태로 저장합니다.
    - 힙(heap)은 가장 큰 값이나 가장 작은 값을 빠르게 찾을 수 있다는 특징을 가집니다.

    - - 우선순위 큐는 어떻게 구현하느냐에 따라 시간복잡도가 달라지지만 힙을 기준으로 한다면 삽입과 삭제에는 O(logn), 우선순위가 가장 높은 요소를 탐색할 때는 O(1)만큼의 시간복잡도를 가집니다.

    -
    Queue pq=new PriorityQueue();
    -

    -
    class PriorityQueueEx {
    +  
    + +

    스택과 큐

    + +
    +
    +

    알고리즘 게시판 본문 내용

    +
    + +

    + + 안녕하세요! 도우미입니다!
    + 오늘은 스택과 큐 개념 및 스택, 큐 알고리즘을 이용한 문제 예제들을 소개해드릴까 합니다.
    + 스택과 큐는 코딩테스트에서 굉장히 자주 쓰이는 자료구조입니다. +

    + 우선 스택과 큐의 개념에 대해서 설명해드릴게요.

    + +

    Stack

    + 스택 알고리즘 그림 +
    스택(stack)이란 쌓아 올린다는 것을 의미합니다.

    + 스택은 가장 마지막에 저장된 데이터가 가정 먼저 삭제되는 후입선물(LIFO, Last In First Out)구조 입니다. 그렇기 때문에 + 한쪽 방향에서만 데이터의 + 삽입과 삭제가 가능합니다.

    + + 간단한 예시로는 포개 둔 일회용 종이컵을 하나하나 꺼내서 사용하는 것으로 예시를 들 수 있을 것 같네요.


    + +

    Stack의 메서드


    + + + + + + + + + + + + + + + + + + + + + + + + + +
    메서드설명
    Boolean empty()Stack이 비어있는지 알려줍니다.
    Object peek()스택의 맨 위에 저장된 객체를 반환합니다. 그림상에서는 요소 4가 해당됩니다. (비었다면 EmptyStackException발생)
    Object push(Object o)데이터를 삽입하는 연산입니다. 삽입된 데이터는 삭제 시 가장 먼저 삭제 될 데이터가 됩니다. (비었다면 EmptyStackException발생)
    Object pop()데이터를 삭제하는 연산입니다. 가장 최근에 저장된 데이터가 삭제됩니다.
    Int search(Object o)스택에 주어진 객체(o)를 찾아서 그 위치를 반환합니다. 못 찾으면 -1을 반환합니다. (배열과 달리 위치는 0이 아닌 1부터 시작합니다.)
    + +


    +

    Queue

    + 큐 알고리즘 그림 +
    Queue의 사전적 의미는 줄, 또는 줄을 서서 기다리는 것을 의미합니다.

    + 일상생활에서 맛집에 줄을 서서 기다리는 것, 은행에서 먼저 온 순서대로 업무를 처리하는 것과 같이 선입선출(FIFO)방식의 자료구조를 + 말합니다.
    + 스택과 달리 한 쪽에서는 데이터 삽입, 다른 한쪽에서는 데이터의 삭제만 가능합니다.

    + 큐는 데이터의 추가/삭제가 쉬운 LinkedList로 구현하는 것이 더 적합합니다.
    +
    Queue queue=new LinkedList();
    +

    +

    Queue의 메서드


    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    메서드설명
    Boolean add(Object o)저장된 객체를 Queue에 추가합니다. (저장공간이 부족하면 IllegalStateException 발생)
    Object remove()Queue에서 객체를 꺼내 반환합니다. 그림상에서는 1이 반환됩니다. (비었으면 NoSuchElementException 발생)
    Object element()삭제 없이 요소를 읽어옵니다. (peek와 달리 Queue가 비었을 때 NoSuchElementException 발생)
    Boolean offer(Object o)Queue에 객체를 저장합니다.
    Object poll()Queue에서 객체를 꺼내서 반환합니다. (저장된 건 삭제) 비어 있으면 null이 반환됩니다.
    Object peek()삭제 없이 요소를 읽어옵니다. 비어있으면 null이 반환됩니다.
    +
    + 이 메서드를 보면 서로 비슷한데 뭔 차이지 싶을 겁니다.
    + 자세히 정리해보자면 다음과 같습니다.

    + + + + + + + + + + + + + + + + + + + + + + +
    예외발생메서드값출력
    추가add()offer()
    삭제remove()poll()
    읽기element()peek()
    +
    + 두 비슷한 메서드들은 문제가 발생했을 시 예외를 발생시키느냐, null 또는 false를 반환하느냐의 차이입니다.
    + 큐에 값을 추가하는데 큐가 꽉 찼을 시 add()는 예외를 발생시키고, offer는 추가 실패를 의미하는 false를 반환합니다. +

    + 큐와 스택은 삽입과 삭제에는 O(1), 탐색에는 O(n)의 시간 복잡도를 가집니다.



    + +

    우선순위 큐(Priority Queue)

    + 우선 순위 큐 알고리즘 그림
    + 우선 순위 큐의 각 요소는 값과 우선 순위, 총 2개의 데이터를 가지고 있습니다.
    + 선형 큐와는 달리 저장한 순서에 관계없이 우선순위(priority)가 높은 요소일수록 먼저 삭제되는 특징을 가지고 있습니다.
    + 우선순위가 같은 데이터일 경우 삽입 순서를 따릅니다.

    + + PriorityQueue는 null은 저장할 수 없으며, null을 저장할 시 NullPointerException이 발생합니다
    + PrioryityQueue는 저장공간을 배열을 사용하며, 각 요소를 “힙(heap)”이라는 자료구조의 형태로 저장합니다.
    + 힙(heap)은 가장 큰 값이나 가장 작은 값을 빠르게 찾을 수 있다는 특징을 가집니다.

    + + 우선순위 큐는 어떻게 구현하느냐에 따라 시간복잡도가 달라지지만 힙을 기준으로 한다면 삽입과 삭제에는 O(logn), 우선순위가 가장 높은 요소를 탐색할 때는 + O(1)만큼의 시간복잡도를 가집니다.

    +
    Queue pq=new PriorityQueue();
    +

    +
    class PriorityQueueEx {
     	public static void main(String[] args) {
     		Queue pq = new PriorityQueue();
     		pq.offer(3);
    @@ -191,140 +198,141 @@ 

    우선순위 큐(Priority Queue)

    } }
    - poll로 값을 가져오면 숫자가 작은 것이 우선순위를 가져, 1 2 3 4 5 순으로 출력됩니다.



    + poll로 값을 가져오면 숫자가 작은 것이 우선순위를 가져, 1 2 3 4 5 순으로 출력됩니다.



    -

    Deque(Double-Ended Queue)

    - Deque는 양쪽 끝에 추가, 삭제가 가능합니다.
    - Deque의 조상은 Queue이고, 구현체는 ArrayDeque, LinkedList등이 있습니다.

    -
    Deque deque = new LinkedList();
    +      

    Deque(Double-Ended Queue)

    + Deque는 양쪽 끝에 추가, 삭제가 가능합니다.
    + Deque의 조상은 Queue이고, 구현체는 ArrayDeque, LinkedList등이 있습니다.

    +
    Deque deque = new LinkedList();
     Deque deque = new ArrayDeque();
     
    -
    - 스택, 큐와 같이 데이터의 삽입과 삭제에 O(1)의 시간복잡도를 가집니다.
    - -
    -

    Deque의 값 삽입


    - 덱 알고리즘 그림
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    메서드설명
    add()마지막에 원소 삽입 용량 초과 시 예외 발생
    addFirst()맨 앞에 원소 삽입 용량 초과 시 예외 발생
    addLast()마지막에 원소 삽입 용량 초과 시 예외 발생
    offer()마지막에 원소 삽입, 삽입 성공 시 true, 용량 제한에 걸리는 경우 false 반환
    offerFirst()맨 앞에 원소 삽입, 삽입 성공 시 true, 용량 제한에 걸리는 경우 false 반환
    offerLast()마지막에 원소 삽입, 삽입 성공 시 true, 용량 제한에 걸리는 경우 false 반환
    -

    - -

    Deque의 값 삭제


    - 덱 알고리즘 그림
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    메서드설명
    remove()맨 앞의 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 예외 발생
    removeFirst()맨 앞의 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 예외 발생
    removeLast()마지막 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 예외 발생
    poll()맨 앞의 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 null 리턴
    pollFirst()맨 앞의 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 null 리턴
    pollLast()마지막 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 null 리턴
    -

    - -

    Deque의 원소 확인


    - 덱 알고리즘 그림
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    메서드설명
    getFirst()맨 앞의 원소를 리턴, 덱이 비어있는 경우 예외 발생
    getLast()마지막 원소를 리턴, 덱이 비어있는 경우 예외 발생
    removeLast()마지막 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 예외 발생
    peek()맨 앞의 원소를 리턴, 덱이 비어있는 경우 null 리턴
    peekFirst()맨 앞의 원소를 리턴, 덱이 비어있는 경우 null 리턴
    peekLast()마지막 원소를 리턴, 덱이 비어있는 경우 null 리턴
    -

    - -
    -

    예제 문제


    - 스택, 큐 개념에 대해서 배웠으니 예제로 넘어가겠습니다.

    - - 1. 같은 숫자는 싫어 - -
    - 정답 보기 -
    - 자바 스택과 그 메소드를 활용하는 문제입니다.

    -
      -
    1. 1. Integer 타입으로 스택을 선언합니다.
    2. -
    3. 2. Stack의 값이 존재하지 않는 경우 (Stack.isEmpty())는 처음 배열의 요소 값을 삽입합니다.
    4. -
    5. 3. Stack의 값이 추가되어서 이를 통해 다음 배열의 요소와 비교하여 같으면 넣지 않고, 같지 않는 경우 Stack에 추가합니다.
    6. -
    7. 4. 최종적으로 Stack에서 후입선출(FIFO)에 의해 마지막 값이 먼저 출력이 되어 배열을 역순으로 순회하며 요소 값을 채워 넣습니다.
    8. -
    -
    - -
    public class Solution {
    +      
    + 스택, 큐와 같이 데이터의 삽입과 삭제에 O(1)의 시간복잡도를 가집니다.
    + +
    +

    Deque의 값 삽입


    + 덱 알고리즘 그림
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    메서드설명
    add()마지막에 원소 삽입 용량 초과 시 예외 발생
    addFirst()맨 앞에 원소 삽입 용량 초과 시 예외 발생
    addLast()마지막에 원소 삽입 용량 초과 시 예외 발생
    offer()마지막에 원소 삽입, 삽입 성공 시 true, 용량 제한에 걸리는 경우 false 반환
    offerFirst()맨 앞에 원소 삽입, 삽입 성공 시 true, 용량 제한에 걸리는 경우 false 반환
    offerLast()마지막에 원소 삽입, 삽입 성공 시 true, 용량 제한에 걸리는 경우 false 반환
    +

    + +

    Deque의 값 삭제


    + 덱 알고리즘 그림
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    메서드설명
    remove()맨 앞의 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 예외 발생
    removeFirst()맨 앞의 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 예외 발생
    removeLast()마지막 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 예외 발생
    poll()맨 앞의 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 null 리턴
    pollFirst()맨 앞의 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 null 리턴
    pollLast()마지막 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 null 리턴
    +

    + +

    Deque의 원소 확인


    + 덱 알고리즘 그림
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    메서드설명
    getFirst()맨 앞의 원소를 리턴, 덱이 비어있는 경우 예외 발생
    getLast()마지막 원소를 리턴, 덱이 비어있는 경우 예외 발생
    removeLast()마지막 원소 제거 후 해당 원소를 리턴, 덱이 비어있는 경우 예외 발생
    peek()맨 앞의 원소를 리턴, 덱이 비어있는 경우 null 리턴
    peekFirst()맨 앞의 원소를 리턴, 덱이 비어있는 경우 null 리턴
    peekLast()마지막 원소를 리턴, 덱이 비어있는 경우 null 리턴
    +

    + +
    +

    예제 문제


    + 스택, 큐 개념에 대해서 배웠으니 예제로 넘어가겠습니다.

    + + 1. 같은 숫자는 싫어 + +
    + 정답 보기 +
    + 자바 스택과 그 메소드를 활용하는 문제입니다.

    +
      +
    1. 1. Integer 타입으로 스택을 선언합니다.
    2. +
    3. 2. Stack의 값이 존재하지 않는 경우 (Stack.isEmpty())는 처음 배열의 요소 값을 삽입합니다.
    4. +
    5. 3. Stack의 값이 추가되어서 이를 통해 다음 배열의 요소와 비교하여 같으면 넣지 않고, 같지 않는 경우 Stack에 추가합니다.
    6. +
    7. 4. 최종적으로 Stack에서 후입선출(FIFO)에 의해 마지막 값이 먼저 출력이 되어 배열을 역순으로 순회하며 요소 값을 채워 넣습니다.
    8. +
    +
    + +
    public class Solution {
         public int[] solution(int[] arr) {
            Stack<Integer> stack = new Stack<>();
            for (int i : arr) {
    @@ -345,27 +353,32 @@ 

    예제 문제


    } }
    -
    -
    -
    -
    - - - - 2. 기능개발 - -
    - 정답 보기 -
    - 자바 큐와 그 메소드를 활용하는 문제입니다.

    -
      -
    1. 1. Integer 타입의 LinkedList로 큐를 선언합니다.
    2. -
    3. 2. 해당 큐에 기능 구현에 필요한 작업 일 수 (Math.ceil((100.0 - progresses[i]) / speeds[i])))를 삽입합니다.
    4. -
    5. 3. 큐에 있는 요소(작업 일 수)를 꺼내서(poll) 남은 큐의 맨앞 값(peek)과 비교합니다. 뒤에 있는 기능이 먼저 개발 완료된다 하더라도 앞에 있는 기능이 먼저 완료되어야만 함께 배포가 가능하기 때문입니다.
    6. -
    7. 4. 비교를 하여 크다면 배포 가능 기능 개수를 증가하고(cnt++) 작다면 해당 개수를 정답 리스트에 담습니다.
    8. -
    -
    -
    public int[] solution(int[] progresses, int[] speeds) {
    +          
    +
    +
    +
    + + + + 2. 기능개발 + +
    + 정답 보기 +
    + 자바 큐와 그 메소드를 활용하는 문제입니다.

    +
      +
    1. 1. Integer 타입의 LinkedList로 큐를 선언합니다.
    2. +
    3. 2. 해당 큐에 기능 구현에 필요한 작업 일 수 (Math.ceil((100.0 - progresses[i]) / speeds[i])))를 + 삽입합니다. +
    4. +
    5. 3. 큐에 있는 요소(작업 일 수)를 꺼내서(poll) 남은 큐의 맨앞 값(peek)과 비교합니다. 뒤에 있는 기능이 먼저 개발 완료된다 하더라도 앞에 + 있는 기능이 먼저 완료되어야만 함께 배포가 가능하기 때문입니다. +
    6. +
    7. 4. 비교를 하여 크다면 배포 가능 기능 개수를 증가하고(cnt++) 작다면 해당 개수를 정답 리스트에 담습니다.
    8. +
    +
    +
    public int[] solution(int[] progresses, int[] speeds) {
         Queue<Integer> queue = new LinkedList<>();
         List<Integer> answer = new ArrayList<>();
     
    @@ -387,28 +400,29 @@ 

    예제 문제


    }
    -
    -
    -
    - - - - 3. 명예의 전당 - -
    - 정답 보기 -
    - 자바 우선순위 큐와 그 메소드를 활용하는 문제입니다.

    -
      -
    1. 1. 데이터 처리를 수행하려는 배열을 순회합니다.
    2. -
    3. 2. 우선순위 큐에 값을 넣습니다. : pg.add(score[j]) (* 우선순위(값)에 따라 정렬이 됩니다)
    4. -
    5. 3. k 값이 우선순위 큐의 사이즈보다 작은 경우 맨 앞의 요소를 결과값으로 반환합니다. (제거 X) : pg.peek()
    6. -
    7. 4. k 값이 우선순위 큐의 사이즈보다 큰 경우에는 배열에 값을 넣고, 배열 안에서 제일 작은 값을 제거합니다 : pg.poll()
    8. -
    9. 5. 배열의 작은 값을 반환합니다. pg:peek()
    10. -
    11. 6. 해당 작업들을 통해서 최종적으로 배열을 구성합니다.
    12. -
    -
    -
    class Solution {
    +        
    +
    +
    + + + + 3. 명예의 전당 + +
    + 정답 보기 +
    + 자바 우선순위 큐와 그 메소드를 활용하는 문제입니다.

    +
      +
    1. 1. 데이터 처리를 수행하려는 배열을 순회합니다.
    2. +
    3. 2. 우선순위 큐에 값을 넣습니다. : pg.add(score[j]) (* 우선순위(값)에 따라 정렬이 됩니다)
    4. +
    5. 3. k 값이 우선순위 큐의 사이즈보다 작은 경우 맨 앞의 요소를 결과값으로 반환합니다. (제거 X) : pg.peek()
    6. +
    7. 4. k 값이 우선순위 큐의 사이즈보다 큰 경우에는 배열에 값을 넣고, 배열 안에서 제일 작은 값을 제거합니다 : pg.poll()
    8. +
    9. 5. 배열의 작은 값을 반환합니다. pg:peek()
    10. +
    11. 6. 해당 작업들을 통해서 최종적으로 배열을 구성합니다.
    12. +
    +
    +
    class Solution {
         public int[] solution(int k, int[] score) {
         int[] answer = new int[score.length];
     
    @@ -428,23 +442,25 @@ 

    예제 문제


    } }
    -
    -
    -
    - 예제를 풀어보니 스택과 큐를 어떻게 활용해야할 지 조금 감이 오지 않나요?

    - 끝으로, 오르미 여러분들의 실력을 더욱 향상 시킬 수 있는 스택, 큐 관련 문제들 추천해드리겠습니다.

    -
    -
    + +
    + 예제를 풀어보니 스택과 큐를 어떻게 활용해야할 지 조금 감이 오지 않나요?

    + 끝으로, 오르미 여러분들의 실력을 더욱 향상 시킬 수 있는 스택, 큐 관련 문제들 추천해드리겠습니다.

    + +
    +
    - +
    \ No newline at end of file diff --git a/src/main/resources/templates/algorithm/timeComplexity.html b/src/main/resources/templates/algorithm/timeComplexity.html index 90e83a8..f4021d2 100644 --- a/src/main/resources/templates/algorithm/timeComplexity.html +++ b/src/main/resources/templates/algorithm/timeComplexity.html @@ -1,62 +1,64 @@ - - Doumi - - - - + + Doumi + + + + - - - - - + + + + +
    -
    - -

    시간 복잡도

    - -
    -
    -

    퀴즈 게시판 본문 내용

    -
    -

    -  안녕하세요. 앞으로 코딩테스트에 대해 알려드릴 도우미라고 합니다!
    - 오늘은 코딩테스트에서 기본이 되는 시간복잡도에 대해 알려 드릴게요.

    +
    + +

    시간 복잡도

    + +
    +
    +

    퀴즈 게시판 본문 내용

    +
    +

    +  안녕하세요. 앞으로 코딩테스트에 대해 알려드릴 도우미라고 합니다!
    + 오늘은 코딩테스트에서 기본이 되는 시간복잡도에 대해 알려 드릴게요.

    -  시간복잡도를 계산하는 이유에 대해 먼저 알려드릴게요.
    - 프로그램이 수행되는 시간을 알기위한 방법은 간단합니다.
    - 실행해보고 실행시간을 측정하면 되죠! 제일 정확한 방법입니다.

    +  시간복잡도를 계산하는 이유에 대해 먼저 알려드릴게요.
    + 프로그램이 수행되는 시간을 알기위한 방법은 간단합니다.
    + 실행해보고 실행시간을 측정하면 되죠! 제일 정확한 방법입니다.

    -  그렇다면 프로그램을 수행해보지 않고도 쉽게 아는 방법은 없을까요? 그래서 나온 개념이 시간복잡도 입니다.

    -
    -
        문제에는 - 시간과 공간의 제한이 존재한다. -
    -
    - 앞으로 시작하려는 프로그래밍 테스트에는 제한 시간이라는게 존재해요. 시간 내에 수행되어야 하는건데요.
    - 코딩테스트를 문제의 답을 힘들게 구현 했는데 수행을 해보니 출력결과는 맞았더라도 시간초과가 됬다고 할게요.
    - 처음부터 시간초과가 나지 않도록 잘 설계, 계획해서 문제를 풀어야 겠죠? 시간복잡도 라는걸 잘 이해하신다면 가능해요. - 이 프로그램 수행시간에 대해 직접 실행해 보지 않고도 알 수 있는 개념이 시간 복잡도이고 주로 빅오라는걸 사용해서 - 표현 하는데 이는 뒤에서 알려드릴게요!
    -

    "시간 복잡도로 프로그램을 직접 실행시키지 않고도 대략적인 수행시간을 알 수 있다"

    -
    -  먼저 연산 횟수를 세는것부터 해볼게요. 연산횟수란 연산자가 몇번 적용되었는지 세는거에요.
    -
    +       그렇다면 프로그램을 수행해보지 않고도 쉽게 아는 방법은 없을까요? 그래서 나온 개념이 시간복잡도 입니다.

    +
    +
        문제에는 + 시간과 공간의 제한이 존재한다. +
    +
    + 앞으로 시작하려는 프로그래밍 테스트에는 제한 시간이라는게 존재해요. 시간 내에 수행되어야 하는건데요.
    + 코딩테스트를 문제의 답을 힘들게 구현 했는데 수행을 해보니 출력결과는 맞았더라도 시간초과가 됬다고 할게요.
    + 처음부터 시간초과가 나지 않도록 잘 설계, 계획해서 문제를 풀어야 겠죠? 시간복잡도 라는걸 잘 이해하신다면 가능해요. + 이 프로그램 수행시간에 대해 직접 실행해 보지 않고도 알 수 있는 개념이 시간 복잡도이고 주로 빅오라는걸 사용해서 + 표현 하는데 이는 뒤에서 알려드릴게요!
    +

    "시간 복잡도로 프로그램을 직접 실행시키지 않고도 대략적인 수행시간을 알 수 있다"

    +
    +  먼저 연산 횟수를 세는것부터 해볼게요. 연산횟수란 연산자가 몇번 적용되었는지 세는거에요.
    +
      void func(int n) {
       int a = 0;     // 대입연산 1회
       int b = 0;       // 대입연산 1회
    @@ -68,28 +70,28 @@ 

    "시간 복잡도로 프로그램을 직접 실행시키지 않고도 대략 b += i; // 덧셈 연산 n회 } }

    -  위 함수에서 연산 횟수를 세보면 4n+5회 하였다고 볼수 있는데요.
    - 예제를 몇개 더 연습해 볼게요.

    -
     combination(A[], n) {
    +       위 함수에서 연산 횟수를 세보면 4n+5회 하였다고 볼수 있는데요.
    + 예제를 몇개 더 연습해 볼게요.

    +
     combination(A[], n) {
         sum <- 0;
         for i <- 0 to n-1
             for j <- i + 1 to n-1
                 print(i, j)
     }
    -  위에서 예제는 조합의 개수를 구할 때 자주 사용하는 식인데요.
    - A = [1, 2, 3, 4]라면 (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)가 출력 되는데요. - (대입 연산, 비교연산, 증감연산은 생략하고 간략히 for문 도는 횟수만 세도록 할게요.) - 위 식에서 연산의 개수를 한번 세보면 i=0 일 때 j는 n-1번, i=1일 때 j는 n-2번, i=2일 때 j는 n-3번 ... i=n-1일 때 j는 0번 - 돌게 됩니다. 다 더해보면 0+1+2+...+(n-1) = (n-1)*(n-2)/2 = (n^2-3*n+2)/2 번 for문을 도네요! -

    -
     MenOfPassion() {
    +       위에서 예제는 조합의 개수를 구할 때 자주 사용하는 식인데요.
    + A = [1, 2, 3, 4]라면 (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)가 출력 되는데요. + (대입 연산, 비교연산, 증감연산은 생략하고 간략히 for문 도는 횟수만 세도록 할게요.) + 위 식에서 연산의 개수를 한번 세보면 i=0 일 때 j는 n-1번, i=1일 때 j는 n-2번, i=2일 때 j는 n-3번 ... i=n-1일 때 j는 0번 + 돌게 됩니다. 다 더해보면 0+1+2+...+(n-1) = (n-1)*(n-2)/2 = (n^2-3*n+2)/2 번 for문을 도네요! +

    +
     MenOfPassion() {
         for i <- 1 to n
             for j <- 1 to n
                 for k <- 1 to n
                     print(i, j, k)
     }
     
     위 식은 n*3의 연산을 수행해야 해요.

    -
    +      
      MenOfPassion(A[], n, target) {
         sum <- 0;
         for i <- 1 to n
    @@ -98,28 +100,28 @@ 

    "시간 복잡도로 프로그램을 직접 실행시키지 않고도 대략 return -1 }

     시간 복잡도의 경우에 최선의 경우, 평균적인 경우, 최악의 경우 3가지의 경우가 있는데요.
    - 위의 식과 같이 target에 해당하는 데이터가 마지막에 있을 경우 즉, 최악인 경우 n개의 데이터를 다 살펴봐야 하는데요.
    - 좀 더 정확히 연산 횟수를 세서 3n+4와 같은 연산 횟수를 얻었다고 해요
    - 이제 등장할 빅오라는 개념에서 3n+4 에서 3과 4는 중요하지 않아요.
    - 이유는 n이 상당히 클 경우 n+3, 23*n+21, n^2, 23*n^2+21은 결국
    - n < nlogn < n^2 < n^3 과 같이 각 대표적인 클래스에 따라 값의 크기가 결정 되기 때문이에요.

    -
    -
     n값이 커지면 결국 계수나 상수와 상관 없이 - 대표적인 클래스에 해당하는 비교가 된다. -
    -

    "그럼 빅오라는 개념을 코딩테스에서 언제 사용하면 돼?"

    -  그에 대한 답은 아래와 같은 절차를 보면 알 수 있다.우리가 구현할 코드의 코드의 빅오를 파악한다.
    - n^2의 코드가 되었다면 해당 n을 대입하여 값을 매겨본다. 예를 들어 n=10,000 이라고 하자.
    - 10,000^2 = 100,000,000 이고 1억의 값이 나오게 된다. 1억번에 1초라고 생각하면 된다.
    - 시간 제한에 걸리는지 확인할 수 있게 되는 것이다.
    -
    -  마지막으로 한가지를 덧붙이면 시간복잡도와 마찬가지로 공간복잡도 라는 개념이 있고 시간복잡도와 마찬가지로 메모리 영역을 차지하는 수 로 - 계산하면 된다. 메모리 공간 제한을 두고 있는 문제가 있긴 하지만 자주 사용되지는 않는다. -
    -
    + 위의 식과 같이 target에 해당하는 데이터가 마지막에 있을 경우 즉, 최악인 경우 n개의 데이터를 다 살펴봐야 하는데요.
    + 좀 더 정확히 연산 횟수를 세서 3n+4와 같은 연산 횟수를 얻었다고 해요
    + 이제 등장할 빅오라는 개념에서 3n+4 에서 3과 4는 중요하지 않아요.
    + 이유는 n이 상당히 클 경우 n+3, 23*n+21, n^2, 23*n^2+21은 결국
    + n < nlogn < n^2 < n^3 과 같이 각 대표적인 클래스에 따라 값의 크기가 결정 되기 때문이에요.

    +
    +
     n값이 커지면 결국 계수나 상수와 상관 없이 + 대표적인 클래스에 해당하는 비교가 된다. +
    +

    "그럼 빅오라는 개념을 코딩테스에서 언제 사용하면 돼?"

    +  그에 대한 답은 아래와 같은 절차를 보면 알 수 있다.우리가 구현할 코드의 코드의 빅오를 파악한다.
    + n^2의 코드가 되었다면 해당 n을 대입하여 값을 매겨본다. 예를 들어 n=10,000 이라고 하자.
    + 10,000^2 = 100,000,000 이고 1억의 값이 나오게 된다. 1억번에 1초라고 생각하면 된다.
    + 시간 제한에 걸리는지 확인할 수 있게 되는 것이다.
    +
    +  마지막으로 한가지를 덧붙이면 시간복잡도와 마찬가지로 공간복잡도 라는 개념이 있고 시간복잡도와 마찬가지로 메모리 영역을 차지하는 수 로 + 계산하면 된다. 메모리 공간 제한을 두고 있는 문제가 있긴 하지만 자주 사용되지는 않는다. +
    +
    - + \ No newline at end of file diff --git a/src/main/resources/templates/codingTest/index.html b/src/main/resources/templates/codingTest/index.html index c94dc6d..deab45b 100644 --- a/src/main/resources/templates/codingTest/index.html +++ b/src/main/resources/templates/codingTest/index.html @@ -6,7 +6,8 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> DoumiCoteMain - + @@ -57,20 +58,20 @@ diff --git a/src/main/resources/templates/myPage/myPage.html b/src/main/resources/templates/myPage/myPage.html index 7e62f31..f7dfb34 100644 --- a/src/main/resources/templates/myPage/myPage.html +++ b/src/main/resources/templates/myPage/myPage.html @@ -3,7 +3,8 @@ MyPage - + @@ -23,30 +24,26 @@

    + + + + - -
    -
    -
      -
      - - - - -
      @@ -54,6 +51,5 @@

      - \ No newline at end of file diff --git a/src/main/resources/templates/myPage/myPageCodingTest.html b/src/main/resources/templates/myPage/myPageCodingTest.html index 63e1c68..94060ca 100644 --- a/src/main/resources/templates/myPage/myPageCodingTest.html +++ b/src/main/resources/templates/myPage/myPageCodingTest.html @@ -1,42 +1,98 @@ -
    • -
      번호
      -
      제목
      -
      작성자
      -
      작성일
      - -
    • + + + + + MyPage + + + + + - + + + + +
      - \ No newline at end of file + + + + \ No newline at end of file diff --git a/src/main/resources/templates/myPage/myPageComment.html b/src/main/resources/templates/myPage/myPageComment.html index 029a6d2..2bd82a4 100644 --- a/src/main/resources/templates/myPage/myPageComment.html +++ b/src/main/resources/templates/myPage/myPageComment.html @@ -1,44 +1,154 @@ -
    • -
      번호
      -
      댓글 내용
      -
      작성자
      -
      최근 수정일
      -
    • - -
        -
      • -
        - -
        작성자
        -
        - 최근 수정일 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyPage + + + + + + +
        + +
        + +
        +
        + +
      • +
        번호
        +
        댓글 내용
        +
        작성자
        +
        최근 수정일
        +
      • + +
        -
      • -
      - - \ No newline at end of file + + + + +
      + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/myPage/myPageQuiz.html b/src/main/resources/templates/myPage/myPageQuiz.html index d8abfa3..ee730e6 100644 --- a/src/main/resources/templates/myPage/myPageQuiz.html +++ b/src/main/resources/templates/myPage/myPageQuiz.html @@ -1,42 +1,99 @@ -
    • -
      번호
      -
      제목
      -
      작성자
      -
      작성일
      - -
    • - - - - \ No newline at end of file + + + + +
      + + + + + \ No newline at end of file