Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

개발이 하고싶니?

[프로그래머스 입문]각도기, 배열의 평균값, 피자 나눠 먹기(3),배열 뒤집기, 문자열뒤집기(자바) 본문

스터디 . 코테 해체하기

[프로그래머스 입문]각도기, 배열의 평균값, 피자 나눠 먹기(3),배열 뒤집기, 문자열뒤집기(자바)

차해:) 2024. 1. 28. 01:16
나는 그동안 제로베이스에서 중간중간 코딩테스트를 맛보기로 접해왔다.

코딩테스트에 'ㅋ'도 모르는 나는 한 문제를 푸는데 기본 1일~4일 걸렸고
(책이나 서치 하지 않고 혼자서는 작성을 못해서 매번 함수를 어떻게 쓰는지,
해당 메서드를 쓸 수 있는 게 맞는지, 이럴 땐 어떤 함수나 자료구조를 쓰는지 찾아보고 구현하거나
에러가 발생했을 때는 왜 에러가 난 건지 오픈카톡방에 물어보거나
아예 아이디어가 떠오르지않아 못 푸는 문제가 나왔을 땐 구글링으로 코드분석을 하여 해결했다.)
그마저도 IDE로 돌려본 후 코드를 붙여 넣기 해서 제출했었다.
그런데 이번 코딩테스트는 달라도 너무 달랐다.
프로그래머스랑 연계되어서 진행했고,  5문제당 3시간으로 시간제한이 있었다.
연습 삼아 IDE 도움을 받지 않고 진행했더니 결과는 10문제 중 2문제 정답..........
이게 맞는건가 현타가 세게 왔다. 공부를 안 해왔던 게 아닌데 이렇게까지 심하다고? 어이도 없고
너무너무너무 처참했다👤

시간은 1~4일에 하나 풀어왔으니 당연히 모자랐고
IDE가 없어서 작성한 코드에 오타가 있는지 오류가 있는지 메서드가 어떤 게 있었는지
해당 메서드를 여기서 쓸 수 있는지 없는지 매번 IDE가 친절하게 표시해 주고 알려줘서
그나마 코드를 이어나갔었는데 슬프게도 이번에 나는 아무것도 모르는
그냥 컴퓨터 앞에 앉은 코딩 신생아였다....👶(기초정도의 문제 같았는데)
그동안 풀어봤던 거에 비하면 분명히 그리 어려운 문제도 아니어서 문제 읽을 때까지만 해도
이렇게 저렇게 하면 되겠다 싶었는데 현실은 생각대로 되지 않았다.
문자열을 뒤집는데 왜 뒤집어지는 거에 그치지 않고 거울처럼 출력이 되는지...
왜 내가 원하는 답의 근처만 돌고 있는지
제대로 쓴 것 같은데 수정에 수정을 해도 왜 에러가 추가로 생기기만 하고 잡히지 않는 건지
그렇게 나 자신의 수준을 확실히 느꼈다.
(모든 문제를 if문과 for문으로만 해결 보려 하고 그걸 못쓰거나 그게 막히면 바보가 되는 수준)
그리고 생각했다. 지금 이런 문제 풀 때가 아니라 입문부터 기초부터 그렇게 올라가야겠다고....
뒤집지도 못하면서 일어나서 걷는 게 당연히 안되는 건데 일어나서 걷겠다고 며칠을 허비하지 말자고
추가로 욕심은 과감히 버리기로 했다.
입문부터 차근차근 풀다가 기억해야 하는 것들이 나오면 분석하고 기록해 놓자
그렇게 처음부터 시작하자🔥🔥🔥🔥🔥🔥🔥

🔒각도기

프로그래머스 입문문제 각도기 + 작성한 코드

나는 if문을 사용해서 범위를 나눴고, 해당 범위의 값이 들어오면 그에 맞는 답이 출력될 수 있게 answer을 잡아주었다.

그런데 제출하고 다른 사람들의 코드를 확인해 보니 삼항연산자를 활용한 코드가 있었다.

저거 나도 아는 건데.... 배운 건데.... 공부한 건데.... 왜 생각이 안 나는 걸까? 아니 생각이 났으면 내가 작성은 할 수 있었을까?

그래서 이 문제를 포스팅에 넣기로 했다.

우선 여러 코드와 댓글을 확인하다가 망치로 얻어맞은 것 같은 댓글이 있었다.

정말 뼈 때리는 것 같지만 도움이되는 댓글

맞다.

실전 코딩테스트였다면 저렇게 쓸데없이 타이핑할 시간은 없을 텐데.

 

0 <angle&&   -> 문제에서 '0 <angle <=180'이라고 범위가 지정되어 있어서 작성할 필요 X

90 <angle&& -> else if에서 'angle==90'으로 잡아놨기 때문에 중복작성

 

이런 부분도 신경 써야겠다.

 

🔑 다른 코드 풀이 & 분석

이제 삼항연산자를 사용하여 작성한 코드를 살펴보자!

class Solution {

public int solution(int angle){

return angle == 180 ? 4 : angle < 90 ? 1 : angle == 90 ? 2 : angle > 90 ? 3 : 0;

}

}

 

return 반환해

 

  angle == 180 ? 

  각도가 180과 같다면? 4

  angle < 90 ?

  각도가 90보다 작다면? 1

  angle == 90 ? 

  각도가 90도와 같다면? 2

  angle > 90 ?

  각도가 90도보다 크다면? 3

  아니면 0

 

 

 

이렇게도 작성하는 방법이 있는데 정말 생각이 안 났다.

처음 보자마자 정말 오!!!!! 가 절로 나왔는데

댓글에서는 "실무에서 이렇게 쓰면 안 된다" ||"가독성이 떨어진다"라는 말이 많은 거 보니 우선은 코테같이 시간 싸움인 곳에서만 쓰거나 길지 않은, 짧게 나오는 경우 쓰는 습관을 들여야겠다.

 

기억하자 짧은 if문 대신 삼항연산자를 활용할 수도 있다!

삼항연산자 삼항연산자 삼항연산자!!!!! 삼항연산자아아아악!!!!!!!!!


🔒배열의 평균값

프로그래머스 입문문제 배열의 평균값 + 작성한 코드

역시나 for문 밖에 모르는 나는 오늘도 여러 번 for문을 써 내려갔다.

이 문제를 해결하고 다른 사람의 Stream 코드를 봤는데 Stream을 생각했다는 것과

서치 하지 않고, 생각한 대로 막힘없이 코드를 작성할 수 있다는 게 그렇게나 부러웠다.

솔직히 나는 Stream을 배우긴 했어도 쓰라면 딱 'Stream.' 까지만 쓸 수 있다😂😂😂

(아  ()가 없네? 그마저도 틀림....  )

그 뒤에 어떤 메서드를 써야 하는지 잘 모른다. 이다음 문제도 Stream을 적용할 수 있고

그다음문제도 Stream을 적용할 수 있었는데 항상 풀고 다른 사람의 풀이를 본 후에야  아~?   오! 만 나왔다.

나도 혼자서 작성할 수 있게 따라 쓰고 또 따라 쓰자! 

그렇기 때문에 다른 사람 코드에 Stream이 적용된 문제는 다 포스팅에 넣어보겠다.

다른 사람의 코드를 분석하자면

🔑 다른 코드 풀이 & 분석

import java.util.Arrays;

 

class Solution {

public double solution(int [] numbers){

return  Arrays.stream(numbers).average().orElse(0);

}

}

 

다시 봐도 짧고 간결하다... 멋있다.

 

아예 return 값으로 바로 출력되게 작성할 수 있다.

 

Arrays.stream(변수명)배열 (변수명)을 stream으로 변환( Arrays->Stream )하는 역할을 함.

// () 비어있지 않고 변수명을 넣어줌

 

.average()  평균 구하는 메서드 

//() 안이 비어있음.

 

.orElse(n)  값이 존재하지 않을 경우 or 주어진 값이 null인 경우에 기본값으로 n을 반환하는 역할을 함

**n을 문자로 작성할 경우 ClassCastException 에러발생!!!  이 경우에는  double대신 object 타입을 사용하여 다 둘 수 있지만 형변환이 필요할 수도 있음.


🔒피자 나눠 먹기(3)

프로그래머스 입문문제 피자 나눠 먹기(3) + 작성한코드

🔑 다른 코드 풀이 & 분석

class Solution {

public int solution(int slice, int n){

return n % slice > 0 ? n/slice+1 : n/slice;

}

}

 

 

반환해 return 

 

   n을 slice로 나눈 나머지가 0보다 크니?

   n % slice > 0 

   맞다면 

   n/slice+1

   아니라면

   n/slice

 

 

 

ㅋㅋㅋㅋㅋㅋㅋ아 또 삼항연산자다!!!!!!!!!

난 결국 생각을 못했던거다....ㅎ

아니 위에 문제가 지나간 지 1시간도 안 지났던 것 같은데...

이렇게 생각이 안 나네... 문제를 해결하는 센스가 왜 이러지?

아무튼 이번 문제는 그래도 나름 괜찮았던 것 같다.

삼항연산자가 생각이 나서 적용했다면 정말 뿌듯했을 텐데 그게 하나 아쉬운 문제였다.


🔒배열 뒤집기

프로그래머스 입문문제 배열 뒤집기 + 작성한코드

🔑 다른 코드 풀이 & 분석

 

import java.util.Collections;

import java.util.List;

import java.util.stream.Collectors;

import java.util.Arrays;

 

class Solution {

public int [] solution(int [] numList) {

List <Integer> list = Array.stream(numList).boxed().collect(collectors.toList());

 

Collections.reverse(list);

return list.stream().mapToInt(Integer::intValue).toArray();

 

 

Array.stream(변수명)   배열 변수명을 스트림으로 변환함.

 

List<Integer> list

.boxed()    기본 자료형의 스트림을 해당하는 래퍼 클래스의 박싱 된 스트림으로 변환 IntStrem -> Stream<Integer>

// 박싱은 기본 자료형을 해당하는 래퍼클래스로 변환하는 과정.   ex) int ->Integer /  double -> Double

 

.collect()   최종 연산 중 하나,   스트림의 요소들을 어떤 형태로 수집할지를 지정.

//.collect() 는 Collectors.~ 랑 같이 사용하는 듯?

 

Collectors.toList(스트림의 요소들을 List로 수집하는 역할.

 

Collections.reverse(list)  리스트를 뒤집음.

 

list.stream()   리스트스트림으로 변환

.mapToInt(Integer::intValue)요소를 int로 매핑함.

//  Integer::intValue는 Integer를 int로 변환하는 메서드 레퍼런스

.toArray()     스트림의 요소들을 배열로 변환함.

 

Stream 찢었다.

진짜 나도 꼭 잘 쓰게 만들어야지!!!!

 

또 다른 코드

 

class Solution {

public int[] solution(int[] numList) {

int length = numList.length;

 

for(int i =0; i < length / 2; i++)

{

int temp = numList[i];

numList[i] = numList{length - i -1];

numList[length - i - 1] = temp;

}

 

return numList;

 

같은 for문이지만 나는 배열 전체를 뒤에서부터 꺼내 넣어준 걸 출력했다면,  이 코드는 다른 배열을 생성하지 않고

 배열길이의 반까지만 for문을 돌리고 임의로 한 공간을 만들어 0번 인덱스의 값을 넣어준 후

0번 인덱스가 있던 자리에 끝 인덱스를 넣어주고 공간에 넣어놓았던 0번 인덱스였던 값을 끝인덱스 위치에 넣는 코드다

그렇게 되면 배열 중간까지 갔을 때 모든 인덱스들이 거꾸로 뒤집혀있으니까! 

이것도 강의에서 많이 보던 방식인데 전혀 생각이 나지 않았다.

뭐 계속 이렇게 하다 보면 나도 문제를 봤을 때 한 가지 방식이 아닌 여러 방식이 생각나지 않을까?


🔒문자열 뒤집기

프로그래머스 입문문제 문자열 뒤집기 + 서치 후 작성한코드

문자열 뒤집기는 무조건!!!!  무조건! 꼭!!!!!! 포스팅해야겠다 생각했다.

요번 멘털이 털린 테스트에서 문자열 뒤집기 때문에 두 시간을 허비해 놓고도 못 맞췄다.

그 문제는 잘라내서 버려야 하는 글자도 있었고, 배열식으로 인덱스 순서는 그대로인데 그 안에 문자열만 뒤집는 거였다.

split 함수를 사용하여 시도했으나 정말이지 결과가 너무 어이없었다. (또다시 그렇게 만들어보라면 못 만들 정도...)

수정의 수정을 거치다 보니 의도하지 않은 거울에 반사된 모양으로 이상하게 출력이 됐다.

일단 문자열 뒤집기는 내선에서 끝낼 수 없는 걸 알기에 기초부터 배워야겠다 생각했고 우선 바로 서치에 들어갔다.

아무래도 입문문제라 그런지 되게 간결하게 풀 수 있는 방법들이 있었다.

그중 StringBuffer를 사용해서 작성하는 방법이 있어서 따라 해봤다.

그리고는 다른 사람들의 더 다양한 코드를 살펴보았다.

🔑 다른 코드 풀이 & 분석

import java.util.*;

 

class Solution {

public String solution(String my_string) {

StringBuilder 객체 sb 생성

StringBuilder sb = new StringBuilder();

sb에 문자열 추가 

sb.append(my_string);

.reverse() 사용하여 문자열 뒤집기

sb.reverse();

.toString() 사용하여 문자열로 변환 

return sb.toString();

**여기서 또다시 문자열로 변환시켜 주는 이유는 StingBuilder는 가변적인 문자열을 나타내는 클래스이고, 사용하면서 발생한 변경은 내부 버퍼에만 적용되어 실제 문자열로 얻으려면 toString을 호출하여 변환해야 함. 

}

}

 

이 코드는 StringBuilder를 사용했다.

왜 buffer를 사용하지 않았을까.... 흠.

StringBuilder와 StringBuffer는 뭐가 다른 거지?

  • 공통점 :  둘 다 가변적인 문자열을 처리하는 클래스
  • 차이점 :
  1.  가변성 - Builder: 스레드 안전성이 보장되지 않음/ Buffer: 여러 스레드에서 동시에 수정되더라도 안전하게 동작함.
  2. 성능 - Builder: 단일 스레드환경에서 사용할 때 더 빠른 성능을 제공/ Buffer: 동기화 작업이 추가되어 성능이 떨어짐.

최근에는 StringBuilder를 더 선호(동기화를 지원하지 않기 때문에 성능상 이점이 있음. 상황에 따라 사용하는 클래스가 달라지겠지만 대부분의 상황에서는 Builder를 선호)

이렇게 찾아보다 보니  이거.. 배운 거였네;;;; 강의에서 분명 들은 기억이 났다.

또 다른 코드

 

class Solution {

public String solution(String my_String) {

return new StringBuilder(my_String).reverse().toString();

}

}

 

new StringBuilder(my_String)

.reverse()

.toString()

 

이 코드도 Builder를 썼다.

그리고는 한 번에 return값으로 잡아 출력했다.

코드 분석을 위해서 쪼개다 보니 위에 코드랑 결국에는 똑같은 코드인데 한 줄 버전인 거다!!!!!

 

StringBuilder sb = new StringBuilder();  객체를 sb라는 이름으로 생성해서 sb.~   sb.~   하지 않고

new StringBuilder(my_String) 객체를 생성한 곳에.~.~  바로 붙여서 return에 바로 출력!

 

 

 

 

제발 이렇게 쉬운 것부터 여러 번 차곡차곡 경험을 쌓아나가

나중에 어려운 문제들을 만났을 때 이 자잘한 것들이  떠올라 부분 부분 적용할 수 있게 되었으면 좋겠다.

입문문제이기 때문에 10개 정도는 하고 싶었는데 시간은 왜 이렇게 빠르게 흐르는지...

공부할 때는 천천히 흘러줘라... 제발 일할 때만 빠르게 흘러가줘🙏