JavaRush /Java Blog /Random-KO /Java의 역방향 문자열: 다양한 방법으로 문자열 역방향 학습

Java의 역방향 문자열: 다양한 방법으로 문자열 역방향 학습

Random-KO 그룹에 게시되었습니다
알고리즘을 몰라도 좋은 프로그래머가 될 수 있나요? 매우 논란의 여지가 있습니다. 예, 우리 아웃소싱 회사에서 일자리를 찾을 수 있습니다. 인터뷰 중에 주로 기술에 관한 질문을 하기 때문입니다. Java의 문자열 역방향: 다양한 방법으로 문자열 역방향 학습 - 1하지만 당신의 결정이 목발로 가득 차 있다면 당신은 훌륭한 전문가가 될 수 있을까요? 좀 더 진지한 외국 회사로 이직하고 싶다면 주로 알고리즘에 초점을 맞춘 인터뷰를 만나게 될 것입니다. 어떤 식으로든 가장 기본적인 알고리즘을 채택하는 것은 가치가 있습니다. 왜냐하면 알고리즘은 프로그래머의 친구이기 때문입니다 . 오늘 우리는 이러한 주제 중 하나를 다루고 문자열을 뒤집는 방법에 대해 논의할 것입니다. 여기에서는 모든 것이 간단합니다. 문자열을 뒤집는 것은 문자열을 거꾸로 가져오는 것입니다. 예를 들면 다음과 같습니다. JavaRush Forever ->reverof hsuRavaJ 그렇다면 Java에서 문자열을 어떻게 반전시킬 수 있습니까?

1. 스트링빌더/스트링버퍼

가장 일반적이고 간단한 방법은 StringBuilder/StringBuffer를 사용하는 것입니다 .
public static String reverseString(String str) {
  return new StringBuilder(str).reverse().toString();
}
최고의 솔루션 = 가장 간단합니다. Java에서 문자열을 뒤집는 방법을 묻는다면 이것이 가장 먼저 염두에 두어야 할 사항입니다. 하지만 앞서 알고리즘에 대해 이야기했지요? 기본적으로 제공되지 않는 솔루션을 살펴보겠습니다.

2. 어레이 솔루션

public static String reverseString(String str) {
  char[] array = str.toCharArray();
  String result = "";
  for (int i = array.length - 1; i >= 0; i--) {
     result = result + array[i];
  }
  return result;
}
toCharArray 메소드를 사용하여 문자열을 배열로 변환합니다 . 이 배열의 끝부터 for 루프를 실행하여 결과 문자열에 문자를 추가해 보겠습니다.

3. charAt를 사용한 솔루션

public static String reverseString(String str) {
  String result = "";
  for (int i = 0; i < str.length(); i++) {
     result = str.charAt(i) + result;
  }
  return result;
}
이 경우에는 String 클래스 메서드 인 charAt를 사용하여 각 문자를 추출하기 때문에 문자열을 배열로 분할할 필요조차 없습니다 (for 루프는 역방향이므로 문자를 순차적으로 뒤로 가져올 수 있습니다).

4. 스택을 이용한 솔루션

Stack 클래스는 오랫동안 사용되지 않았으며 더 이상 사용되지 않는 것으로 간주되지만 참고로 이를 사용하는 솔루션을 살펴보는 것이 유용할 것입니다.
public static String reverseString(String str) {
  Stack<Character> stack = new Stack<>();
  String result = "";
  for (Character character : str.toCharArray()) {
     stack.add(character);
  }
  while (!stack.isEmpty()) {
     result = result + stack.pop();
  }
  return result;
}
여기서 다시 toCharArray를 사용하여 문자열을 배열로 분할하고 일반 유형인 Character를 사용하여 스택 에 모두 넣습니다 . 다음으로 스택 상단에서 요소를 가져오기 시작합니다. LIFO 구조 인 L ast I n First O ut( 선입 , 후출) 스택의 특성으로 인해 요소는 뒤로 가져오고 결과는 결과 행에 저장됩니다.

5. 재귀에 의한 해법

거의 모든 알고리즘 문제는 재귀를 사용하여 해결할 수 있습니다. 그리고 여기서도 그녀 없이는 할 수 없습니다. 아니면 그들 없이도. 결국 오늘 우리는 재귀를 해결하는 한 가지 방법이 아니라 여러 가지 방법을 고려할 것입니다.
  • 방법 1

    public static String reverseString(String str) {
      String rightStr;
      String leftStr;
      int length = str.length();
    
      if (length <= 1) {
         return str;
      }
    
      leftStr = str.substring(0, length / 2);
      rightStr = str.substring(length / 2, length);
    
      return reverseString(rightStr) + reverseString(leftStr);
    }

    rightStrleftStr 변수를 사용하여 들어오는 문자열을 두 개의 동일한 부분으로 분할합니다. 다음으로, 이 분할을 사용하여 문자열을 나눌 수 있는 가장 작은 부분(1자)으로 나눕니다. 그 후, 재귀가 무너지기 시작하고 문자를 반대 순서로 반환합니다(오른쪽에 있던 문자는 왼쪽에 배치되고 왼쪽에 있는 문자는 오른쪽에 배치되었습니다).

    각 재귀는 메소드에 대한 다중 호출이며 결과적으로 상당한 리소스 지출이라는 점을 잊어서는 안됩니다. 음, 도달할 수 없는 종료 조건이 있는 재귀에 대해 이야기하고 있다면 이것이 무한대 및 StackOverflowError로 가는 경로입니다.

  • 방법 2

    여기서는 index 메소드에 추가 인수가 필요합니다.

    이 메소드가 실행되면 문자열 길이는 -1로 지정됩니다.

    String str = "JavaRush forever";
    System.out.println(reverseString(str, str.length()-1));

    그리고 방법 자체는 다음과 같습니다.

    public static String reverseString(String str, int index) {
      if(index == 0){
         return str.charAt(0) + "";
      }
    
      char letter = str.charAt(index);
      return letter + reverseString(str, index-1);
    }

    색인은 지금 사용할 행 요소를 나타내는 지표 역할을 합니다(그리고 마지막 요소를 사용할 것입니다).

    따라서 인덱스가 첫 번째 요소에 도달하면 종료 조건을 설정합니다.

  • 이전 메소드 실행 결과에 문자 인덱스를 사용하여 얻은 값을 더하고 그 결과를 반환합니다.

  • 방법 3

    public static String reverseString(String str) {
      if (str.length() <= 1) {
         return str;
      }
      return reverseString(str.substring(1)) + str.charAt(0);
    }

    이 방법은 본질적으로 재귀적인 방법 중 가장 간단합니다. 그리고 우리가 기억하는 것처럼 단순 = 최고입니다.

    각 실행 중에 동일한 문자열을 지정하지만 첫 번째 요소는 없습니다. 종료 조건에 도달하면(한 문자가 남을 때) 재귀가 축소되기 시작하고 이전에 사용되지 않은 문자가 각 후속 결과에 추가됩니다.

6. XOR 사용

XOR 은 논리적 비트 단위 연산입니다. 두 변수의 경우 인수 중 하나가 true이고 다른 하나가 false인 경우에만 연산 결과가 true입니다.
와이
0 0 0
0 1 1
1 0 1
1 1 0
이 기사 에서 비트 연산에 대한 자세한 내용을 읽을 수 있습니다 . 다음 솔루션은 다음 사실에 의존합니다.

(A XOR B) XOR B = A
(A XOR B) XOR A = B
방법은 다음과 같습니다.
public static String reverseString(String str) {
  char[] arr = str.toCharArray();
  int low = 0;
  int high = arr.length - 1;
  String result = "";
  while (low < high) {
     arr[low] = (char) (arr[low] ^ arr[high]);
     arr[high] = (char) (arr[low] ^ arr[high]);
     arr[low] = (char) (arr[low] ^ arr[high]);
     low++;
     high--;
  }
  for (int i = 0; i < arr.length; i++) {
     result = result + arr[i];
  }
  return result;
}
여기서 무슨 일이 일어나고 있는지 알아 봅시다. 들어오는 문자열에서 배열을 만듭니다. 배열을 순회하기 위한 인덱스를 저장하는 두 개의 변수 lowhigh 를 만듭니다 . 따라서 처음부터 끝까지 이동합니다. 값은 0이고 두 번째는 끝에서 처음으로 arr.length - 1 로 설정합니다 . 인덱스 high 가 low 보다 큰 한 재생되는 루프에 들어갑니다 . 여기에서 배타적 OR 사용이라는 재미있는 일이 일어나기 시작합니다. 예를 들어 xy를 살펴보겠습니다 . arr[high] = 'x' ; 이진 코드는 1 1 1 1 0 0 0입니다. 이때 arr[high] = 'n'; 이진 코드 - 1 1 0 1 1 1 0 루프의 XOR 연산에서 얻을 수 있는 내용은 다음과 같습니다.
  1. arr[low] = (char) (arr[low] ^ arr[high]);

    
    arr[low] = 1 1 0 1 1 1 0
    arr[high] =1 1 1 1 0 0 0
    arr[low] = 0 0 1 0 1 1 0
  2. arr[높음] = (문자) (arr[낮음] ^ arr[높음]);

    
    arr[low] =  0 0 1 0 1 1 0
    arr[high] = 1 1 1 1 0 0 0
    arr[high] = 1 1 0 1 1 1 0
  3. arr[low] = (char) (arr[low] ^ arr[high]);

    
    arr[low] =  0 0 1 0 1 1 0
    arr[high] = 1 1 0 1 1 1 0
    arr[low] =  1 1 1 1 0 0 0
결과적으로 이러한 작업 덕분에 두 배열 셀의 값을 교환했습니다. arr[high] 는 arr[low] 가 처음부터 요소 수만큼 배열 끝부터 요소 수를 나타냅니다 . 그러므로 우리는 단순히 요소를 이러한 인덱스로 교환합니다. 예를 들어, "JavaRush Forever" 문장의 첫 번째 실행에서 Jr이 바뀌고, 두 번째 실행에서는 ae 등이 됩니다. 문자 수가 홀수인 경우 다음 요소에 도달하면 중간에 있으면 루프에서 제외됩니다(즉, 중간 요소를 변경할 필요가 없습니다). 짝수이면 모든 요소를 ​​처리한 후 버림받게 됩니다. 그 후에는 일반 루프로 들어가 배열 요소로부터 문자열을 만듭니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION