TIL Java

내일배움캠프 16일차 TIL _ 4주 2일차

mad038 2024. 5. 8. 15:00

 

  • 오늘 있었던 일
    • 팀과제 및 알고리즘

팀과제

     ●  리팩토링

더보기

● 해당 문을

 // 수강생 생성
    public static void studentNew() {
        while (true){
            Scanner scanner = new Scanner(System.in);

            // ID값 등록
            int studentId = DataRegistry.getStudentId();

            // 이름 등록
            System.out.print("\n학생이름을 입력해주세요 name: ");
            String studentName = scanner.next();

            // 과목 등록
            Set<Integer> studentSubjects_list_test = new HashSet<>();
            List<Subject> studentSubjects_list = new ArrayList<>();
            boolean SubjectsMain = false;
            boolean SubjectsSub  = false;
            String test_int = "^[0-9]*$";

            System.out.println("\n 등록할 과목을 입력해 주세요 \n 최소 3개 이상의 필수 과목, 2개 이상의 선택 과목");
            while (true) {
                if (!SubjectsMain) System.out.print("필수 과목 : 1.Java , 2.객체지향 , 3.Spring , 4.JPA , 5.MySQL  \n 입력해주세요 : ");
                else if (!SubjectsSub) System.out.print("선택 과목 : 1.디자인 패턴 , 2.Spring Security , 3.Redis , 4.MongoDB \n 입력해주세요 :  ");
                else System.out.print( "\n 상태입력 1, RED 2, YELLOW 3,GREEN : ");

                String subjectName = scanner.next();
                // 문자열을 감지해 => 정수값

                int subjectId = 0;
                if (subjectName.matches(test_int)) {
                    subjectId = Parser.parseId(subjectName);
                }

                if (!SubjectsMain) {
                    // 메인
                    SubjectsMain = studentNewSubjectsMain( studentSubjects_list_test, subjectId, studentSubjects_list );
                }else if (!SubjectsSub) {
                    //서브
                    SubjectsSub = studentNewSubjectsSub( studentSubjects_list_test, subjectId, studentSubjects_list );
                }else if(subjectId <= 3) {
                    // 상태
                    StateType stateType = studentNewStateType(subjectId);
                    // 생성 완료
                    DataRegistry.addStudent( new Student(studentId ,studentName, studentSubjects_list,stateType));
                    break;
                }else {
                    System.out.println("지정 범위내의 값을 입력해 주세요");
                }
            }

            System.out.print("\n 추가를 끝내시겠습니까?  끝내기 = (n) 추가 = (y) \n 입력해 주세요 : ");
            String next = scanner.next();
            if (next.equals("n")) {
                break;
            }
        }
    }

    // 매인 수업
    private static boolean studentNewSubjectsMain(Set<Integer> studentSubjects_list_test, int subjectId, List<Subject> studentSubjects_list) {
        boolean SubjectsMain = false;
        if (studentSubjects_list_test.contains( subjectId )) {
            System.out.println(" 이미 등록하신 과목입니다.");
        } else if (subjectId == 99) {
            SubjectsMain = true;
            studentSubjects_list_test.clear();
        }else {
            studentSubjects_list_test.add( subjectId );
            switch (subjectId) {
                case 1 -> studentSubjects_list.add( DataRegistry.getSubjects().get( 0));
                case 2 -> studentSubjects_list.add( DataRegistry.getSubjects().get( 1));
                case 3 -> studentSubjects_list.add( DataRegistry.getSubjects().get( 2));
                case 4 -> studentSubjects_list.add( DataRegistry.getSubjects().get( 3));
                case 5 -> studentSubjects_list.add( DataRegistry.getSubjects().get( 4));
                default -> System.out.println("지정 범위내의 값을 입력해 주세요");
            }
            System.out.println( studentSubjects_list_test.size() + "번째 과목 선택됨 = " + DataRegistry.getSubjects().get( subjectId -1).getSubjectName());
            System.out.println();
            if (studentSubjects_list_test.size() >= 3) {
                System.out.println("3개 이상입니다. \n 선택과목을 선택하려면 '99' 을 입력해 주세요");
                System.out.println();
            }
        }
        return SubjectsMain;
    }
    // 서브 수업
    private static boolean studentNewSubjectsSub(Set<Integer> studentSubjects_list_test, int subjectId, List<Subject> studentSubjects_list) {

        boolean SubjectsSub = false;
        if (studentSubjects_list_test.contains( subjectId + 10 )) {
            System.out.println( " 이미 등록하신 과목입니다." );
        } else if (subjectId == 99 ) {
            SubjectsSub = true;
            studentSubjects_list_test.clear();
        } else {
            studentSubjects_list_test.add( subjectId + 10 );
            switch (subjectId) {
                case 1 -> studentSubjects_list.add( DataRegistry.getSubjects().get( 5 ) );
                case 2 -> studentSubjects_list.add( DataRegistry.getSubjects().get( 6 ) );
                case 3 -> studentSubjects_list.add( DataRegistry.getSubjects().get( 7 ) );
                case 4 -> studentSubjects_list.add( DataRegistry.getSubjects().get( 8 ) );
                default -> System.out.println("지정 범위내의 값을 입력해 주세요");
            }
            System.out.println( studentSubjects_list_test.size() + " 번째 선택 과목 선택됨 " + DataRegistry.getSubjects().get( subjectId + 4 ).getSubjectName()+"\n");
        }
        if (studentSubjects_list_test.size() >= 2) {
            System.out.print( "2개 이상입니다. 상태를 등록 하려면 '99' 을 입력해 주세요 : " );
            System.out.println();
        }
        return SubjectsSub;
    }

    private static StateType studentNewStateType( int stats_set) {
        StateType stateType = null;
        switch (stats_set) {
            case 1 -> stateType = StateType.RED;
            case 2 -> stateType = StateType.YELLOW;
            case 3 -> stateType = StateType.GREEN;
            default -> System.out.println("지정 범위내의 값을 입력해 주세요");
        }
        return stateType;
    }
}
  • 이 문으로 리팩토링
   // 수강생 생성
    public static void studentNew() {
        do{
            // 이름 등록
            String studentName = UserInputReader.getString("\n학생이름을 입력해주세요 name: ");

            // 과목 등록
            List<Subject> studentMainSubjects = new ArrayList<>();
            List<Subject> studentSubSubjects = new ArrayList<>();
            boolean isMainSubjectDone = false;
            boolean isSubSubjectDone  = false;

            System.out.println("\n 등록할 과목을 입력해 주세요 \n 최소 3개 이상의 필수 과목, 2개 이상의 선택 과목");
            do {
                isMainSubjectDone = studentNewSubjectsMain(studentMainSubjects);
            } while (!isMainSubjectDone);

            do {
                isSubSubjectDone = studentNewSubjectsSub(studentSubSubjects);
            } while (!isSubSubjectDone);

            StateType stateType = studentNewStateType();

            List<Subject> studentSubjects = new ArrayList<>(); // 서브, 메인 과목 합치기
            studentSubjects.addAll(studentMainSubjects);
            studentSubjects.addAll(studentSubSubjects);

            // 학생 생성
            DataRegistry.addStudent(new Student(DataRegistry.getStudentId() ,studentName, studentSubjects, stateType));

        } while (!UserInputReader.getString("\n 추가를 끝내시겠습니까?  끝내기 = (n) \n 입력해 주세요 : ")
                .equals("n"));
    }


    // 매인 수업
    private static boolean studentNewSubjectsMain(List<Subject> studentSubjects) {
        int subjectId = 0;
        if(studentSubjects.size() >= 3) {
            subjectId = UserInputReader.getOption(6,
                                                  "필수 과목 : 1.Java , 2.객체지향 , 3.Spring , 4.JPA , 5.MySQL, 6.선택과목 선택으로 이동 \n 입력해주세요 : ");
        } else {
            subjectId = UserInputReader.getOption(5,
                                                  "필수 과목 : 1.Java , 2.객체지향 , 3.Spring , 4.JPA , 5.MySQL  \n 입력해주세요 : ");
        }

        if(subjectId == 6) {
            return true;
        }

        for(Subject subject : studentSubjects) { // 이미 등록되어 있는지 확인
            if (subject.getSubjectId() == subjectId) {
                System.out.println(" 이미 등록하신 과목입니다.");
                return false;
            }
        }

        Subject subject = DataRegistry.searchSubject(subjectId);
        studentSubjects.add(subject);
        System.out.println(studentSubjects.size() + "번째 필수 과목 선택됨 = " + subject.getSubjectName());

        return false;
    }

    // 서브 수업
    private static boolean studentNewSubjectsSub(List<Subject> studentSubjects) {
        int subjectId = 0;
        if(studentSubjects.size() >= 2) {
            subjectId = UserInputReader.getOption(5,
                                                  "선택 과목 : 1.디자인 패턴 , 2.Spring Security , 3.Redis , 4.MongoDB, 5.상태등록으로 이동 \n 입력해주세요 :  ");
        } else {
            subjectId = UserInputReader.getOption(4,
                                                  "선택 과목 : 1.디자인 패턴 , 2.Spring Security , 3.Redis , 4.MongoDB \n 입력해주세요 :  ");
        }

        if(subjectId == 5) {
            return true;
        }

        for(Subject subject : studentSubjects) { // 이미 등록되어 있는지 확인
            if (subject.getSubjectId() == subjectId  + SUBSUBJECTTUNING) {
                System.out.println(" 이미 등록하신 과목입니다.");
                return false;
            }
        }

        Subject subject = DataRegistry.searchSubject(subjectId + SUBSUBJECTTUNING);
        studentSubjects.add(subject);
        System.out.println(studentSubjects.size() + "번째 선택 과목 선택됨 = " + subject.getSubjectName());

        return false;
    }

    // 상태 삽입
    private static StateType studentNewStateType() {
        int subjectId;
        subjectId =UserInputReader.getOption(3,
                                             "\n 상태입력 1.RED, 2.YELLOW, 3.GREEN : ");
        StateType stateType = StateType.values()[subjectId - 1]; // 상태
        return stateType;
    }
}

 

 

알고리즘 문제 풀기

     ●  가장 가까운 같은 글자

더보기

● 가장 가까운 같은 글자 //링크

import java.util.*;
class Solution {
    public int[] solution(String s) {
        Map<String,Integer> map = new HashMap<>();
        String[] ss = s.split( "" );
        int[] answer = new int[ss.length];
        int cont = 0;
        for(String a : ss){
            if(map.containsKey(a)){
                answer[cont] = cont - map.get(a);
                map.put(a,cont);
            }else {
                map.put(a,cont);
                answer[cont] = -1;
            }

            cont++;
        }
        return answer;
    }
}
  • 첫 시도시 2중배열을 이용했지만 문자가 많아질 수록 배열의 총 인덱스값을 조절하지 못해 컬랙션으로 변경함 
    • = 방식은 틀리지 않았지만 인덱스 값이 정적이라 문제됨
    • 문제 지문에
      • 1 ≤ s의 길이 ≤ 10,000
    • 그렇다면 어떤 컬렉션을 써야하나? 
      • List로 2중배열을 했지만 안됨 = 20% 
      • Map 사용 Key값을 문자로 하고 동일 문자를 덮어쓰기로 이어붙임
      • if(map.containsKey(a)){
        	answer[cont] = cont - map.get(a);
        	map.put(a,cont);
        }else {
        	map.put(a,cont);
        	answer[cont] = -1;
        }
  • 성공함 밑은 다른 사람의 풀이
  • import java.util.stream.IntStream;
    
    class Solution {
        public int[] solution(String s) {
            return IntStream.range(0, s.length())
            			.map(i -> s.substring(0, i)
              		  	.lastIndexOf(s.charAt(i)) > -1 ? i - s.substring(0, i)
                        .lastIndexOf(s.charAt(i)) : -1)
                        .toArray();
        }
    }
  • 이걸 스트림으로 한줄로 만들다니 ㄷㄷ
  • 다른 사람의 풀이 2
  • import java.util.*;
    
    class Solution {
        public int[] solution(String s) {
            int[] answer = new int[s.length()];
            HashMap<Character,Integer> map = new HashMap<>();
            for(int i=0; i<s.length();i++){
                char ch = s.charAt(i);
                answer[i] = i-map.getOrDefault(ch,i+1);
                map.put(ch,i);
            }
            return answer;
        }
    }
  • getOrDefault을 배웠다

 

     ●  크기가 작은 부분문자열

더보기

● 크기가 작은 부분문자열 //링크

class Solution {
    public int solution(String t, String p) {
        long pt = Long.parseLong(p);
        int answer = 0;

        for (int i = 0; i < t.length() - (p.length() -1); i++) {
     
            long tt = Long.parseLong(t.substring(i, i+p.length()));
            
            if(pt >= tt){
                answer++;
            }
            
        }
        return answer;
    }
}
  • 첫 시도시 초반 몇 문제를 제외하고 런타임 오류가 나왔다 
    • = 방식은 틀리지 않았다.
    • 문제 지문에
      • 1 ≤ p의 길이 ≤ 18
    • 18길이 =>  int 값은 10자리 까지다 그렇다면?
      • Int값을 Long으로 변경한다
  • 성공함 밑은 다른 사람의 풀이
  • import java.util.stream.LongStream;
    
    class Solution {
        public int solution(String t, String p) {
            long targetNumber = Long.parseLong(p);
            int targetNumberLength = p.length();
    
            return (int) LongStream.range(0L, t.length() - targetNumberLength + 1L)
                    .mapToObj(i -> t.substring((int) i, (int) i + targetNumberLength))
                    .mapToLong(Long::parseLong)
                    .filter(number -> number <= targetNumber)
                    .count();
        }
    }
  • 스트림을 더 배워야겠다.

 

     ●  가장 가까운 같은 글자

더보기

● 시저 암호  //링크

class Solution {
    public String solution(String s, int n) {
          String answer = "";
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            int a = c;

            if (a == 32){
                answer += " ";
            } else if (a >= 65 && a <= 90) {
                if(a+n > 90){
                    answer += (char)((a+n - 90) + 64);
                }else{
                    answer += (char)(a+n);
                }
            } else if (a >= 97 && a <= 122) {
                if(a+n > 122){
                    answer += (char)((a+n - 122) + 96);
                }else {
                    answer += (char)(a+n);
                }
            }
        }
        return answer;
    }
}
  • 첫 시도시 글자 위치가 맞지않음 
    • A의 아스키 코드는  97이다. 
      • 아 97부터가 아니라 96부터 해야한다.
  • 성공함 밑은 다른 사람의 풀이
  • class Caesar {
        String caesar(String s, int n) {
            String result = "";
        n = n % 26;
        for (int i = 0; i < s.length(); i++) {
          char ch = s.charAt(i);
          if (Character.isLowerCase(ch)) {
            ch = (char) ((ch - 'a' + n) % 26 + 'a');
          } else if (Character.isUpperCase(ch)) {
            ch = (char) ((ch - 'A' + n) % 26 + 'A');
          }
          result += ch;
        }
            return result;
        }
    
        public static void main(String[] args) {
            Caesar c = new Caesar();
            System.out.println("s는 'a B z', n은 4인 경우: " + c.caesar("a B z", 4));
        }
    }
  • 26....Character.isLowerCase(ch) ...생각보다 더 간단하게 할수 있었다.

 


당일 회고

  • 팀과제가 거의 끝났다.