2022.12.06.TUE

ronglong·2022년 12월 6일
0

코드스테이츠 Day34

  1. 오전 데일리 코딩

1) 반만 통과했던 18번 문제 결국 질문해서 오류 해결했다.

public class Solution { 
	public int numberSearch(String str) {
    // 빈 문자열 거르기
    if(str.length()==0) return 0;
    //문자열에서 숫자 찾아서 모두 더하고, "숫자와 공백을 제외한 나머지" 문자열 길이로 나누고, 정수로 반올림하여 int 타입 출력
    double num = 0;

    String intStr = str.replaceAll("[^0-9]", ""); // 숫자가 아닌 문자들을 모두 공백으로. 숫자만 남기기
    for(int i=0; i<intStr.length(); i++){ // 문자열 내 숫자 다 더하기
      num += intStr.charAt(i) - '0';
    }
    
    // 밑에 부분에서 오류가 있었어서 정민님께 질문 후 도움 받음. 
    // str = str.replaceAll("[0-9//s]", ""); // 숫자와 공백 제외. - 공백이 제대로 제거되지 않음
    // return Math.round(num / str.length());  
    // 반올림 문제. 정수끼리 나누면서 문제 생김. 소수점이 무시된 듯. 나누기 및 반올림은 double로 하고, 이후 int로 변환하자. 

    str = str.replaceAll("[0-9]", "").replaceAll(" ", ""); // 숫자와 공백 제외. 따로 해야 먹히나 봄. 멍청한 컴퓨터!
    num = num / str.length(); 
    //나눈 값을 실수(double)로해서 반올림 해야함. 애초에 num 선언할 때 double로 하자. 
    return (int) Math.round((num*10)/10); // Math 함수는 long으로 리턴됨. 
	} 
}

공백 제거가 제대로 안 되었고, int끼리 나누면서 소수점 무시가 되어 반올림이 제대로 안 되었다.

공백 제거는 솔직히 왜 따로 2번 해야하는지.. 멍청한 컴퓨터!
숫자랑 공백 한 번에 제거하라구,,

그리고 Math.round() 반올림할 때는 안의 파라미터를 double로 하고, (*10)/10 해줘야 소수점이 제대로 산정되는 것 같다. 후에 형변환을 해주어야함.

이와 관련된 링크들.
https://stackoverflow.com/questions/37795248/integer-division-in-java
https://msm8994.tistory.com/21

오류가 발생했을 때 직접 하나하나 찍어보면서 오류가 나는 지점을 확인하고 디버깅하는 연습을 해야할 것 같다.

2) 며칠 내내 고민했던 20번 문제는 결국 레퍼런스 봤음.
밑에 순서대로 레퍼런스와 나의 작살난 망한 코드.. ㅋㅋㅋ 리스트로 풀려다가 멸망.

public class Solution { 
	public String compressString(String str) {
    if(str.length() == 0) return "";
    // 연속되는 문자를 기록하기 위한 변수를 선언하고
    // 첫 번째 문자로 초기화합니다.
    char before = str.charAt(0);
    // 동일한 문자의 반복 횟수를 저장할 변수를 선언, 초기값은 1로 할당합니다.
    int count = 1;
    // 정답으로 리턴할 문자열을 선언합니다. 초기값은 공백으로 할당합니다.
    String result = "";

    // 마지막 부분이 연속된 문자일 경우를 위해 dummy 문자 추가합니다.
    str = str + ' ';
    for (int i = 1; i < str.length(); i++) {
      // 동일한 문자가 반복될 경우
      if (before == str.charAt(i)) {
        //count를 1씩 더해줍니다.
        count++;
      } else {
        // 이전과 다른 문자일 경우,
        // 반복된 횟수가 3 이상일 경우에만 문자열을 압축합니다.
        if (count >= 3) {
          result = result + count + before;
        } else {
          //count의 수만큼 결과에 문자열을 저장합니다.
          for(int j = 0; j < count; j++) {
            result = result + before;
          }
          //자바 11에서 지원하는 String.repeat메소드를 활용하면 조금 더 간단하게 작성이 가능합니다.
          //result = result + Character.toString(before).repeat(count);
        }
        before = str.charAt(i);
        count = 1;
      }
    }
    return result;
  }
}
public class Solution { 
	public String compressString(String str) { 
  // 3개 이상 문자가 연달아 반복되면, [반복횟수 + 문자] 로 압축.  

  // 빈 문자열 거르기
  if(str.length()==0) return str;

  ArrayList<String> list = new ArrayList<>();
  // 문자가 바뀌는 시점마다 다 쪼개서 리스트에 넣을까..? <www, gg, o, pp, o, pppp> 이런 식으로..

    for(int i=0; i<str.length(); i++){
      for(int j=i+1; j<str.length(); j++){
        if(str.charAt(i)!=str.charAt(j)){
        list.add(str.substring(str.charAt(i), str.charAt(j))); 
        i=j;
        break;
        }
      }
    }

    String result = "";

    // 리스트 요소의 길이가 3이상이면 길이 + 문자로 값 치환? 
    for(int i=0; i<list.size(); i++){
      if((list.get(i)).length() >= 3) result += (list.get(i)).length() + list.get(i);
      else result += list.get(i);
    }

    return result;
	}    
}

3) 오랜만에 기분 좋게 한 번에 풀었던 문제! 21번❤️

public class Solution { 
	public int largestProductOfThree(int[] arr) {
    // 3개를 순서없이 뽑아서 곱한 값들을 리스트에 넣고 그중 가장 큰 값을 고른다?
    ArrayList<Integer> list = new ArrayList<>();

    for(int i=0; i<arr.length; i++){
      for(int j=i+1; j<arr.length; j++){
        for(int k=j+1; k<arr.length; k++){
          list.add(arr[i]*arr[j]*arr[k]);
        }
      }
    }
    return list.stream().mapToInt(i->i).max().getAsInt();
	} 
}
  1. 스프링 프레임워크 특징
  • framework : 프로그래밍을 위한 구조나 틀 제공
    • 효율적인 코드 작성 (개발자가 핵심 로직 개발에 집중)
    • 정해진 규약에 따른 코드 --> 유지/보수 용이 (but 자유롭고 유연한 개발은 어려움)
  • library : 부품. 필요한 기능을 미리 구현해놓은 집합체
  • 프레임워크와 라이브러리는 애플리케이션에 대한 제어권의 차이가 있음.
    • 프레임워크 : 애플리케이션 흐름의 주도권이 개발자가 아닌 프레임워크에 있음.
    • 라이브러리 : 애플리케이션 흐름의 주도권이 개발자에 있음.
  • Java 언어의 장점
    - 정적 타입 언어로써 변수의 타입, 메서드의 입력과 출력이 어떤 타입을 가져야 하는지를 강제함. 유지/보수 용이.
  • Spring framework를 통해
    • 객체 지향 설계 원칙에 따른 재사용과 확장이 가능한 애플리케이션 개발 스킬을 향상
    • 좋은 성능과 서비스의 안전성이 필요한 복잡한 기업용 엔터프라이즈 시스템 구축
  • Spring 삼각형
    1) POJO(Plain Old Java Object) : Java로 생성하는 순수한 객체. for 제한없는 객체 지향 설계
    - Java나 Java의 스펙(사양)에 정의된 것 이외의 다른 기술이나 규약에 얽매이지 않을 것.
    - 특정 환경에 종속적이지 않을 것.
    2) IoC(Inversion of Control) / DI(Dependency Injection)
    - IoC : 애플리케이션 흐름의 주도권이 뒤바뀐 것
    - DI : IoC 개념을 구체화 시킨 것으로, 생성자로 어떤 클래스의 객체를 전달 받는 것
    - new 키워드를 통한 의존 객체를 생성 --> 클래스 간의 강한 결합(Tight Coupling)
    - 인터페이스를 통한 느슨한 결합(Loose Coupling). DI
    - Spring framework에서 DI해줌.
    3) AOP(Aspect Oriented Programming)
    - 핵심 관심 사항(Core concern)과 공통 관심 사항(부가적인 관심 사항, Cross-cutting concern)을 분리하여 객체 지향적 설계.
    4) PSA(Portable Service Abstraction) : 다형성
    - 추상화 된 상위 클래스를 일관되게 바라보며 하위 클래스의 기능을 사용하는 것
  • 스프링 부트 : 스프링 프레임워크 세팅 툴
    https://melonicedlatte.com/2021/07/11/174700.html
  • 객체 지향 설계 5원칙 : 단일 책임, 개방/폐쇄, 리스코프 치환(다형성), 인터페이스 분리(작은 기능 단위로 쪼개기), 의존관계 역전(구체화가 아닌 추상화에 의존할 것)
    https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)
  • 클래스 다이어그램 도구 : 클래스 간의 관계 설계
    https://online.visual-paradigm.com/diagrams/features/

<느낀 점>
오늘 오전에는 데일리 코딩에서 며칠 내내 막히던 부분을 마무리 짓고, 새로운 문제로 넘어갔다!

그리고 오후에는 드디어 스프링 프레임워크 시작.
객체 지향 설계에 대한 텍스트를 읽는 것이 대부분이었고, 이는 섹션 1에서 버거퀸 과제할 때 봤어서 그래도 조금 익숙했다.

당분간은 텍스트를 읽고 이해하거나 예제를 따라서 작성해보는 것이 전부인데, 이 부분을 빨리 끝내고 혼자서 남는 시간을 만들어서 버거퀸 과제를 한 번 더 해보면 좋을 것 같다.
직접 한 번 해보는 게 이해하는데 제일 좋음.

이제 슬슬 공부한 게 쌓여서 헷갈리는 시점이 다가올 것 같다.
부지런히 복습해야지..
아직 화요일이라니 믿기지 않지만,, 오늘 저녁도 내일도 화이팅!
내일 공부할 부분 밤에 미리 봐야겠다.

0개의 댓글