wisePocket

[Algorithm] 제곱근 루트 구하는 계산기 만들기 본문

Java & Algorithm/Algorithm Practice

[Algorithm] 제곱근 루트 구하는 계산기 만들기

ohnyong 2023. 8. 7. 21:49

숫자를 입력받아 제곱근을 찾아내는 프로그램 계산기 만들기

정해진 나의 룰에 따라서 연습 문제를 계속해서 답안을 보지 않고 스스로 풀어보고자 한다.

핵심이 되었던 연습 과정은 아래 두개 과정이다.
물론 이 구조가 이제 Java를 배우면서 더 깊게 변경 될 예정이다.
하지만 해당 카테고리 페이지는 
알고리즘 문제 해결을 하기 위한 연습이 주 목적이라서
기본적으로 내가 객체 인스턴스화를 통해 메서드 호출을 구분하면서 
"연산"에 집중 할 수 있는 나만의 틀로 활용하고자 한다.
 
https://ohnyong.tistory.com/177
 [Algorithm★] 4칙연산을 해주는 계산기 - 객체 지향 - 혼자 만들기+ChatGPT의 피드백 받기

https://ohnyong.tistory.com/178
 [Algorithm★] 4칙연산을 해주는 계산기 - 객체 지향 - 혼자 만들기+ChatGPT의 피드백 적용
SQL과 알고리즘 둘다 연습 문제 푸는데, 프로그래머스 사이트 자체적으로 문제 현황이 기록되는줄 이제 알았다. 모든 문제를 기록하고 있었는데 반복되는 경우도 많아서 SQL은 특별하게 어려웠거나 특징적인 것들을 기록하고자 하고,
Java알고리즘은 매번 새롭다보니 계속해서 이 방식으로 후기글을 작성하고자 한다. 이번엔 Math클래스의 Math.sqrt()라는 메서드를 사용해보았다. 루트를 연산해주는 프로그램인데 어딘가 쓸대가 있을것 같은데 확 와닿지는 않는다. 근대 방법 자체가 재밌어서 푸는데 재미있었다.
 
 
1. 문제 파악 과정
 - 필요 데이터 파악
    +--- 데이터 타입 확인

 - 필요 메서드 파악
    +--- 기본 입력부 input(){} 
             +-- 입력 값 갯수 확인
             +-- 데이터 제한조건 파악(유효성검사 while loop)
    +--- 기본 계산부 calculate(){}
             +-- 필요 연산 확인
             +-- 필요 조건 확인
    +--- 기본 출력부 output(){}
             +-- 출력할 데이터, 내용 확인
    +--- 각 메서드 별 파라미터 전달 필요 부분 확인
 
2. 코드 작성 과정
 - Main.java 실행부 생성 , Solution.java 클래스(설계도) 생성

 - 클래스 member 구현
    +--- 필요 데이터 정리에 따라 변수 선언
    +--- 기본 생성자 선언
    +--- 필요 메서드 정리에 따른 메서드 선언
             +-- input(){}과 관련된 메서드부터 작성, 유효성 체크(진입부 메서드)
             +-- calculate(){}의 실제 연산 로직 작성
             +-- output(){}의 출력 관련 정리

 - 실행부 Main.java에서 객체 인스턴스 생성 및 객체로부터 진입부 메서드 호출

 


0. 프로그래머스

프로그래머스에서 연습 문제를 실행 시킬 수도 있어서 아마 Main을 따로 나누지 않고 하나로 하는 것도 연습해야겠다. 이런 테스트 플랫폼에서 한다면 클래스 파일을 하나로만 사용해야 될 수도 있기 때문에 연습해야 될 것같다고 느꼈다. 상당히 코드가 줄어든다.

class Solution {
    static double rowN;
    static int resultN;
    int answer;
    public int solution(int n) {
        if(n<1 || n>1000000){
            System.out.println("잘못된 숫자 입력");
        }else{
            rowN = Math.sqrt(n);
            resultN = (int)rowN;
        if(rowN == resultN){
            answer = 1;
        }else{
            answer = 2;
            }
        }
        return answer;
    }
}

검색해보니 진짜 문제풀이만을 위한 아래같은 코드도 있었다. 그런데 제한사항 같은 유효성체크는 안하는건가?? 그냥 답만 빠르게 내면 되는 것인가 혼란스럽다. 뭔가 프로그램같지 않고 암기식 공부처럼 흘러가는데 어디에 기준을 두어야 될지 모르겠다.. 

class Solution {
    public int solution(int n) {
        return (int)Math.sqrt(n)*(int)Math.sqrt(n) == n ? 1:2;
    }
}

 

1. Main.java

이번 실습까지는 나누어서 진행해보고 다음 실습부터 하나로 합쳐야 겠다. 별것 아니긴 한데 객체를 생성하고 메서드를 불러오는 것을 익숙하게 하기 위해서 일부러 했던 과정인데 

package Algorithm12;

public class Main {
    public static void main(String[] args){
        Solution solution = new Solution();
        solution.input();
    }
}

 

2. Solution.java

연산은 약간 고등학교 수학정도로 생각해야 했다. 근대 오래되서 기억이 잘 나질 않는다. 루트는 많이 들어봤지만 제곱수라고 명칭이 있었는지는 기억이 안났다. 아무튼 제곱근을 구하는 것이기 때문에 분명 Math클래스에서 기능이 있을 것이라 생각해서 뒤져보았는데 Math.root가 없는것이다. 그런데 잘 보니 sqrt라고 줄임말로 써져있는 것 같았다. 4로 테스트를 해보니까 역시 제곱근을 구하는 메서드가 맞아서 사용하게 되었다. 유효성체크를 모두 걸어주고 테스트를 진행했다.

package Algorithm12;

import java.util.Scanner;

public class Solution {
    /*문제 설명
    어떤 자연수를 제곱했을 때 나오는 정수를
     제곱수라고 합니다.
      n^2 = result  => int jegopsu

      정수 n이 매개변수로 주어질 때,
      if result == jegopsu =>return 1
      else =2

      n이 제곱수라면 1을
      아니라면 2를 return하도록 solution 함수를 완성해주세요.

    제한사항
    1 ≤ n ≤ 1,000,000*/
    int inputNum;
    double rootRow;
    int rootResult;
    int resultFlag;
    int tryNum;
    Scanner sc = new Scanner(System.in);

    public Solution() {

    }

    void input() {
        while (true) {
            System.out.println("아무 숫자를 입력해 보세요. 제곱수 판별기입니다.");
            inputNum = sc.nextInt();
            if (inputNum < 1 || inputNum > 1000000) {
                System.out.println("숫자는 1~100만까지만 입력하세요.");
                continue;
            }
            calculate(inputNum);
            break;
        }
    }

    void calculate(int inputNum) {
        //    만약 4를 입력하면 2가 제곱수
        //     input 4         jegopsu 2
        //    16을 입력하면 4가 제곱수.
        //    16 = 4*4  :  input = je*je
        rootRow = Math.sqrt(inputNum);
        rootResult = (int) rootRow;
        System.out.println(rootRow);
        System.out.println(rootResult);
        if (rootRow == rootResult) {
            resultFlag = 1;
            outputRoot(inputNum, rootRow, rootResult, resultFlag);
        } else {
            resultFlag = 2;
            outputRoot(inputNum, rootRow, rootResult, resultFlag);
        }
    }

    void outputRoot(int inputNum, double rootRow, int rootResult, int resultFlag) {
        if (resultFlag == 1) {
            System.out.printf("입력하신 %d는 제곱수로, 제곱근은 %d입니다. -%d", inputNum, rootResult, resultFlag);
        } else {
            System.out.printf("입력하신 %d는 제곱수가 아닙니다. -%d\n", inputNum, resultFlag);
        }
        tryAgain();
    }

    void tryAgain() {
        System.out.println("다시 실행하시겠습니까?\n[1] YES   [2] NO");
        tryNum = sc.nextInt();
        while (true) {
            if (tryNum == 1) {
                input();
                break;
            } else if (tryNum == 2) {
                System.out.println("안녕히가세요.");
                System.exit(0);
                break;
            }
        }
    }
}