[항해99] 2주차 [프로그래밍 기초] - 1Day 풀이

kyuu·2022년 11월 19일
0

항해99

목록 보기
17/19
post-thumbnail

항해99 시작주차 2주차 항해일지 <1day - 문제풀이>

  • 오늘은 2주차 주언어 프로그래밍 기초 시작일이다. 이번주차는 걷기반과 달리기반으로 나뉘는데 걷기반으로 할지, 달리기반으로 할지 엄청 고민이 됐다.
  • 전주 사용한 파이썬처럼 Java 실력도 애매했기 때문이다 👻
  • 그래도 뛰기반에 들어가서 팀원들이랑 강제로 발 맞추다보면 나도 경보정도는 할 수 있지 않을까(?) 싶어서 뛰기반에 들어왔당

✏️ 오늘의 문제들 풀이

  • 같은 조 팀원중 코치님이 계신데 10문제까지 풀라고 하셨다 ㅋ 열심히 풀었음
  • 풀었던 문제는 다시 한번 정리하면서 자세히 공부하려고함

1️⃣ 2016년


- 문제 :
2016년은 윤년이고, 2016년 1월 1일은 금요일이다.
월(a),일(b)을 입력받고 해당 날짜가 무슨 요일인지 리턴하는 함수를 작성하라

-풀이 :

public class HomeworkPrac4 {
    public static void main(String[] args){
        int a = 5;              // 월 입력 받을 변수 선언
        int b = 24;             // 일 입력 받을 변수 선언

        // 내가 생각한 문제 풀이 방법 : a월 b일까지의 모든 일수를 더한 후, 7일로 나눠서 매칭되는 요일을 출력하고자함

        int[] monthsDay = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        // 2016년은 윤년이므로 2월이 29일까지 있다. 매월 몇일까지 있는지 monthsDay 배열에 데이터를 넣어둔다.
        String[] day = {"FRI", "SAT", "SUN", "MON", "TUE", "WED", "THU"};
        // day라는 문자열 배열에 요일들을 넣는다. 1월 1일이 금요일이라했으니까 정렬하기 편하게 금요일부터 작성했다.

        int totalDate = 0;
        // a월 b일까지 총 몇일인지 구하여 저장하기 위한 totalDate 변수를 선언한다.

        for (int i =0; i < a-1; i++){
            // 반복문을 사용하는데 여기서 ( i < a-1)까지만 반복하는 이유는 a(=5)는 특정 일수(b)까지만 더해주면 되기 때문이다.
            totalDate += monthsDay[i];
            // totalDate 변수에 반복하여 MonthsDay[0] ~ MonthDay[3]까지의 숫자들을 더한다
        }
        totalDate += b-1;
        // 1월 1일부터 시작했기 때문에 Total count에서 -1을 빼준다.

        String answer = day[totalDate % 7];
        // 전체 일수(totalDate에서 7(일주일)을 나눠 해당 일자에 매핑 된 요일 정보를 받는다.

        System.out.println(answer);
        // 출력하여 확인
    }
}

이 문제에서 헷갈렸던 부분은 totalDate에서 b-1을 한 부분이였는데 팀원분들과 코드 리뷰 하던 중
기념일을 계산할때 오늘부터 1일을 세더라도, 오늘은 사실 0일째라는 개념과 비슷하다고 생각하니 이해가 쏙쏙 되었다.

*) 이외의 자세한 내용은 코드에 주석으로 작성하였다.

2️⃣ 나누어 떨어지는 숫자 배열

- 문제 :

  • 배열의 element 중 divisor 로 나누어 떨어지는 값을 오름차순으로 정렬한 배열을 반환
  • divisor로 나누어 떨어지는 element가 없다면 배열에 -1을 담아 반환한다.

import java.util.ArrayList;
import java.util.Arrays;

class proPrac1 {
    public static void main(String[] args) {
        int[] arr = {5, 9, 7, 10};
        // arr 배열 생성
        int divisor = 5;
        // divisor 값 담을 변수 생성
        int[] answer = {};

        ArrayList<Integer> list = new ArrayList<>();
        // division 연산을 위한 ArrayList 선언
        for (int i = 0; i < arr.length; i++){
            // arrr 배열의 길이만큼 반복하며 수행한다.
            if ( arr[i] % divisor == 0){
                // arr[i]번에 저장된 데이터를 divisor(5)로 나눴을때 0으로 떨어지면
                list.add(arr[i]);
                // list에 arr[i]번에 저장된 내용을 추가한다.
            }
        }
        if ( list.size()==0){
            // list size가 0이면(division element로 나누어떨어지는게 없다면) -1을 반환한다.
            answer = new int[1];
            // 앞에 선언해준 answer 배열에 크기 1으로 공간을 생성해서
            answer[0] = -1;
            // 첫번쨰 배열에 -1 을 저장하여 리턴한다.
        }else {
            for (int i=0; i < list.size(); i++){
                // list size가 0이 아니라면, list size만큼 반복하며 아래 구문을 수행한다.
                answer[i] = list.get(i);
                // answer(i)에 list(i)에 있는 데이터를 저장한다.
            }
            Arrays.sort(answer);
            // Arrays.sort 함수를 사용하여 오름차순으로 정렬한다.
        }
    }
}

-풀이 :
(1) Arraylist 사용 :

  • ArrayList는 List 인터페이스를 상속받은 클래스로 크기가 가변적으로 변하는 선형 리스트.
  • 배열은 한번 생성되면 크기가 변하지않지만, ArrayList는 객체들이 추가되어 저장 용량이 초과되면 자동으로 부족한만큼 저장 용량(capacity)가 늘어나는 특징이 있다.
*/ ArrayList 생성문
ArrayList list = new ArrayList();//타입 미설정 Object로 선언된다.
ArrayList<Student> members = new ArrayList<Student>();//타입설정 Student객체만 사용가능
ArrayList<Integer> num = new ArrayList<Integer>();//타입설정 int타입만 사용가능
ArrayList<Integer> num2 = new ArrayList<>();//new에서 타입 파라미터 생략가능
ArrayList<Integer> num3 = new ArrayList<Integer>(10);//초기 용량(capacity)지정
ArrayList<Integer> list2 = new ArrayList<Integer>(Arrays.asList(1,2,3));//생성시 값추가

*/ ArrayList 데이터 추가 
list.add(3); //값 추가
list.add(null); //null값도 add가능
list.add(1,10); //index 1에 10 삽입

*/ ArrayList 데이터 삭제
list.remove(1);  //index 1 제거
list.clear();  //모든 값 제거

*/ ArrayList 데이터 변경 
list.set(1, "b"); // 1번에 있는값을 "b"로 변경

*/ ArrayList 사이즈 구하기
list.size();  // list의 size 구하기

*/ ArrayList내 데이터 검색
list.contains(1) // list에 1이 있는지 검사

*/ ArrayList.get()
arrList.get(0)  //해당 번지의 값을 가져옴

3️⃣ 수박수박수박수박수박수?

- 문제 :

  • n의 패턴만큼 "수박수박수.."를 출력하는 문제
  • 별거 없는데 어떻게 풀어야할지 한참 고민했당
public class proPrac2 {
    public static void main(String[] args) {
        int n = 5; // n의 값을 저장하는 변수
        String result = ""; // 결과값을 출력할 String변수를 선언한다

        for (int i = 0; i < n; i++)
            // i는 0부터 n까지 반복
            result += i % 2 == 0 ? "수" : "박";
                // i를 2로 나눈 나머지가 0이면(참이면), "수" 거짓이면 "박"
        System.out.println(result);
    }
}

- 풀이
이 문제는 간단하니 풀이는 패스한다.

4️⃣ 완주하지 못한 선수

- 문제 :

  • 마라톤에 참여한 선수들의 이름이 담긴 배열과, 완주한 선수들의 이름이 담긴 배열을 비교하여
    완주하지 못한 선수의 이름을 return하는 문제

import java.util.Arrays;

public class proPrac5 {
    public static void main(String[] args) {
        String[] participant = { "leo", "kiki", "eden"};
        // 마라톤 참여 선수의 명단을 저장한다.
        String[] completion = {"eden", "kiki"};
        // 마라톤 참여 선수 중 성공한 선수의 명단을 저장한다
        String answer = "";

        Arrays.sort(participant);
        Arrays.sort(completion);
        // 참여 선수와 성공한 선수의 데이터가 담긴 배열을 오름차순으로 정렬한다.
        // 같은 차순으로 정렬을 해야 비교하기 편하기 때문

        for (int i =0; i < completion.length; i++){
            // for문을 사용하여 completion의 길이만큼 반복하는데, participant 를 두고 completion의 길이만큼 하는 이유는
            // 참여한 선수명단보다, 성공한 선수가 더 적기때문에 참여 선수 명단만큼 할경우 오류가 발생한다.
            
            if(!(participant[i].equals(completion[i]))){
                // 참여선수명단[i]와 완료선수명단[i]을 비교해서 만일 값이 틀린경우
                // 참여선수명단[i]의 참가자가 성공명단에 없는것이기때문에 그 사용자를 답으로 return 한다.
                answer = participant[i];
                break;
            }
            if(i == completion.length-1) answer = participant[i+1];
            // 만일 성공명단의 배열을 다 돌았는데도, 위 if문에서 걸리는게 없다면 참여선수의 명단 중 제일 마지막에 있는 사람이 
            // 통과하지 못한 사람이라고 간주하여 participant[i+1]을 더한 배열의 값을 리턴한다.
        }
    }
}
  • 풀이
    이 문제를 풀이할때는 약간 꼼수아닌(?) 꼼수를 사용했다.
    참가자명단과, 완주자 명단을 비교하여 틀린값이 있으면 그 사람이 미완주자 처리가 되도록 하거나
    만일 완주자명단만큼 반복했음에도 불구하고 찾아내지못했다면 참가자명단의 맨 마지막 사람이 미완주자(=미완주자는 1명이니깐) 처리되도록 구현했다.

5️⃣ 이상한 문자 만들기

- 문제 :

  • 문자열내의 단어를 짝수번째 알파벳은 대문자로, 홀수번째 알파벳은 소문자로 바꾼 문자열을 리턴
public class proPrac4 {
    public static void main(String[] args) {
        String a = "try hello world";
        // 문자열을 a에 저장
        String[] aChange = a.split(" ");
        // 저장한 문자열을 공백을 기준으로(=단어별로 홀/짝을 변환해야하니까) 나누어 배열에 저장
        String answer = "";

        for (int i = 0; i < aChange.length; i++) {
            for (int j = 0; j < aChange[i].length(); j++) {
                // 다중 for 문을 이용하여 각 단어의 길이만큼 반복하고, 총 문자열만큼 반복한다.
                if (j % 2 == 0) {
                    // aChange[j]를 2로 나눈값이 0 이라면 == 짝수
                    String result = String.valueOf(aChange[i].charAt(j));
                    // aChange[i]번의 [j]번째 글자를 char 타입으로 한글자만 받아와서 스트링 형식으로 변환하여 result에 저장
                    answer += result.toUpperCase();
                    // answer 배열에 저장하기 전 toUpperCase라는 함수로 소문자를 대문자로 변경 한 후 저장
                } else {
                    String result = String.valueOf(aChange[i].charAt(j));
                    // 홀수자리의 알파벳도 aChange[i]번의 [j]번째 글자를 char 타입으로 한글자만 받아와서 스트링 형식으로 변환하여 result에 저장
                    answer += result;
                    // 소문자 그대로 출력하면 되기때문에 그대로 배열에 넣는다
                }
            }
            if(i==aChange.length-1){break;}
            // 단어를 합칠때 단어 사이사이 공백을 만들어주기 위해서 해당 부분을 사용한다.
            // 맨 마지막 단어(world) 뒤에는 공백이 필요하지않기 때문에 if문을 사용했다.
            answer+=" ";
        }
        System.out.println(answer);
    }
}
  • 풀이 :
    이 문제는 정답이 나옴에도 불구하고 테스트만 하면 실패했다고 떠서 아직 미지의 부분에 있다.
    성공 소스를 짜긴 했는데 아직 이해가 잘 안되서 시간 날때 다시 해볼 예정

📌 valueOf

  • String.valueOf()메소드는 object의 값을 String으로 형변환할때 사용하는 부분으로
  • 비슷한 메소드에는 toString()이 있다.
  • 두 메소드가 비슷한 역할을 하는데 한가지 차이점이 있다면 변경 값이 Null일때 NullPointerException의 발생 유무이다.

*) 넘어오는 object의 값이 null일때 ? :

  • toString() : null 값을 형 변환 시 NullPointerException(NPE)이 발생 / Object의 값이 String이 아니여도 출력
  • String.valueOf() : 파라미터로 null이 오면 "null"이라는 문자열을 출력

📌 charAt

  • charAt함수는, string 타입으로 받은 문자열을 char 타입으로 한 글자만 받는 함수이다.
  • 이번 문제에서는 한글자만 받아와서 대문자로 바꿔주는 작업이 필요하여 해당 함수를 사용하였다.

*) 만약 받아오려는게 문자가 아니라 숫자였다면 아래와 같이 사용해야한다.

String a = "0";
int b = a.charAt(0) - 48;
(48을 하는 이유는 숫자 0-9까지는 유니코드상 48-57이기 때문임!)

📌 toUpperCase, toLowerCase

  • 대상문자열을 대문자/소문자로 변경해주는 함수

6️⃣ 자릿수 더하기


- 문제 :

  • 자연수N의 각 자릿수의 합을 구해서 리턴하기
import java.util.stream.Stream;

public class proPrac6 {
    public static void main(String[] args) {
        int num = 123;
        // 123의 각 자릿수를 더하여 계산할 예정
        int sum = 0;

        int[] numArray = Stream.of(String.valueOf(num).split("")).mapToInt(Integer::parseInt).toArray();
        // 스트링 배열을 int 배열로 변환한다.
        // Stream.of()는 지정된 array에서 순차 스트림을 만드는 데 사용함
        // 한글자 한글자 분리해야되기 때문에 split("")을 사용해서 분리한다.
        // mapToInt 스트림을 IntStream으로 변환해주는 메서드

        for (int i = 0; i < numArray.length; i++) {
            // for문으로 numArray.length만큼 반복한다.
            sum += numArray[i];
            // sum에 각 자릿수를 더하여 저장함
        }
        System.out.println(sum);
    }
}

- 풀이 :

  • 정수형 문자를 받아서 각 자리별로 나눈다음 정수형 배열에 넣어야하는데 해당 부분을 고민을 오래했다.
  • 검색해보니 정수형 문자를 받아서, 문자열을 한글자씩 쪼개서 스트림 배열에 넣은다음 다시 정수형 배열로 바꿔줄때는 11행처럼 사용하는 것 같았다.
  • 어떤 이유로 사용했는지는 찾았지만 활용하려면 조금 더 공부해봐야겠다

7️⃣ 자연수를 뒤집어서 배열로 만들기

- 문제 :

  • 자연수n을 뒤집어 각 자리 숫자를 원소로 가지는 배열 형태로 리턴하기
  • 54321이면 [1,2,3,4,5]로 리턴해야함

public class proPrac7 {
    public static void main(String[] args){
        long num = 123 ;
        // 뒤집어서 배열로 바꿀 변수를 선언함
        String nStr = ""+num;
        // 입력받은 정수형 변수를 String으로 바꾸기 위해서 사용
        // 문자열 + 정수형변수를 더하면 문자열로 변하기 때문!

        StringBuffer tp = new StringBuffer(nStr);
        String reverse = tp.reverse().toString();
        //문자열을 뒤집기 위해서 StringBuffer 클래스를 이용해 객체를 생성한다
        //StringBuffer 객체를 생성 후에 제공되는 reverse() 메서드를 사용하여 뒤집는다.

        char[] rChar = reverse.toCharArray();
        // 뒤집은 문자열을 한글자 한글자 배열에 넣어야하기 때문에 char 문자형으로 변환한다.
        int[] answer = new int[rChar.length];
        // char배열에 있는 데이터를 int형 변수에 넣어서 리턴해야되기 때문에 char 배열 size 크기의 int 배열을 만든다.

        // char를 int로 바꿔서 다시 출력함 Character의 getNumericValue(char ch) 이용
        int i=0; // 인덱스용
        for(char c : rChar){
            // rchar에 있는 값들을 다 불러올때 까지 반복
            answer[i++] = Character.getNumericValue(c);
            // rchar[i]값을 사용 후 i를 1 증가
            // 숫자형태의 char형을 Int형 배열로 바꾸기 위해 Character.getNumericValue 함수를 사용
        }
    }
}

- 풀이 :

  • 정수형을 문자열로 저장하여, 뒤집기위해서 StringBuffer의 reserve()메소드를 이용했다.
  • 바꾸고 싶은 문자열이 있으면 StringBuilder 또는 StringBuffer 객체를 생성하여 reverse() 메소드를 사용해서 변경할 수 있다.
  • 기본적인 String클래스의 인스턴스는 한번 생성되면 그 값을 읽기만 할 수 있고 변경할수 없지만 StringBuffer 클래스를 사용하면 인스턴스 값을 변경할수도있고, 추가할수도있다.

✏️ ) StringBuffer :
인스턴스 값 변경/추가를 위해 StringBuffer클래스는 내부적으로 버퍼 공간을 가진다.
기본값은 16개의 문자를 저장할수있고, 생성자를 통해 크기는 별도 설정이 가능하다.

덧셈(+) 연산자를 이용해 String 인스턴스의 문자열을 결합하면, 내용이 합쳐진 새로운 String 인스턴스를 생성하여 결합하면 할수록 늦어지는데,

StringBuffer 인스턴스를 사용하면 문자열을 바로 추가할 수 있으므로, 공간의 낭비도 없고 빨라진다고 함!

8️⃣ 자연수를 뒤집어서 배열로 만들기


import java.util.Arrays;
import java.util.Collections;

public class proPrac8 {
    public static void main(String[] args) {
        int n = 118372;
        long answer = 0;
        String sum = "";

        String page = "" + n;
        // 정수형 n값을 문자열로 변경

        String[] pagen = page.split("");
        // 한자리씩 분리하기위해서 ""으로 분리하여 배열에 저장
        Arrays.sort(pagen, Collections.reverseOrder());
        // 역순으로 정렬

        for (int i=0; i < pagen.length; i++ ){
            sum += pagen[i];
            // sum 배열에 pagen 배열에 있던 데이터 순차적으로 저장
            answer = Long.parseLong(sum);
            // String형 배열을 Long 형으로 형변환
        }
    }
}

- 풀이 :

  • 앞에 풀었던 문제들과 비슷한 유형이므로 설명 생략! 주석 참조

9️⃣ 자연수를 뒤집어서 배열로 만들기


- 문제 :

  • 임의의 정수 n에 대해, 양의 정수 x의 제곱인지 아닌지 판단하여 n이 x의 제곱이라면 x+1을 리턴하고, 아니라면 -1을 리턴한다.
  • 제곱근이라는거부터 몰라서 찾아서 푸느라 조금 오래걸렸당
 Double n_value = Math.sqrt(n);
        // Math.sqrt 함수는 n의 제곱근을 반환한다.

        if (n_value == n_value.intValue()) {
            return (long) Math.pow(n_value + 1, 2);
            // Math.pow는 n_value에 1을 더한값을 2번 곱할때 사용한다,

        } else {
            return -1;
        }

- 풀이 :
java의 Math함수를 이용하여 제곱근, 제곱한 값을 구할 수 있다.

🔟 제일 작은 수 제거하기


- 문제 :

  • 배열에서 가장 작은수를 찾아서 가장 작은수를 제거한 배열을 리턴
  • 만약 arr의 값이 [10]이면, -1을 반환
class Solution {
    public int[] solution(int[] arr) {

        if(arr.length == 1){	//배열 길이가 1인(=10이 들어가있는경우)
            int[] answer = {-1}; // -1을 리턴
            return answer;
        }


        int[] answer = new int[arr.length-1];
		// 가장 작은수를 빼야하니까 가장 작은수를 뺀 길이로 생성한다
        int min = arr[0]; 
        // 기준값을 잡는다
        for(int i=1; i<arr.length; i++){
            min = Math.min(min, arr[i]);
            // Math.min 함수를 사용하여, min과 arr[i]의 값을 비교하여 작은값을 min변수에 넣는다.
        }
        int index = 0;

        for(int i=0; i<arr.length; i++){

            if(arr[i] == min){
				// arr[i]가 min의 값과 같으면
                continue;
                // 저장하지않고 넘어가고,
            }
            answer[index++] = arr[i];
            // 같으면 answer 배열에 추가한다.
        }

        return answer;
    }
}

이렇게 오늘의 10문제 정리가 끝났다.
오늘 문제를 풀때는 주석을 다 미리미리 달아둬야지 😎
끝!

profile
엔지니어 꿈틀 개발자

0개의 댓글

관련 채용 정보