pwoogi
자신의 왜곡된 경험을 진실이라고 생각하지 말자

Algorithm/프로그래머스 LV.0 (Day 1)

[JAVA] 알고리즘 입문 LV.0

pwoogi 2022. 7. 16. 02:08
드디어 알고리즘 세상에 입문

 

우선 알고리즘이란 무엇일까?

 

1. 알고리즘과 순서도 개념 작성법

  • 컴퓨터를 이용한 문제 해결 4단계

우리가 컴퓨터를 사용하는 목적은 주어진 문제를 사람의 힘으로 해결하지 않고 컴퓨터를 이용하여 해결하자는 것이다. 이러한 컴퓨터를 이용한 문제 해결은 다음과 같은 4단계를 거친다.

1단계 : 주어진 문제를 정확하게 이해하고 이를 분석한다.

2단계 : 분석한 문제를 해결하기 위한 가장 좋은 방안을 구상한다. 이 결과물이 알고리즘(Algorithm)이다.

3단계 : 알고리즘을 컴퓨터가 알아들을 수 있는 방법으로 표현하여 컴퓨터가 이를 수행하도록 지시한다.

이러한 작업이 프로그래밍(Programming) 또는 코딩(Coding)이다.

프로그래밍을 잘하려면 C언어나 Java와 같은 프로그래밍 언어를 알아야한다. (난 JAVA)

 

4단계 : 작성한 프로그램을 컴퓨터상에서 실행하여 출력을 얻는다. 만일 이때 얻은 출력이 처음 기대한 바와 달면 프로그램이 잘못 작성된 경우이므로 3단계 프로그래밍 과정을 다시 거친다. 이러한 검증 과정이 디버깅(Debugging)이다.

*요약

문제 이해 및 분석 -> 알고리즘(문제해결방안) -> 프로그래밍(코딩) -> 검증(디버깅)

출처-jihoman13님 블로그

 

어차피 미친듯이 문제 풀건데 개념은 가볍게 이정도 알아보고 더 궁금하면 구글링하자

 

참고로 아래의 알고리즘 풀이에 대한 설명의 용어나 개념들이 조금 어긋날 수도 있다. 5일차니까 뭔소리인가 싶으면 구글링하자. ?물음표? 붙일테니 이해해주자. 나중에 고치겠다.

 

 

1. 직사각형 별찍기

문제 : 이 문제에는 표준 입력으로 두 개의 정수 n과 m이 주어집니다.
별(*) 문자를 이용해 가로의 길이가 n, 세로의 길이가 m인 직사각형 형태를 출력해보세요.

 

조건 :

  • n과 m은 각각 1000 이하인 자연수입니다.

해결 :

import java.util.Scanner;

class Solution {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int b = sc.nextInt();
        
        for(int i=0; i < b; i++){
            for(int j=0; j < a; j++){
                System.out.print("*");
            }System.out.println();
        }

    }
}
입력 : 3, 5
출력 : 
*****
*****
*****

해석 :

1. 우선 Scanner 클래스를 이용해서 입력받을 객체? 에 대한 변수 sc를 선언하고 System.in 으로 값을 받는다.  

2. 입력받은 값을 저장할 변수 a, b에 저장

3. 그리고 중복  for문을 이용하여 돌린다. 

4. 예를 들어 b가 5인 경우 첫번째 i의 값은 < 5 인 조건을 만족할때까지 반복하고 두번째 j의 값은 < 3보다 작은 조건을 만족할때까지 반복한다. 

즉, 5번 * 별을 찍고 아래로 3번 찍어주는 구조이다. (반복문 끝나고 println이 아닌 print (줄바꿈X)을 주의하자)


 

2. 짝수와 홀수

문제 : 정수 num이 짝수일 경우 "Even"을 반환하고 홀수인 경우 "Odd"를 반환하는 함수, solution을 완성해주세요.

조건 :

  • num은 int 범위의 정수입니다.
  • 0은 짝수입니다.

해결

class Solution {
    public String solution(int num) {
        String answer = (num%2 == 0) ? "Even" : "Odd";
        return answer;
    }
}

해석

1. 정수 num이 짝수인 경우니까 나머지가 0인 경우 Even, 나머지가 0이 아닌경우 Odd를 출력하기 위해서 삼항연산자를 이용하여 해결했다


 

3. 가운데 글자 가져오기

문제 : 단어 s의 가운데 글자를 반환하는 함수, solution을 만들어 보세요. 단어의 길이가 짝수라면 가운데 두글자를 반환하면 됩니다.

 

조건 :

  • s는 길이가 1 이상, 100이하인 스트링입니다.

해결

class Solution {
    public String solution(String s) {
        if(s.length()%2==0){
            return s.substring(s.length()/2-1,s.length()/2+1);
        } else {
            return String.valueOf(s.charAt(s.length()/2));
        }
    }
}

해석

1. 문자열 길이를 구하는 메서드인 length를 이용하여 우선 짝수인 경우(나머지가 0)를 구해야했는데 String 클래스가 제공하는 substring 함수를 이용하였다.

2. substring함수는 주어진 시작 위치와 끝 위치에 포함된 문자열을 반환해주는 메서드이다.뒤에 매개변수를 활용하는 방법을 알아보자

String substring(int begin) : 시작 위치만 정한경우 끝 위치까지의 index요소를 모두 반환
String substring(int begin, int end) : 끝 위치까지 정해준 경우 끝의 index요소를 제외하고 모두 반환
- > String s = "Java.lang.object"
String c = s.substring(10)    출력 : "object"
String d = s.substring(5, 9)    출력 : "lang"
'.' 도 문자열에 포함되니 주의하자

3. valueOf 역시 String 클래스가 지원하는 메서드로써 지정된 값을 문자열로 반환하여 반환한다.( 참조변수인 경우 toString)  예 : String.valueOf(true);  출력 : "true"


4. 두 정수 사이의 합

 

문제 : 두 정수 a, b가 주어졌을 때 a와 b 사이에 속한 모든 정수의 합을 리턴하는 함수, solution을 완성하세요.
예를 들어 a = 3, b = 5인 경우, 3 + 4 + 5 = 12이므로 12를 리턴합니다.

 

조건:

  • a와 b가 같은 경우는 둘 중 아무 수나 리턴하세요.
  • a와 b는 -10,000,000 이상 10,000,000 이하인 정수입니다.
  • a와 b의 대소관계는 정해져있지 않습니다.

해결

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

 

해석

1. 너무나 다양방법이 존재하지만 필자는 a > b 인 경우만 if 문을 거치고 for 문에 진입하는 구조를 만들었다.

2. a < b 인경우는 바로 for문으로 진입하여 해결하는 방법이다.

3. if 문에서 a > b 경우에 치환한 이유는 for문의 조건문인 i <= b 를 만족시키기 위해서 치환하였다.

 


5. 문자열을 정수로 바꾸기

문제 : 문자열 s를 숫자로 변환한 결과를 반환하는 함수, solution을 완성하세요.

조건:

  • s의 길이는 1 이상 5이하입니다.
  • s의 맨앞에는 부호(+, -)가 올 수 있습니다.
  • s는 부호와 숫자로만 이루어져있습니다.
  • s는 "0"으로 시작하지 않습니다.

해결

class Solution {
    public int solution(String s) {
        return Integer.parseInt(s);
    }
}

해석 :

1. Integer.parseInt 기능을 알면 쉽게 해결할 수 있다.

2. parseInt()의 기능은 String타입의 숫자를 int타입으로 변환해주는 역할

예시를 보고 이해해보자

String number1 = new String("1234");
String number2 = new String("4321");
System.out.println(number1 + number2);

- 문자열 1234, 4321 을 합치면 555라는 결과가 나올거라고 예상했을 것이다. 당연히 아니다. 궁금하면 코드를 치면된다.

String strNum1 = new String("1234");
String strNum2 = new String("4321");

int num1 = Integer.parseInt(strNum1);
int num2 = Integer.parseInt(strNum2);

System.out.println(num1 + num2);

-위와 같이 문자열 타입의 숫자를 integer 타입으로 변환하여 출력해야 555라는 결과가 나온다. 부디 나같은 초보개발자가 무사히 이해하길 바란다.


 

6. 없는 숫자 더하기

 

문제 : 0부터 9까지의 숫자 중 일부가 들어있는 정수 배열 numbers가 매개변수로 주어집니다. numbers에서 찾을 수 없는 0부터 9까지의 숫자를 모두 찾아 더한 수를 return 하도록 solution 함수를 완성해주세요.

 

조건 :

  • 1 ≤ numbers의 길이 ≤ 9
    • 0 ≤ numbers의 모든 원소 ≤ 9
    • numbers의 모든 원소는 서로 다릅니다.

해결 : 

class Solution {
    public int solution(int[] numbers) {
        int answer = 45;
        
        for(int number : numbers) {
            answer -= number;
        }          
        return answer;
    }
}

해석 : 

1. 아래의 출력 예시를 보자

numbers result
[1,2,3,4,6,7,8,0] 14
5, 9가 없으므로  5+9 = 14

2.정수배열안에 없는 정수의 index를 1~9까지의 합에서 빼주면 된다

3. answer 변수에 저장된 45를 향상된 for문 numbers 배열안에 요소를 하나씩 꺼내어 빼주고 결과를 저장하면 된다.

 

int [] numbers = { 1, 3, 5 }; 라면 45에서 1,3,5를 하나씩꺼내어 빼주면 배열에 없는 요소들의 합이된다는 말이다. 코딩천재들은 많은 것 같다.


7. 음양 더하기

 

문제 : 어떤 정수들이 있습니다. 이 정수들의 절댓값을 차례대로 담은 정수 배열 absolutes와 이 정수들의 부호를 차례대로 담은 불리언 배열 signs가 매개변수로 주어집니다. 실제 정수들의 합을 구하여 return 하도록 solution 함수를 완성해주세요.

 

조건: 

  • absolutes의 길이는 1 이상 1,000 이하입니다.
    • absolutes의 모든 수는 각각 1 이상 1,000 이하입니다.
  • signs의 길이는 absolutes의 길이와 같습니다.
    • signs[i] 가 참이면 absolutes[i] 의 실제 정수가 양수임을, 그렇지 않으면 음수임을 의미합니다.

해결: 

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        for(int i = 0; i < absolutes.length; i++){
            if(signs[i]==true){
                answer += absolutes[i];
            }else{
                answer -= absolutes[i];
            }
        }
        return answer;
    }
}

해석 : 

1. 마지막 조건인 signs[i] 가 참이면 absolutes[i] 의 실제 정수가 양수임을, 그렇지 않으면 음수임을 의미한다는 것을 기억하자

2. 그렇다면 absolutes 배열의 길이만큼 변수 i를 반복시키고 sign 배열의 인덱스 i 가 true인 경우에는 answer변수에 더해주고  sign 배열의 인덱스 i 가 음수이면 answer 변수에서 빼준다음에 결과를 반환해주면 된다.

3. absolutes 배열의 길이가 3이고 index 요소가 { 1, 5, 7} 이라고 가정했을 때 sign 배열의 index 요소가 {true, false, true} 라면 for문을 돌렸을 때 결과는 { 1, -5, 7 } 가 각각 answer에 결과를 반환하니까 최종결과는 3이된다.

 


8. 평균 값 구하기

 

문제 : 정수를 담고 있는 배열 arr의 평균값을 return하는 함수, solution을 완성해보세요.

조건 : 

  • arr은 길이 1 이상, 100 이하인 배열입니다.
  • arr의 원소는 -10,000 이상 10,000 이하인 정수입니다.

해결 : 

class Solution {
    public double solution(int[] arr) {
        double sumArr = 0;
        for(int i = 0; i < arr.length; i++){
            sumArr += arr[i];
        }
        sumArr /= arr.length;
        return sumArr;
    }
}

해석 : 

1. 배열의 길이만큼 인덱스 요소를 sumArr 변수에 계속 더해서 저장한다. 

2. 저장한 sumArr 변수의 값을 배일의 길이만큼 나누면 된다.


정리를 하고나니까 복습도 되는 느낌이다. 우선 지금을 결과를 보고 이해하는데 최대한 집중하자