[JAVA 백엔드 스터디] 3회차

minhyeok·2023년 2월 8일
0
post-thumbnail

학습내용

  • 반복문
  • 배열
  • List(ArrayList)
  • 제네릭

psvm + 엔터
sout + 엔터
정규표현
Next() 와 NextLine() 차이
String.format 을 이용한 소숫점 반올림
ArrayList 다양한 사용방법

예제풀이

Ex1) [구구단 프로그램]

[구구단] 몇 단을 출력하실건가요?
13
1단에서 9단까지만 출력이 가능합니다.
[구구단] 몇 단을 출력하실건가요?
8
8 * 1 = 8
8 * 2 = 16
8 * 3 = 24
8 * 4 = 32
8 * 5 = 40
8 * 6 = 46
8 * 7 = 56
8 * 8 = 64
8 * 9 = 72
[구구단] 몇 단을 출력하실건가요?
exit
프로그램을 성공적으로 종료했습니다.
import java.util.Scanner;
public class ex1 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str2 = "exit";
        for (; ; ) {
            System.out.print("[구구단] 몇 단을 출력하실건가요?");
            String str = scanner.nextLine();
            while (!str.equals(str2)) {
                int i = Integer.parseInt(str);
                if (i > 0 && i < 10) {
                    for (int j = 1; j < 10; j++) {
                        System.out.println(+i + " * " + j + " = " + i * j);
                    }
                    break;
                } else if (i < 0 || i > 10) {
                    System.out.println("1단에서 9단만 출력이 가능합니다.");
                    break;
                }
                }
            if(str.equals(str2))
            {
                System.out.println("프로그램을 성공적으로 종료했습니다.");
                break;
            }
        }
    }
}

구구단 출력이 너무 힘들었다. 구구단 자체 출력은 쉬웠지만, 입력을 받을 때 숫자와 문자열을 동시에 입력받으면 예외처리를 하라는 에러가 떠서 이거를 어떻게 처리할지에 대해 시간을 굉장히 많이 썼다.. try-catch 구문까지 써야하는지 , 아니면 문자열 과 숫자를 따로 받도록 하여 처리 할지 굉장히 머리를 많이 썼는데 결국은 String 과 int 변환과 while 구문을 통해 해결하였다.

Ex2) [ArrayList와 친해지기]

1. 정수(`int`) 데이터를 담을 빈 `ArrayList`를 만들어라.
2. `ArrayList`에 `5`, `7`, `10`, `9`, `4`라는 데이터를 차례대로 넣어라. 
3. `ArrayList`에서 `7`이라는 데이터를 삭제해라. 
4. `ArrayList`에 들어있는 두 번째 값을 조회해서 출력해라.
5. `ArrayList`를 내림차순으로 정렬해라. 
6. `for문`을 활용해서 `ArrayList`의 모든 데이터를 차례차례 출력해라. 
7. `ArrayList`안에 `11`의 값이 존재하는 지 여부를 출력해라.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class ex2 {
    public static void main(String[] args) {
        ArrayList<Integer> number = new ArrayList<Integer>();
        number.add(5);
        number.add(7);
        number.add(10);
        number.add(9);
        number.add(4);
        number.remove(1);
        System.out.println(number.get(1));
        Collections.sort(number, Collections.reverseOrder());
        //System.out.println(number); // 전체 출력
        for(Integer i : number) { //for문을 통한 전체출력
            System.out.println(i);
        }
        boolean isContains = number.contains(11);
        System.out.println(isContains);
    }
}

ArrayList에 관해 알아보는 예제였다. C++에서 배운 LinkedList 와 내용이 비슷한 느낌이라 금방 배우게 되었다. 확실히 기존 배열보다 효율적이라 생각된다. 아직 메써드가 익숙치 않아 코드를 사용해보며 익히는 중이다. add,get,remove 등과 같은 내용을 숙지해 놓아야겠다.

3회차 미션

학생들의 이름을 가나다 순으로 출력하기

학생의 이름을 입력하고 엔터를 누르세요. (한글로만 입력해야 합니다.)
학생들을 다 입력했다면, print라고 입력해주세요.
박재성
유재석
jason
학생의 이름은 한글로만 입력해야 합니다.
강호동
신동엽
print
[학생 명단(가나다순)]
강호동
박재성
신동엽
유재석
  • 배열(int[], String[] 등)을 사용하지 말고, ArrayList를 사용해라.
  • ArrayList를 사용할 때, 제네릭(Generic)을 사용해라.
  • 입력값이 한글 또는 print가 아니라면, 학생의 이름은 한글로만 입력해야 합니다.라는 문구가 출력된다.

문제 풀이

  • 조건 확인
    한글/ 영어 입력 따로 받기
    print 입력할 때 구분하기
    가나다 순으로 정렬하여 출력하기
  • 풀이 과정
    먼저, 풀이를 시작할 때 제일 처음 고민한 부분은 한글만/영어만 입력을 받는 조건이었다.
    내 짧은 기억으로는 그런 내용이 기억이 나지 않아 어떻게 구현하지 라는 고민이 많았다. 구글링 끝에, 정규표현식을 이용해보자 라는 결론이 나왔다. 정규표현식이 생소하여, 어떻게 쓰는 지 많이 찾아보았었다. 그렇게 정규표현식을 이용해 한글만 입력받는 것을 구현하였다.
    또한, 프로그램의 종료를 위한 print 를 입력 받을때와 아닐때를 구분 하였다.
    한글만 입력하는 String input 을 통해, .matches 메서드를 이용하여 한글일 경우 true 이므로 그때만 ArrayList 에 값을 추가하는게 가능하도록 코드를 작성하였다. print 를 입력할 경우, 이름을 정렬하고 출력하게 하였다.
    그리고 이 문제에서 고민했던 부분은, 주석처리한 부분이다. String str 을 입력 받을때 next() 로 받게 되면 "송 민혁" 이라는 입력은 송 / 민혁 이 다른 사람이 되고, nextLine() 으로 입력을 받게 되면 ""도 입력이 되어 학생으로 인식된다.[정확히는(\n)] 처음 고민했던 "" 가 next()로 하니 해결이 되었지만, "송 민혁" 과 같은 문제가 발생한다. 이 부분에서 시간을 되게 많이 쓰게 되었다. replaceAll 이나 "" 을 입력 받을때를 따로 처리하면 해결될 듯 하지만 시간 상 넘어가게 되었다.
  • 검색했던 키워드
    • 정규식 enter key
    • regex enter key
    • str 입력받을때 엔터 키 처리

참고 링크

팀원 분의 참고 코드
            student = student.replaceAll("(\r\n|\r|\n|\n\r)", "");
            if (student.equals("")) {
                System.out.println("학생의 이름은 한글로만 입력해야 합니다.");
                continue;
            }
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("학생의 이름을 입력하고 엔터를 누르세요. (한글만 입력해야 합니다.)");
        System.out.println("학생들을 다 입려했다면, print 라고 입력해주세요.");
        ArrayList<String> name = new ArrayList<>();

        String input = "^[가-힣]*$";
        for(;;) {
            //String str = scanner.nextLine();
            String str = scanner.next();
            while (!str.equals("print")) {
                if (str.matches(input) == true) {
                    name.add(str);
                    break;
                } else if (str.matches(input) == false) { //영어 입력일때
                    System.out.println("학생의 이름은 한글로만 입력해야 합니다.");
                    break;
                }
            }
            if (str.equals("print")) {
                System.out.println("[학생 명단(가나다순)]");
                Collections.sort(name);
                System.out.println(name);
                break;
            }
        }
    }
}

100m 달리기 선수 중 1등 찾기

선수의 번호를 입력하세요.
13
이 선수의 100m 달리기 기록이 몇 초인지 입력하세요.
13.56
선수의 번호를 입력하세요.
7
이 선수의 100m 달리기 기록이 몇 초인지 입력하세요.
15.153
선수의 번호를 입력하세요.
7
이 선수의 100m 달리기 기록이 몇 초인지 입력하세요.
12.157
선수의 번호를 입력하세요.
2
이 선수의 100m 달리기 기록이 몇 초인지 입력하세요.
14
선수의 번호를 입력하세요. 
print
1등 : 7번 선수 / 12.16초 (참가인원 : 3명)
  • 똑같은 선수 번호를 입력할 경우, 새로운 기록으로 갱신한다.
  • 100m 달리기 기록을 입력할 때, 소숫점 둘째자리까지 반올림하여 기록한다.
  • print라고 입력하면 1등의 선수를 출력한다.
  • 배열(int[], String[] 등)을 사용하지 말고, ArrayList를 사용해라.
  • ArrayList를 사용할 때, 제네릭(Generic)을 사용해라.

문제 풀이

  • 조건확인
    선수 번호 / 달리기 기록을 어떻게 기록할 것인가
    소수점 둘째자리 까지 반올림 하여 데이터 기록
    똑같은 번호의 선수 입력 받을 때 처리
    1등의 선수와 기록 정렬하여 찾기
    참가인원 수 계산
  • 풀이 과정
    일단 맨 처음 고민한 부분은, 선수 번호 와 달리기 기록을 어떤 배열로 할 것인가 였다. 맨 처음에는 선수와 기록을 각각 따로 ArrayList를 만들어 입력받아 볼려고 했다.
    그렇게 생각 했을때는 그러면 그 선수에 해당하는 점수가 기록이 될까? 해서 ArrayList 한 개를 사용해 진행해보려고 하였다.
    그래서 한개의 ArrayList 의 index(선수번호) 에 value(값) 을 집어 넣는 방식과, 2차원 배열을 생각해보았지만 , 검색도 힘들고 관련 내용도 찾기 힘들어서 멘토님에게 도움을 요청하였다.
    여쭈어 보니 처음 구상한 두개로 가는게 맞았었다..
    그래서 다시 선수(player)는 Integer 형으로, 기록(record) 는 Double 형으로 선언하였다.
    그렇게 쭉쭉 진행하는 중 입력까지 성공하였다가 다시 막힌 부분은, 1등을 출력할 때 1등은 찾았지만 1등에 해당하는 선수의 번호 출력이 문제였다. 정렬하고 난 뒤의 indexof 나 get 을 이용하여 구해보려 하였지만, 내 머리로는 한계에 봉착했다..
    또한 참가인원 수 를 구현할 때 7번 선수를 2번 입력하면 2명으로 인식되는 문제가 발생하여 고민이 되었다. 이 부분은 원래 player.size()로 해결할려고 했었는데 이 방법은 실패하였다.
    다시 한번 멘토님께 여쭈어 보았다 ..
    두 가지 체크포인트에 관한 조언을 얻었다.
    <정렬 전 list 와 정렬 후 list 를 저장하여 그 둘을 통한 1등 기록을 가지고 정렬하기 전 인덱스 값을 활용해 선수 번호 찾기>
    < arraylist에 선수 번호를 넣기 전에 동일한 번호 확인하고, 만약 동일한 값이 있다면 기존 값을 지우고 새로 입력하는 로직 추가>
    이 두 가지를 짚어 주시고 나니 해결해야할 길이 보였다. 정말 감사합니다 !!
    그리하여 정렬하기 전 record 의 list를 새로운 record2 라는 list 에 저장해두었다.
    그 뒤, 정렬을 하고 정렬한 리스트(record) 에서 0번째 index 에 해당하는 값이 1등의 기록일 것이다.
    따라서 그 값을 find 라는 변수에 저장하여, 정렬하기 전 record2 리스트에서 find 값(1등 값)을 가진 index를 찾아 set 이라는 변수에 저장하였다.
    그리하여 최종 출력에서 1등의 선수 번호는 기존의 player 리스트에서 get(set) 을 이용해 1등 값을 가진 선수의 번호를 찾고, 1등 값은 정렬된 record 리스트에서 get(0) 이다.(find 로 적어도 무방할 것이라 생각된다) 이렇게 1등 선수의 번호와 1등 기록을 찾았다.
    참가인원 수도 문제였는데, 그냥 count 라는 변수를 따로 설정해주어 player 리스트를 add 하거나 remove 할때마다 count 를 ++,-- 하게 하여 참가 인원 수를 계산하였다.
    사실 코드가 조금 조잡하다고 생각되긴 하지만, 어쨌거나 잘 돌아가니까,, 나중에 시간이 되면 조금 더 깔끔하게 작성해보아야겠다.
import java.util.*;
public class hw2 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        ArrayList<Integer> player = new ArrayList<>();
        ArrayList<Double> record = new ArrayList<>();
        int count=0; // 참가인원수
        for(;;) {
            System.out.println("선수의 번호를 입력하세요.");
            String number = scanner.next();
            while (!number.equals("print")) {
                int i = Integer.parseInt(number);
                boolean isContains = player.contains(i);
                if(isContains != false) { // 이전과 똑같은 선수 번호 입력일때
                    player.remove("i");
                    record.remove("i");
                    count --;
                    player.add(i);
                    count ++;
                    System.out.println("이 선수의 100m 달리기 기록이 몇 초인지 입력하세요.");
                    double rec = scanner.nextDouble();
                    double time = Double.parseDouble(String.format("%.2f", rec));
                    record.add(time);
                    break;
                }else if(isContains == false){ // 이전과 다른 선수 번호 입력일때
                    player.add(i);
                    count ++;
                    System.out.println("이 선수의 100m 달리기 기록이 몇 초인지 입력하세요.");
                    double rec = scanner.nextDouble();
                    double time = Double.parseDouble(String.format("%.2f", rec));
                    record.add(time);
                    break;
                }
            }
            if(number.equals("print")){
                ArrayList<Double> record2 = new ArrayList<>();
                for(Double j : record) {// 정렬하기 전 리스트 저장
                    record2.add(j);
                }
                Collections.sort(record); // 정렬
                double find = record.get(0);// 정렬한 리스트에서 1등에 해당하는 값 찾기
                int set = record2.indexOf(find); // 1등 값을 가진 정렬 전 리스트에서 인덱스 찾기

                System.out.println("1등 : " + player.get(set) + "번 선수 / " + record.get(0) + "초 (참가인원 : " + count + "명)");
                break;
            }
        }
    }
}


3회차 심화미션

추후 작성 예정,,

JCF에 대해 설명해주세요.

  • 힌트
    • JCF가 무엇인지 한 줄로 요약해서 설명할 수 있어야 한다.
    • JCF를 사용하는 이유 또는 장점을 설명할 수 있어야 한다.

제네릭(Generic)에 대해 설명해주세요.

  • 힌트
    • 제네릭(Generic)이 무엇인지 한 줄로 요약해서 설명할 수 있어야 한다.
    • 제네릭(Generic)을 사용하는 이유 또는 장점을 설명할 수 있어야 한다.

String, StringBuilder, StringBuffer 각각의 차이에 대해 설명해주세요.

  • 힌트
    • 불변 객체
    • 멀티쓰레드

정리

  • 배운 내용, 깨달은 점
    이번 3회차의 학습 키워드는 반복문, 배열, List(ArrayList), 제네릭 이였다.
    ArrayList를 특히 많이 배우게 되었다. 다양한 메서드를 좀 더 활용하는 법을 숙지해야겠다.
    확실히 다 알려주시는 것보다는 스스로 찾아보도록 스터디를 진행하실려고 생각하신다는 게
    미션에서 많이 느껴졌다. 키워드만 공부해와서는 조금 힘든 부분들이 있었지만 도움이 크게 되었다.
    2회차 보다 시간도 훨씬 많이 쓰고, 구글링도 엄청 많이 하게 되었다.
    멘토님의 도움도 많이 받게 되었는데, 확실히 멘토님이 방향을 정해주시니 훨씬 효율적으로 코드를 작성하는 부분에서 도움이 되었다.

  • 어려웠던 점, 반성하고 싶은 점 / 개선할 방법
    당황했던 점은 1번 문제에서 정규표현식과 같은 부분은 배우지 않아서, 한글/영어 입력만 처리하는 방법같은 부분을 되게 많이 고민했었다. 2번 문제에서는 멘토님의 도움을 많이 받았는데, 굉장히 효율적으로 캐치해주셔서 도움이 크게 되었다.
    지금까지는 아는 내용이 대부분이라 그때 그때 필요한 부분을 공부한 시간이 더 컸는데, 점점 더 모르는 내용이 나오고 있어 공부를 더 많이 해와야 할 필요성을 느꼈다.

  • 궁금한 점
    코드가 제대로 돌아가긴 하지만 조금 더 깔끔하게 작성할 수 있도록 멘토님의 코드나 다른 팀원분들과 코드를 미션 제출이 끝난 뒤 비교해보고 싶습니다!
    그리고 ArrayList 에서 ,
    2번 문제를 예시로 들면 player.remove("i") 라거나 player.remove(i) 와 같은 부분
    player.get(set) 라거나 record.get(0) 과 같은 ()에 들어가는 인자? 부분은 사실 저는 이것 저것 막 넣어보면서 제가 원하는 값을 찾아보는 형식으로 많이 진행하였습니다.
    반환하는 값(인자) 에 대한 내용은 대강 숙지하고 있지만 이런 부분을 제가 하는 방식으로 하는 것도 괜찮을까요? record.get(indexof(set)) 막 이런 식으로 넣어보기도 하면서 안되면 다시 다른 값을 넣어보는 것 보다는 아무래도 확실하게 공부하는 부분이 더 도움이 되겠지요?

그리고 다시 한번 늦은 시각에도 질문에 답변 해주셔서 매번 감사합니다!
혼자서는 공부를 잘 하지 못해 스터디를 신청하였는데, 너무나 잘한 결정이라고 생각합니다!
공부도 열심히 하게 되고 큰 도움이 되네요 ㅎㅎ 정말 감사합니당! 😄

1개의 댓글

comment-user-thumbnail
2023년 2월 13일

이번 미션 많이 어려우셨을텐데 포기하지 않고 끝까지 잘 수행해주셨네요👍👏 이번 3회차 미션에 대한 코드는 추후 톡방에서 공지 또는 클래스에서 다시 설명드리겠습니다!! 고생하셨습니다:)

[궁금한 점]
Q. 코드가 제대로 돌아가긴 하지만 조금 더 깔끔하게 작성할 수 있도록 멘토님의 코드나 다른 팀원분들과 코드를 미션 제출이 끝난 뒤 비교해보고 싶습니다!
A. 4회차 클래스 시간에 제가 직접 코드 작성하는 형태 보여드리도록 할게요:) 참고하시고 비교해보시면 좋을 것 같네요~~~

Q. 그리고 ArrayList 에서 , 2번 문제를 예시로 들면 player.remove("i") 라거나 player.remove(i) 와 같은 부분 player.get(set) 라거나 record.get(0) 과 같은 ()에 들어가는 인자? 부분은 사실 저는 이것 저것 막 넣어보면서 제가 원하는 값을 찾아보는 형식으로 많이 진행하였습니다. 반환하는 값(인자) 에 대한 내용은 대강 숙지하고 있지만 이런 부분을 제가 하는 방식으로 하는 것도 괜찮을까요? record.get(indexof(set)) 막 이런 식으로 넣어보기도 하면서 안되면 다시 다른 값을 넣어보는 것 보다는 아무래도 확실하게 공부하는 부분이 더 도움이 되겠지요?
A. 이것저것 넣어보시면서 장난감 가지고 놀듯이 테스트 해보시는 것 굉장히 좋습니다! 이 과정을 거치게 된다면 훨씬 빠르게 학습하실 수 있습니다. 하지만 이에 추가적으로 같이 해야하는 작업이 실제 그 메서드의 정확한 사용법을 찾아보고 같이 정리 하시는 작업도 중요합니다~!

답글 달기