TIL 23/08/18

song yuheon·2023년 8월 18일

Today I Learn

목록 보기
4/83
post-thumbnail

데일리 리포트

06:50 ~ 07:35 : Self Development
07:35 ~ 08:35 : Java 문법 종합반 5주차_2
08:35 ~ 08:55 : 아침
08:55 ~ 09:00 : 휴식
09:00 ~ 09:30 : 항해99 2주차 OT
09:30 ~ 18:00 : Java 프로그래머스 코딩 테스트
18:00 ~ 19:00 : 저녁
19:00 ~ 23:20 : Java 프로그래머스 코딩 테스트


데일리 스터디

Java 코딩 테스트

  1. X만큼 간격이 있는 n개의 숫자
public class sol5 {
    public static void main(String[] args) {
        Solution sol = new Solution();
        long []result;
        result= sol.solution(4,6);
        System.out.println(result);
    }
}

class Solution {
    public long[] solution(int x, int n) {
        long[] answer = {};
        answer = new long[n];
        // 반드시 new long[n]; 으로 객체를 선언 해야한다.

        for (int i = 0; i < n; i++) {
            if(i==0)
                answer[i]=x;

            else
                answer[i]=answer[i-1]+x;
        }
        System.out.println(answer);
        return answer;
    }

트러블 슈팅

  • 배열 초기화 문제 long[] answer = {} (ArrayIndexOutOfBoundsException)
    => 배열을 적절한 크기로 초기화
    ( answer = new long[n];)
  1. 자연수 뒤집어 배열로 만들기
class Solution {
    public int[] solution(long n) {
        long num=n;
        int len = 0;
        while (num!=0)
        {
            num/=10;
            len++;
        }
        int [] answer=new int[len];
        for (int i = 0; i < len; i++) {
            answer[i]=(int)(n%10);
            n/=10;
        }
        return answer;
    }
}

트러블 슈팅

  • 잘못된 형변환 문제
    answer[i]=(int)n%10;
    원래 long 형이었던 n을 int로 형변환 하여 int가 아닌 long으로만 표현 가능한 값이 손실 발생하였다.
    => (int)(n%10)으로 수정하면 값의 손실을 없앨수 있다.

++ 다른 분들의 풀이

import java.util.stream.IntStream;

class Solution {
    public int[] solution(long n) {
        return new StringBuilder().append(n).reverse().chars().map(Character::getNumericValue).toArray();
    }
}

코드리뷰
StringBuilder 생성

new StringBuilder() : StringBuilder 객체를 새로 생성

.append(n) : StringBuilder 객체에 long 타입의 숫자 n을 문자열로 추가

.reverse() : StringBuilder 객체의 문자열을 반전

.chars() : 반전된 문자열의 각 문자를 나타내는 int 값을 포함하는 스트림을 생성

.map(Character::getNumericValue)
스트림의 각 int 값을 해당하는 숫자로 변환합니다. 여기서 Character::getNumericValue 메서드는 주어진 문자(예: '5')를 해당하는 숫자(예: 5)로 변환합니다.

.toArray()
숫자로 변환된 스트림의 값을 배열로 변환

  1. 문자열 정수로 바꾸기
class Solution {
    public int solution(String s) {

        return Integer.parseInt(s);
    }
}
  1. 정수 제곱근 판별
class Solution {
    public long solution(long n) {
        long answer = 0;
        long num=0;
        while(n>(num*num)){
            num++;
            if(n==num*num){
                answer=(num+1)*(num+1);
                return answer;
            }
        }
        return -1;
    }
}
  1. 정수 내림차순으로 배치하기
    java 토큰화를 통해 분리한 이후 정렬
    StringTokenizer sample = new StringTokenizer("123345","1234567890",true);

hasMoreTokens() 메서드는 토큰화된 문자열에서 더 이상 사용할 수 있는 토큰이 있는지 확인하기 위해 사용

StringTokenizer sample = new StringTokenizer("123345","1234567890",true);
        while(sample.hasMoreTokens()){
            System.out.println(sample.nextToken());
        }
import java.util.Arrays;
class Solution {
    public long solution(long n) {
        long answer = 0;
        char [] arr = Long.toString(n).toCharArray();
        // Long -> String -> charArray
        char temp;
        int len = arr.length;
        String result;
        
        
        Arrays.sort(arr);
        for (int i = 0; i < (int)(len/2); i++) {
            temp = arr[i];
            arr[i]=arr[len-i-1];
            arr[len-i-1]=temp;
        }
        // temp로 reverse
        
        result = new String(arr);
        answer = Long.parseLong(result);
        System.out.println(answer);
        return answer;
    }
}

다른 풀이

public class ReverseInt {
    String res = "";
    public int reverseInt(int n){
        res = "";
        Integer.toString(n).chars().sorted().forEach(c -> res = Character.valueOf((char)c) + res);
        return Integer.parseInt(res);
    }

하샤드 수

class Solution {
    public boolean solution(int x) {
        int sum = 0,temp_x=x;
        while(x!=0){
            sum+=(x%10);
            x/=10;
        }
        if((temp_x%sum)==0)
            return true;
        else
            return false;
    }
}

코드 리뷰
코드 간결화: if 문의 조건은 불리언 값을 반환합니다. 따라서 if 문을 사용하여 true 또는 false를 반환할 필요 없이 조건 자체를 직접 반환할 수 있습니다.

변수명: 변수명은 가능한 한 의미를 명확하게 전달해야 합니다. temp_x라는 이름보다는 originalX와 같은 이름이 좀 더 명확하게 의도를 전달할 수 있습니다.

주석 추가: 코드의 기능을 빠르게 이해하는 데 도움이 되는 간략한 주석을 추가하는 것이 좋습니다.

chatgpt 코드 리뷰로 개선된 코드 
class Solution {
    /**
     * Determines if the given number x is divisible by the sum of its digits.
     * @param x The number to check.
     * @return true if x is divisible by the sum of its digits, false otherwise.
     */
    public boolean solution(int x) {
        int sum = 0;
        int originalX = x;

        // Calculate the sum of digits of x
        while(x != 0) {
            sum += (x % 10);
            x /= 10;
        }

        // Return whether originalX is divisible by sum
        return originalX % sum == 0;
    }
}

다른 풀이

public class HarshadNumber{
    public boolean isHarshad(int num){
    String [] tmp = String.valueOf(num).split("");
    int sum=0;
        for(String s:tmp) {
            sum+=Integer.parseInt(s);
        }

        /*
    int tmp = num;
        int sum = 0;

        while(tmp>0) {
            int rem = tmp%10;
            sum+=rem;
            tmp=tmp/10;
        }
        */
        if(num%sum==0) {
            return true;
        } else {
            return false;
        }
    }

       // 아래는 테스트로 출력해 보기 위한 코드입니다.
    public static void  main(String[] args){
        HarshadNumber sn = new HarshadNumber();
        System.out.println(sn.isHarshad(18));
    }
}

=>
String.valueOf(num)
변수를 문자열로

Question String.valueOf(num)은 다른 여러 자료형도 문자형으로 변경 가능?
A.
1. String.valueOf(Object obj): 주어진 객체의 toString() 메서드를 호출하여 문자열로 변환합니다. objnull인 경우 "null" 문자열을 반환합니다.

  1. String.valueOf(char[] data): 문자 배열을 문자열로 변환합니다.

  2. String.valueOf(boolean b): boolean 값을 문자열로 변환합니다. ("true" 또는 "false")

  3. String.valueOf(char c): 문자를 문자열로 변환합니다.

  4. String.valueOf(int i): 정수 값을 문자열로 변환합니다.

  5. String.valueOf(long l): long 값을 문자열로 변환합니다.

  6. String.valueOf(float f): float 값을 문자열로 변환합니다.

  7. String.valueOf(double d): double 값을 문자열로 변환합니다.

따라서 String.valueOf()는 int 외에도 다양한 타입을 문자열로 변환할 수 있습니다.

Question java에서 객체 타입 알고자 할때 방법
getClass(): 객체에서 이 메서드를 호출하면 해당 객체의 런타임 클래스를 나타내는 Class 객체를 얻을 수 있습니다. 이후에 getName(), getSimpleName(), 등의 메서드로 클래스의 이름을 알아낼 수 있습니다.

Object obj = "Hello, World!";
System.out.println(obj.getClass().getName());         // 출력: java.lang.String
System.out.println(obj.getClass().getSimpleName());  // 출력: String

instanceof 연산자: 객체가 특정 클래스나 인터페이스의 인스턴스인지 검사할 수 있습니다. 이 연산자는 주로 타입 체크와 타입 캐스팅의 조합으로 사용됩니다.

Object obj = "Hello, World!";
if (obj instanceof String) {
    System.out.println("The object is a String.");
}

기본 데이터 타입은 래퍼와 해서 알아야한다.

다른 사람의 풀이

class Solution {
    public long solution(int a, int b) {
        int temp = 0;
        long answer=0;
        if(a>b){
            temp=a;
            a=b;
            b=temp;
        }
        for (int i =a; i <=b ; i++)
            answer+=i;
        return answer;

    }
}

콜라츠 추측

class Solution {
    public int solution(int num) {
        long temp=num;
        for (int i = 0; i < 500; i++) {
            if(temp!=1){//num이 1인 경우 바로 반환해야하기에
                if(temp%2==0)//num이 2인 경우 2로 나눈다
                    temp/=2;
                else// num이 아닐경우 *3+1한다
                    temp=temp*3+1;
            }
            else
                return i;
        }
        return -1;
    }
}

서울에서 김서방 찾기

import java.util.*;
class Solution {
    public String solution(String[] seoul) {
        for (int i=0;i<seoul.length;i++) {
            if(Objects.equals("Kim",seoul[i]))
                return "김서방은 "+i+"에 있다";
        }
        return "";

    }
}

코드 리뷰
Objects.equals 메서드 사용: Objects.equals()는 좋은 선택이지만, 문자열을 비교할 때 equals 메서드를 직접 사용해도 충분합니다.

class Solution {
    public int[] solution(int[] arr, int divisor) {
        ArrayList<Integer> answer = new ArrayList<Integer>();
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]%divisor==0){
                answer.add(arr[i]);
            }
        }
        if(answer.isEmpty())
            answer.add(-1);
        System.out.println(answer);
        int[] intAnswer = answer.stream().mapToInt(Integer::intValue).toArray();
        return intAnswer;
    }
}

나누어 떨어지는 숫자 배열

트러블 슈팅
ArrayList<> 사용해서 arr/divisor이 0인 값들 추가
https://psychoria.tistory.com/765
return을 int[]로 해야하는

ArrayList<> answer을 int[]로 형변환해야한다.
answer.stream().mapToInt(Integer::intValue).toArray()
https://velog.io/@deannn/Java-int%ED%98%95-ArrayList-%EB%B0%B0%EC%97%B4-%EB%B3%80%ED%99%98

정렬을 해야한다.
스트림을 사용한다.
Arrays.stream(intAnswer).sorted().toArray();
내림차순은
sorted(Comparator.reverseOrder())

int[] intAnswer = Arrays.stream(answer.stream().mapToInt(Integer::intValue).toArray()).sorted().toArray();

코드 해석
1. answer.stream()
answer는 List 같은 컬렉션(리스트)을 의미하며, 여기에 담긴 요소들을 연속적으로 처리하기 위해 스트림(stream)으로 변환합니다.
스트림이란 데이터의 연속적인 흐름을 의미합니다. 이 흐름을 통해 데이터를 효율적으로 처리할 수 있습니다.
2. mapToInt(Integer::intValue)
mapToInt는 스트림 내의 각 요소를 int 기본 데이터 타입으로 변환하는 역할을 합니다.
Integer::intValue는 각 Integer 객체를 기본 데이터 타입인 int로 바꾸는 방법을 알려줍니다. 이렇게 변환하는 이유는 기본 데이터 타입이 객체보다 메모리와 성능 측면에서 효율적이기 때문입니다.
3. sorted()
이 부분은 스트림 내의 요소를 오름차순으로 정렬합니다.
예를 들어, answer가 [3, 1, 2]로 구성되어 있다면, 이 단계 이후 스트림에는 [1, 2, 3] 순서로 데이터가 정렬되어 있을 것입니다.
4. toArray()
마지막으로, toArray()는 정렬된 스트림의 데이터를 배열로 변환합니다. 그리고 이 배열을 intAnswer 변수에 할당합니다.
요약:
이 코드는 answer라는 Integer 객체 리스트를 받아, 각 요소를 int 기본 타입으로 변환하고, 오름차순으로 정렬한 후, 이를 int 배열로 만듭니다. 결과적으로 intAnswer는 오름차순으로 정렬된 int 배열이 됩니다.

다른 풀이

 public int[] divisible(int[] array, int divisor) {
        return Arrays.stream(array).filter(factor -> factor % divisor == 0).toArray();
    }
  

Arrays.stream(array):

주어진 array 배열로부터 int 타입의 스트림을 생성합니다.
filter(factor -> factor % divisor == 0):

주어진 divisor로 나누어 떨어지는 요소만 필터링합니다.
toArray():

스트림의 요소들을 배열로 변환합니다.

  1. 음양 더하기
  class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        for(int i = 0;i < signs.length;i++)
            if(signs[i]==false)
                answer-=absolutes[i];
            else
                answer+=absolutes[i];
            return answer;
    }
}

다른 풀이

import java.util.stream.IntStream;

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        return IntStream.range(0, absolutes.length)
                        .map(i -> signs[i] ? absolutes[i] : -absolutes[i])
                        .sum();
    }
}

코드 설명
IntStream.range(0, absolutes.length):

0부터 absolutes.length - 1까지의 정수 스트림을 생성합니다.
예를 들어, absolutes 배열의 길이가 5라면, 이 스트림은 0, 1, 2, 3, 4의 값들로 구성됩니다.
.map(i -> signs[i] ? absolutes[i] : -absolutes[i]):

위에서 생성한 스트림의 각 요소 i (즉, 배열의 인덱스)에 대하여 아래의 동작을 수행합니다:
signs[i]가 true인 경우: absolutes[i] 값을 그대로 사용합니다. (즉, 양수로 둡니다.)
signs[i]가 false인 경우: absolutes[i] 값을 음수로 만들어 사용합니다.
이러한 변환 작업을 통해 새로운 스트림이 생성됩니다.
.sum():

스트림의 모든 요소들을 합계합니다.

  1. 핸드폰 번호 가리기
  public class Main {
    public static void main(String[] args) {
        String phone_number="135125125";
        int len = phone_number.length();
        String result = phone_number.substring(0,len-4).replaceAll(".","*")
                +phone_number.substring(len-4,len);
        System.out.println(result);
    }
}

Question 정규표현식은 어떻게 작성?
이메일 주소 검증:

      // 폰번호를 문자열 인덱싱
    // https://hanyeop.tistory.com/326
    //phone_number.substring(start,end);

replaceAll()
"." 모든 문자 의미

regex
Copy code
^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$
전화번호 검증 (아래 예제는 XXX-XXX-XXXX 형식):

regex
Copy code
^\d{3}-\d{3}-\d{4}$
URL 검증:

regex
Copy code
^(http|https|ftp)://[^\s]+\.[^\s]+$
날짜 검증 (아래 예제는 YYYY-MM-DD 형식):

regex
Copy code
^\d{4}-\d{2}-\d{2}$
숫자만 포함하는 문자열 검증:

regex
Copy code
^\d+$
소문자 및 대문자로만 구성된 문자열 검증:

regex
Copy code
^[a-zA-Z]+$
특수 문자가 포함되지 않은 문자열 검증:

regex
Copy code
^[a-zA-Z0-9]*$
비밀번호 검증 (8 ~ 15자 사이, 최소 하나의 대문자, 소문자 및 숫자 포함):

regex
Copy code
^(?=.[a-z])(?=.[A-Z])(?=.*\d)[a-zA-Z\d]{8,15}$

^ 기호는 정규 표현식에서 "문자열의 시작"을 의미
숫자 정규표현식 이용 = [0-9]로 사용

다른 풀이

  class Solution {
  public String solution(String phone_number) {
    return phone_number.replaceAll(".(?=.{4})", "*");
  }
}

return phone_number.replaceAll(".(?=.{4})", "");
이 코드의 주된 목적은: phone_number 문자열에서 마지막 4개 문자를 제외하고 나머지 모든 문자를
로 변경하는 것입니다.

이를 이해하기 위해 정규 표현식 부분을 나눠서 살펴보겠습니다.

. :

이 부분은 어떤 문자 하나를 나타냅니다. (개행 문자를 제외한)
(?=...) :

이것을 "전방탐색"이라고 합니다. 전방탐색은 "뒤에 ...가 오는지 확인해 주세요!"라는 의미입니다. 하지만, 실제로 문자열을 가져오거나 바꾸는 작업은 하지 않습니다. 그저 확인만 합니다.
.{4} :

여기서 .는 어떤 문자 하나를 나타내고, {4}는 그런 문자가 연속 4개 있어야 한다는 것을 의미합니다.
결국, 위의 정규 표현식을 조합하면 "어떤 문자 하나(.) 뒤에 연속된 4개의 문자가 있어야 한다((?=.{4}))"는 의미가 됩니다.

이제 replaceAll 메소드로 돌아가 보면, 이 메소드는 문자열 내에서 위에서 설명한 패턴을 찾아서 *로 바꿔줍니다.

  1. 없는 숫자 더하기
     class Solution {
       public int solution(int[] numbers) {
           int answer = 45;
           // 어떻게 찾을까? 빈 것을
           // s1 for문 0 ~ 9
           // s2 55 - for 문
           
           for(int i=0;i<numbers.length;i++)
               answer-=numbers[i];
           return answer;
       }
    }
다른 풀이

class Solution {
public int solution(int[] numbers) {
return 45-Arrays.stream(numbers).sum();
}
}

numbers 스트림 화 => sum으로 45-

  1. 제일 작은 수 제거하기
 class Solution {
    public int[] solution(int[] arr) {
        int min = Arrays.stream(arr).min().getAsInt();
        if(arr.length!=1)
            return Arrays.stream(arr).filter(n->n!=min).toArray();
        int [] a = {-1};
        return a;
    }
}

스트림으로 제일 작은수 OptionalInt로 -> getAsInt() int 값 추출

  1. 가운데 글자 가져오기
class Solution {
    public String solution(String s) {
        int half=s.length()/2;
        return (s.length()%2==0)?s.substring(half-1,half+1) : s.substring(half,half+1);
    }
}

삼항 연산자와 서브스티링 이용

다른 풀이

class StringExercise{
  String getMiddle(String word){
return word.substring((word.length()-1)/2, word.length()/2 + 1);
  }
  1. 수박수박수박수?
  class Solution {
    public String solution(int n) {
        String answer = "";
        for(int i = 0; i<n;i++)
            answer+=(i%2!=0)? "박":"수";
        return answer;
    }
}

다른 풀이

public String watermelon(int n){

        return new String(new char [n/2+1]).replace("\0", "수박").substring(0,n);
    }
  1. 약수의 개수와 덧셈
class Solution {
    public int solution(int left, int right) {
        int answer = 0;
        for( int i =left;i<=right;i++)
            answer+=((i%Math.sqrt(i))!=0)?i:(-1*i);
        return answer;
    }
}                                
profile
backend_Devloper

0개의 댓글