코딩과 결혼합니다

230620 - 알고리즘 문제를 풀며 본문

2세/기타

230620 - 알고리즘 문제를 풀며

코딩러버 2023. 6. 20. 22:55
728x90

배운것 / 느낀것 

toString()과 String.valueOf()는 Object 값을 String 형으로 변환할 때 주로 사용하는 메소드이다.

두 메소드는 String의 형태로 값을 변환해주는 비슷한 점이 있지만, 변경하고자 하는 값이 null이라면 차이가 있다.

두 메소드의 차이점은 바로 null값에 따른 NullPointerException의 발생 유무이다.

넘어오는 Object의 값이 null 일 때 toString() 과 String.valueOf()의 비교

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

 

toString()과 String.valueOf()

  1. contains(): 이 메서드는 주어진 문자열이 다른 문자열에 포함되어 있는지를 확인합니다. 따라서 대소문자를 구분하지 않고, 문자열 내에 특정 문자 또는 문자열이 포함되어 있는지 여부만을 판단합니다. 예를 들어, "apple".contains("p")는 true를 반환합니다.
  2. equals(): 이 메서드는 주어진 문자열과 다른 문자열이 완전히 일치하는지를 확인합니다. 대소문자를 구분하며, 문자열 전체가 일치해야 true를 반환합니다. 예를 들어, "apple".equals("Apple")는 false를 반환합니다.

 

Math.pow(밑, 지수) = 밑^지수

거듭제곱을 구할 때 쓸 수 있는 함수이다. Math 클래스는 정적이므로 import나 객체의 생성 없이 사용 가능하다. 

 

 

문자열 내 P와 Y의 개수

 

풀이

더보기

public static void main(String[] args) {
       String s = "ppppyy";
       String[] sChar = new String[s.length()];
       int pCount = 0;
       int yCount = 0;
       boolean answer;

       for (int i = 0; i <s.length() ; i++) { 
                  sChar[i] = String.valueOf(s.charAt(i));
                  if(sChar[i].contains("p") || sChar[i].contains("P")){ 
                        pCount++;
                  } else if (sChar[i].contains("y") || sChar[i].contains("Y")){
                        yCount++;
                 }
       }
       answer = pCount == yCount;

       System.out.println(answer);
}

sChar[i] =String.valueOf(s.charAt(i));  :  문자열에서 특정 인덱스의 문자를 추출하여 새로운 문자열로 변환하는 역할

다음 sChar가 "p"나 "P"를 포함하면 pCount++;

다음 sChar가 "y"나 "Y"를 포함하면 pCount++;

그리고 그 둘의 count가 같으면 true를 반환한다.

 

**s.length() 이거는 length라는 함수를 또 불러오게 되므로 효율적이지 않다고 한다. 변수 int a = s.length; 를 선언하여 'a'를 집어넣어 주는게 좋다고 한다!

**contains 보다 equlse()를 쓰는걸 권장 하셨다.

주어진 코드에서 sChar[i]은 단일 문자이므로, contains() 대신 equals()를 사용하는 것이 더 적절하다.

해당 코드는 'p' 또는 'P'가 하나의 문자로 포함되는지 확인하는 것이 목적이기 때문에 equals()를 사용하면 대소문자를 구분하여 정확히 일치하는지 확인할 수 있다.

class Solution {
    boolean solution(String s) {
        boolean answer = true;
        int p=0;
        int y=0;
        for(int i = 0; i < s.length(); i++){
            if("p".equals(s.substring(i,i+1))||"P".equals(s.substring(i,i+1)))  p++;

            if("y".equals(s.substring(i,i+1))||"Y".equals(s.substring(i,i+1)))  y++;

        }
        // [실행] 버튼을 누르면 출력 값을 볼 수 있습니다.
        System.out.println("Hello Java");

        return p == y ? true: false;
    }
}
더보기

 

다른 풀이 방법

boolean solution3(String s) {
        boolean answer = true;
        s = s.toUpperCase(); //대문자
        s.toLowerCase(); // 소문자
        //s 길이 - TTLL
        int p = s.length() - (s.replaceAll("P", "").length());
        int y = s.length() - (s.replaceAll("Y", "").length());
        if(p != y){
              answer = false;
        }
        return answer;
        }
}

먼저 s안의 알파벳을 모두 대문자 or 소문자로 바꾸어 주고

int p에 s의 길이 - (p를 공백으로 바꾸어 없앤 나머지 y의 개수)  //(6-2)=4

int y에 s의 길이 - (y를 공백으로 바꾸어 없앤 나머지 p의 개수)   //(6-4)=2

 

다음 p가 y와 같지 않을때는 flase를 해준다.

 

 

 

정수 제곱근 판별법

 

풀이

더보기
public class q25 {
        public static void main(String[] args) {
               long n = 4;
               long answer = -1;

               //n의 제곱근인 x라는 변수를 만들어줌
               long x = (long)Math.pow(n,0.5);

               //x를 두 번 곱해서 n이 나오면 if문 안을 수행
               if (x*x ==n){
                    answer = (x+1)*(x+1);
               }
        }
}

실패한 풀이

class Solution {
     public long solution(long n) {
            long answer = -1;

            for (int i = 0; i <= Math.pow(n, 0.5); i++) {
                if (n == i*i){
                    answer = (i+1)*(i+1);
                }
           }

          return answer;
      }
}

이거는 런타임이 길어져서 정확성: 61.1 이 나왔다. 어떻게 하면 런타임을 줄일 수 있을까? 고민하다가 for문 없이 구현할 방법을 생각해 낸게 위의 풀이이다.

 

콜라츠 추측

 

풀이

더보기
public class q27 {
      public static void main(String[] args) {
             int num = 626331;
             int answer = 0;

             while (answer != 500) {
                  if (num != 1) {
                          if (num % 2 == 0) {
                               num = num / 2;
                               ++answer;
                          } else {
                               num = num * 3 + 1;
                               ++answer;
                          }
                  } else {
                         break;
                  }
            }
           if (answer >= 500){
               answer = -1;
           }
           System.out.println(answer);
      }
}

lnt num을 long타입으로 바꿔주지 않아서 오버플로우가 걸린 케이스. long num으로 바꿔주니 통과하였다.

조건이 '작업을 500번 반복할 때까지 1이 되지 않는다면 –1을 반환해 주세요.' 였기 때문에

1. answer가 500이 아닐 때 콜라츠의 추측대로 연산을 해주며 answer를 하나씩 더해주었다.

2. 다음 num이 1이 되면 몇 번을 시도했는지 결과값을 보여줄 수 있도록 break를 걸어주었다.

3. answer가 500이상이 되면 answer는 -1