편집 기록

편집 기록
  • 프로필 알 수 없는 사용자님의 편집
    날짜2019.05.22

    Java 프로그래밍 질문좀 드릴게요.


    초보 프로그래머입니다!!. 프로그래머스의 자바입문을 수강 후, 어떻게하면 프로그래밍 실력을 늘릴까 하다가 인터넷을 찾아보니 되도록 코드를 많이 짜보라고 하더라구요. 그래서 마침 눈에 띄는 중1수학책에 보니 '소인수분해를 이용한 최대공약수 구하기'가 보여서 그걸 주제로 코드를 짜보았습니다.

    프로그램은 원하는 결과값은 나오는데요. 제가 질문드리고 싶은건 첫째 객체지향프로그램은 클래스들의 집합이라고 했는데, 제가 짠 프로그램은 클래스가 1개입니다. 클래스를 나누는 기준을 어떻게 잡으면 좋을까요?;; 제 프로그램이 작아서 그런진 몰라도 이게 나눠도 되나? 이런 생각만 들더라구요.

    둘째 메소드일지 클래스일지 결정입니다. 첫번째 질문의 연잔선상일 수 있는데요. 어떤 메소드를 만들때 이걸 클래스로 해야할지 메소드로만 해야할지 결정하기가 어렵습니다. 제 코드 같은 경우 소인수분해를 이용한 최대공약수 구하기 프로그램인데 소인수분해 하는 부분, 최대공약수 구하는 부분, 지수를 정규화하는 부분 3가지로 프로그램을 나눌수 있고, 이들의 비중은 4:4:2 정도로 생각합니다.

    이 때 소인수분해하는 메소드를 만든다고 했을때 저는 소인수분해하는 부분이 최대공약수를 구하기 위한 행동이라고 생각하여 메소드라고 넣어놨습니다만, 소인수 분해하는 부분이 또 다른 클래스로 가도 되는지 궁금하고, 어떤 메소드를 만들때 그냥 메소드로만 할지 클래스로 할지 결정하는 기준 (개인적인 기준도 괜찮습니다) 있으신지 궁금합니다.

    셋째 public과 private의 사용기준을 잘 모르겠습니다. 이 부분을 위해서 제가 들은 강의를 재 반복하였으나 도무지 모르겠습니다. 실제 코드를 짜다보니 어떨대 private, public, protected를 넣을지 감이 안잡힙니다. 예를들어 클래스가 몇개이상일때 이걸 써라, 이건 클래스 개수와 상관없이 이럴 경우 써봐라 등등 팁좀 알려주시면 감사하겠습니다!!.

    사진은 제가 프로그램을 짤 때 그린 약도 및 코드 입니다. 나름 해답을 찾으려 구글링 및 혼자 생각을 해보았지만, 머리속만 더 어지러워져 질문을 올립니다. 프로그래밍 초보라 질문이 허접할 수 있겠지만, 많은 지식공유 및 조언좀 부탁드립니다.!!

    이미지

    이미지

    아래부터는 코드 입니다.

    
    package mathProgramming;
    import java.util.ArrayList;
    
    public class TheGreatestCommonDivisor {
    
        public int number ; //소인수 분해 할 첫째  정수
    
        public ArrayList<Integer> numS = new ArrayList<>(); // 정수의 소인수 값
        public ArrayList<Integer> numE = new ArrayList<>(); // 정수의 소인수의 지수 값  
    
        public void FractionalDecomposition (int number) { //입력 받은 두수의 소인수 분해한 값을 구하는 함수
    
            this.number = number;
    
            int result = 0; // 재귀함수 호출을 위해 사용하는 변수
            int count = 0; // 지수값 변수
    
            for(int i = 2; i <= number; i++) { // 1은 소인수가 아니므로 i를 2부터 number까지 수로 지정한다.
                if(number / i == 1 && number % i == 0  ) { // 자기 자신으로 나눴을 때 값이 1이고, 나머지가 0이면 배열에 추가한다. ex) 7/7 = 1,  7%7 = 0 
                    numS.add(number); // 소인수 값을 어레이리스트에 추가
                    count ++; // 지수값 저장을 위해 1증가 시킨다.
                    numE.add(count); //numS의 지수값을 저장한다.
                    break;
                }
    
                else if(number % i != 0) { //0으로 나눠 떨어지지 않으면  다음으로 넘어 간다.
                    continue;
                }
    
                else // i가 2~ number보다 작은 값으로 나눠서 나머지가 0 일때 실행
                    numS.add(i); // 소인수 값을 어레이리스트에 추가
                    count ++; // 지수값 저장을 위해 1 증가 시킨다.
                    numE.add(count); //numS의 지수값을 저장한다.
                    result = number / i; // 다음 재귀함수 호출을 위한 매개변수 값을 계산한다.              
                    FractionalDecomposition(result); 
                    break; // 재귀를 호출한 후, 값이 필요 없으므로 종료 시킨다.
    
            }
    
       }
    
        public void Normalization() { //지수를 조정하는 메소드 ex) 2 * 2 * 5  를  2 ^ 2 x 5 ^ 1으로 변경 해준다.
    
            for(int i = 0; i < numS.size()-1; i++) {    // i = 0 부터 어레이 리스트 사이즈 -1 까지 반복      
                if(numS.get(i)!=numS.get(i+1)) // 값이 다르면 뛰어 넘는다
                    continue;
    
                else if(numS.get(i) == numS.get(i+1)) { // i번째 요소와 i+1 요소의 값이 같으면 ex) 값 : 2, 2, 5 / 지수 :  1, 1, 1
                    numS.remove(i+1); // i + 1번째 값을 지우고 ex) 값 : 2, 5 / 지수 : 1, 1, 1
                    numE.remove(i+1); // i + 1번째 값의 지수 값을 지운다 ex) 값 : 2, 5 / 지수 : 1, 1
                    numE.set(i, numE.get(i)+1); // 그리고 i 번째 값의 지수 값을 증가 시킨다. ex) 값 : 2, 5 / 지수 : 2,1
                    i--; // 그리고 값이 갱신되 었으므로 다시 i번째 값 부터 지수 조정을 위해 i 값을 감소시킨다.
    
                }
    
            }
    
        }
    
        public void Copy(ArrayList<Integer> num, ArrayList<Integer> num2) { //계산한 소인수의 값들을 복사, 초기화 메소드
    
            for(int i = 0; i < numS.size(); i++) { // 값을 복사한다.
                num.add(i, numS.get(i));
                num2.add(i, numE.get(i));
            }
    
            for(int i = 0; i < numS.size(); i++) { // 두번째 정수 값의 연산을 위해 값을 초기화 한다.
                numS.remove(i);
                numE.remove(i);
                i--; // remove 사용시 인덱스가 자동 조정되므로 i 값을 감소시킨다.
            }
    
        }
    
        public void CompareCommon(ArrayList<Integer> num1, ArrayList<Integer> num1E, ArrayList<Integer> num2, ArrayList<Integer> num2E) { //최대공약수를 구하는 메소드.
            //매개변수는 첫번째 소인수 값, 첫번째 소인수값의 지수, 두번째 소인수 값, 두번째 소인수 값의 지수 순이다.
            int result = 1; //최대공약수 값을 저장할 변수
    
                for(int i = 0; i < num1.size(); i++) { // 2개의 어레이리스트를 비교하기 위한 2중 for문 
                    for(int j = 0; j < num2.size(); j++) { // 1개의 어레이리스트를 기준으로 나머지 1개의 어레이리스트를 계속적으로 비교하기 위한 for문
    
                        if(num1.get(i) == num2.get(j)) {  //2개의 소인수 값이 같은  경우
                           if(num1E.get(i) == num2E.get(j)) { //2개의 소인수의 지수값이 같은 경우
                               result = result * num1.get(i) * num1E.get(i); // 그대로 곱해 준다. 
                           }
    
                           else //소인수 값은 같은데 지수 값이 다른 경우
    
                               if(num1E.get(i)>num2E.get(j)) //num1의 지수값이 큰 경우, 작은지수인 num2의 지수값을 이용하여 곱해준다.
                                   result = result * num1.get(i) * num2E.get(j);
                               else
                                   result = result * num1.get(i) * num1E.get(i); //num2의 지수값이 큰경우, 작은 지수인 num1의 지수값을 이용하여 곱해준다.
                        }       
                    }
                }        
                if(result != 1)
                    System.out.println("두수의 최대 공약수는 : " + result);
                else
                    System.out.println(" 서로 공통된 최대 공약수가 없습니다. ");
        }
    
    
    
    
    
    
    
    package mathProgramming;
    import java.util.ArrayList;
    import java.util.Scanner;
    
    public class TheGreatestCommonDivisorExam {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner scan = new Scanner(System.in);
            int num1 = scan.nextInt();
            int num2 = scan.nextInt();
    
            ArrayList<Integer> numR = new ArrayList<>(); //첫번째로 입력한 값의 소인수를 저장
            ArrayList<Integer> numRE = new ArrayList<>(); //첫번째로 입력한 값의 소인수의 지수를 저장
    
            ArrayList<Integer> numR2 = new ArrayList<>(); //두번째로 입력한 값의 소인수를 저장
            ArrayList<Integer> numRE2 = new ArrayList<>(); //두번째로 입력한 값의 소인수의 지수를 저장
    
            TheGreatestCommonDivisor ex = new TheGreatestCommonDivisor();
            ex.FractionalDecomposition(num1); //
            ex.Normalization(); 
            ex.Copy(numR, numRE);
    
            ex.FractionalDecomposition(num2);
            ex.Normalization(); 
            ex.Copy(numR2, numRE2);
    
            ex.CompareCommon(numR, numRE, numR2, numRE2);
    
        }
    
    }