String

중복문자제거 (1-6)

  • 설명 : 소문자로 된 한개의 문자열이 입력되면 중복된 문자를 제거하고 출력하는 프로그램을 작성하세요. 중복이 제거된 문자열의 각 문자는 원래 문자열의 순서를 유지합니다.

  • 입력 : 첫 줄에 문자열이 입력됩니다. 문자열의 길이는 100을 넘지 않는다.

  • 출력 : 첫 줄에 중복문자가 제거된 문자열을 출력합니다.

  • 작성답안

import java.util.Scanner;
  
public class Main {
  public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        String str = scan.next();

        System.out.println(t.solution(str));
    }

    public String solution(String word){
        char[] ch = word.toCharArray();
        String result = String.valueOf(ch[0]);
        
        for (int i=1; i<ch.length; i++){
            int num = 0;
            for (int j=0; j<i; j++){
                if(ch[i]==ch[j]){
                    num = 1;
                }
            }
            if(num==0){
                result += ch[i];
            }
        }
        return String.valueOf(result);
    }
}
  • 풀이 답안
import java.util.Scanner;
  
public class Main {
  public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        String str = scan.next();

        System.out.println(t.solution(str));
    }

    public String solution(String str){

        char[] ch = str.toCharArray();
        String result = "";

        for(int i=0; i<ch.length; i++){
            if(i==str.indexOf(ch[i])){
                result += ch[i];
            }
        }

        return result;
    }
}
  • 특징
    1. 나의 풀이의 경우 이중 루프를 돌면서 중복 문자가 있는지 체크하고, 해당 단어의 반복이 끝난 후 중복여부가 바뀌지 않은 값만 추가하도록 하였는데
    2. ‘문자열.indexOf(ch[i])’를 이용해서 해당 문자가 가장 처음 나온 값을 추출하고, 해당 순서가 실제 i일때만 추가하도록 하는편이 훨씬 간편함

회문 문자열 (1-7)

  • 설명 : 앞에서 읽을 때나 뒤에서 읽을 때나 같은 문자열을 회문 문자열이라고 합니다. 문자열이 입력되면 해당 문자열이 회문 문자열이면 “YES”, 회문 문자열이 아니면 “NO”를 출력하는 프로그램을 작성하세요. 단 회문을 검사할 때 대소문자를 구분하지 않습니다.

  • 입력 : 첫 줄에 길이 100을 넘지 않는 공백이 없는 문자열이 주어집니다.

  • 출력 : 첫 번째 줄에 회문 문자열인지의 결과를 YES 또는 NO로 출력합니다.

  • 작성 답안

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        String str = scan.next().toUpperCase();

        System.out.println(t.solution(str));
    }

    public String solution(String word){
        char[] ch = word.toCharArray();
        int lt=0, rt=word.length()-1;
        String result = "YES";

        while (lt<rt){
            if(!(ch[lt]==ch[rt])){
                result = "NO";
                break;
            }
            lt++;
            rt--;
        }
        return result;
    }
}
  • 풀이 답안-1
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        String str = scan.next().toUpperCase();

        System.out.println(t.solution(str));
    }

    public String solution(String word){
        String result = "YES";
        char[] ch = word.toCharArray();

        for(int i=0; i<word.length()/2; i++){
            if(word.charAt(i) != word.charAt((ch.length-1)-i)) {
                result = "NO";
                break;
            }
        }
        return result;
    }
}
  • 풀이답안 -2
import java.util.Scanner;
  
public class Main {
  public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        String str = scan.next();

        System.out.println(t.solution(str));
    }

    public String solution(String word){
        String result = "YES";
        String rv = new StringBuilder(word).reverse().toString();
        if(!word.equalsIgnoreCase(rv)) result="NO";
        return result;
    }
}
  • 특징
    1. 풀이1은 유사한 방식이나 수동으로 lt,rt를 지정하지 않고 idx값으로 계산해서 짧게 풀이. 대소문자는 toUpperCase를 이용해 통일시킴.
    2. 풀이2는 StringBuilder의 reverse() 메소드를 이용해 문자열을 뒤집은 후, equalsIgnoreCase를 사용해서 대소문자 관계없이 일치하는지 확인

유효한 팰린드롬 (1-8)

  • 설명 : 앞에서 읽을 때나 뒤에서 읽을 때나 같은 문자열을 팰린드롬이라고 합니다. 문자열이 입력되면 해당 문자열이 팰린드롬이면 “YES”, 아니면 “NO”를 출력하는 프로그램을 작성하세요. 단 회문을 검사할 때 알파벳만 가지고 회문을 검사하며, 대소문자를 구분하지 않습니다. 알파벳 이외의 문자들의 무시합니다.

  • 입력 : 첫 줄에 길이 100을 넘지 않는 공백이 없는 문자열이 주어집니다.

  • 출력 : 첫 번째 줄에 팰린드롬인지의 결과를 YES 또는 NO로 출력합니다.

  • 작성 답안

import java.util.Scanner;
import java.util.ArrayList;
  
public class Main {
  public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        String str = scan.nextLine();

        System.out.println(t.solution(str));
    }

    public String solution(String word){
        char[] ch = word.toCharArray();
        ArrayList str = new ArrayList<>();
        for (char c : ch){
            if(Character.isAlphabetic(c)){
                str.add(Character.toLowerCase(c));
            }
        }

        int lt=0, rt=str.size()-1;
        String result = "YES";
        while(lt<rt){
            if (!str.get(lt).equals(str.get(rt))){
                result = "NO";
                break;
            }
            lt++;
            rt--;
        }
        return result;
    }
}
  • 풀이 답안
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        String str = scan.nextLine();

        System.out.println(t.solution(str));
    }

    public String solution(String word){
        String result = "NO";

        String str = word.toUpperCase().replaceAll("[^A-Z]", "");

        String rv = new StringBuilder(str).reverse().toString();
        if(str.equalsIgnoreCase(rv)){
            result="YES";
        }
        return result;
    }
}
  • 특징
    1. replaceAll에서는 정규식을 사용할 수 있음.
    2. toUpperCase()을 사용하여 모두 대문자로 바꿔놓은다음 “^A-Z” 식을 사용해서 A~Z 사이가 아니라면 지움

숫자만 추출 (1-9)

  • 설명 : 문자와 숫자가 섞여있는 문자열이 주어지면 그 중 숫자만 추출하여 그 순서대로 자연수를 만듭니다. 만약 “tge0a1h205er”에서 숫자만 추출하면 0, 1, 2, 0, 5이고 이것을 자연수를 만들면 1205이 됩니다. 추출하여 만들어지는 자연수는 100,000,000을 넘지 않습니다.

  • 입력 : 첫 줄에 숫자가 섞인 문자열이 주어집니다. 문자열의 길이는 100을 넘지 않습니다.

  • 출력 : 첫 줄에 자연수를 출력합니다.

  • 작성 답안 -1

import java.util.Scanner;
  
public class Main {
  public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        String str = scan.next();

        System.out.println(t.solution(str));
    }

    public int solution(String word){
        char[] ch = word.toCharArray();
        String result = "";
        for(int i=0; i<ch.length; i++){
            if(Character.isDigit(ch[i])){
                result += ch[i];
            }
        }
        return Integer.parseInt(result);
    }
}
  • 작성답안-2
import java.util.Scanner;
  
public class Main {
  public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        String str = scan.next();

        System.out.println(t.solution(str));
    }

    public int solution(String word){
        char[] ch = word.toCharArray();
        String result = "";
        for(int i=0; i<ch.length; i++){
            if(Character.isDigit(ch[i])){
                result += ch[i];
            }
        }
        return Integer.parseInt(result);
    }
}
  • 특징
    1. Character.isDigit(char형) 을 사용하여 전체배열에서 숫자만 추출하는 방식으로 풀이함
    2. 앞서 배운 replaceAll 정규식을 사용하여 숫자가 아닌 항목들을 모두 지움

가장 짧은 문자거리 (1-10)

  • 설명 : 한 개의 문자열 s와 문자 t가 주어지면 문자열 s의 각 문자가 문자 t와 떨어진 최소거리를 출력하는 프로그램을 작성하세요.

  • 입력 : 첫 번째 줄에 문자열 s와 문자 t가 주어진다. 문자열과 문자는 소문자로만 주어집니다. 문자열의 길이는 100을 넘지 않는다.

  • 출력 : 첫 번째 줄에 각 문자열 s의 각 문자가 문자 t와 떨어진 거리를 순서대로 출력한다.

  • 작성 답안

import java.util.ArrayList;
import java.util.Scanner;
  
public class Main {
  public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        String str = scan.next();
        char ch = scan.next().charAt(0);

        int[] result = t.solution(str, ch);
        for (int i : result) {
            System.out.print(i+" ");
        }
    }

    public int[] solution(String word, char ch){
        
        int[] result = new int[word.length()];
        char[] _ch = word.toCharArray();
        ArrayList<Integer> state = new ArrayList<>();
        
        for(int i=0; i<word.length(); i++){
            if(_ch[i]==ch){
                state.add(i);
            }
        }

        for(int i=0; i<word.length(); i++){
            for (Integer integer : state) {
                if(_ch[i]!=ch && (result[i]==0 || result[i]>Math.abs(i-integer))){
                    result[i] = Math.abs(i-integer);
                }
            }
        }
        return result;
    }
}
  • 풀이 답안
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        String str = scan.next();
        char ch = scan.next().charAt(0);

        int[] result = t.solution(str, ch);
        for (int i : result) {
            System.out.print(i+" ");
        }
    }

    public int[] solution(String word, char ch){

        int[] result = new int[word.length()];
        char[] _ch = word.toCharArray();

        int len = 1000;
        for(int i=0; i<word.length(); i++){
            if(_ch[i]==ch){
                len = 0;
                result[i] = len;
            } else {
                result[i] = len;
            }
            len++;
        }

        len = 10000;
        for(int i=word.length()-1; i>=0; i--){
            if(_ch[i]==ch){
                len = 0;
            } else if (result[i]>len){
                result[i] = len;
            }
            len++;
        }
        return result;
    }
}
  • 특징
    1. 나의 풀이의 경우 ch의 idx를 먼저 구하고, 이중 루프를 통해 해당 idx와 현재 idx의 차이를 바로 대입하였음. Math.abs(i-integer)를 통해 절대값을 적용하고, 조건문에 현재 절대값과 이미 적용된 값을 비교해 더 작을때만 반영되도록 함
    2. 배열 하나를 양방향으로 읽는 방식으로 해, 앞전보다 작은 값일때만 반영되게 함
    3. 최초에는 임의의값 1000을 적용하고 대응할 ch를 만났을때 0으로 리셋, 그 이후로는 한칸 이동시 ++ 하는 방식

문자열 압축 (1-11)

  • 설명 : 알파벳 대문자로 이루어진 문자열을 입력받아 같은 문자가 연속으로 반복되는 경우 반복되는 문자 바로 오른쪽에 반복 횟수를 표기하는 방법으로 문자열을 압축하는 프로그램을 작성하시오. 단 반복횟수가 1인 경우 생략합니다.

  • 입력 : 첫 줄에 문자열이 주어진다. 문자열의 길이는 100을 넘지 않는다.

  • 출력 : 첫 줄에 압축된 문자열을 출력한다.

  • 작성 답안

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        String str = scan.next();

        System.out.print(t.solution(str));
    }

    public String solution(String word){

        String result = String.valueOf(word.charAt(0));
        int cnt = 1;

        for(int i=1; i<word.length(); i++){
            if(word.charAt(i-1)!=word.charAt(i)){
                if(cnt!=1){
                    result += cnt;
                }
                result += word.charAt(i);
                cnt = 1;
            } else {
                cnt++;
            }
        }
        if(cnt!=1){
            result += cnt;
        }
        return result;
    }
}
  • 특징
    • 현재의 문자열을 대입하고, 앞선 문자열과 달라졌을때 cnt 수가 증가되어있는 상태라면 현재의 문자열을 대입하기 전 cnt숫자도 반환값에 대입해줌 (풀이도 비슷한 방식이라 추가하지 않음)

암호 (1-12)

  • 설명 : 현수는 영희에게 알파벳 대문자로 구성된 비밀편지를 매일 컴퓨터를 이용해 보냅니다. 비밀편지는 현수와 영희가 서로 약속한 암호로 구성되어 있습니다. 비밀편지는 알파벳 한 문자마다 # 또는 *이 일곱 개로 구성되어 있습니다. 만약 현수가 “#*****#”으로 구성된 문자를 보냈다면 영희는 현수와 약속한 규칙대로 다음과 같이 해석합니다.
    1. “#*****#”를 일곱자리의 이진수로 바꿉니다. #은 이진수의 1로, *이진수의 0으로 변환합니다. 결과는 “1000001”로 변환됩니다.
    2. 바뀐 2진수를 10진수화 합니다. “1000001”을 10진수화 하면 65가 됩니다.
    3. 아스키 번호가 65문자로 변환합니다. 즉 아스크번호 65는 대문자 ‘A’입니다. 참고로 대문자들의 아스키 번호는 ‘A’는 65번, ‘B’는 66번, ’C’는 67번 등 차례대로 1씩 증가하여 ‘Z’는 90번입니다. 현수가 4개의 문자를 다음과 같이 신호로 보냈다면 #**###**#####**#####**##** 이 신호를 4개의 문자신호로 구분하면

#****## –> ‘C’

#**#### –> ‘O’

#**#### –> ‘O’

#**##** –> ‘L’

최종적으로 “COOL”로 해석됩니다. 현수가 보낸 신호를 해석해주는 프로그램을 작성해서 영희를 도와주세요.

  • 입력 : 첫 줄에는 보낸 문자의 개수(10을 넘지 안습니다)가 입력된다. 다음 줄에는 문자의 개수의 일곱 배 만큼의 #또는 * 신호가 입력됩니다. 현수는 항상 대문자로 해석할 수 있는 신호를 보낸다고 가정합니다.

  • 출력 : 영희가 해석한 문자열을 출력합니다

  • 작성 답안

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        Integer num = scan.nextInt();
        String str = scan.next();

        System.out.print(t.solution(str, num));
    }

    public String solution(String str, int num){

        char[] word = str.toCharArray();
        String[] nums = new String[num];
        String result = "";

        for(int i=0; i<str.length(); i++){
            if(i%7==0){
                if(word[i]=='#') nums[i/7] = "1" ;
                else if(word[i]=='*') nums[i/7] = "0" ;
            } else {
                if(word[i]=='#') nums[i/7] += "1" ;
                else if(word[i]=='*') nums[i/7] += "0" ;
            }
        }

        for (String s : nums) {
            char r = (char) Integer.parseInt(s, 2);
            result += r;
        }
        return result;
    }
}
  • 풀이 답안
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Main t = new Main();
        Scanner scan = new Scanner(System.in);
        Integer num = scan.nextInt();
        String str = scan.next();

        System.out.print(t.solution(str, num));
    }

    public String solution(String str, int num){

        String result = "";

        for(int i=0; i<num; i++){
           String tmp = str.substring(0,7).replace('#','1').replace('*', '0');
            str = str.substring(7);
            int n = Integer.parseInt(tmp, 2);
            result += (char) n;
        }
        return result;
    }
}
  • 특징
    1. 내 풀이의 경우 7로 나누는 작업과 조건문을 통해 일일히 비교후 변경하는 하드 코딩을 진행하고, 그 후 다시 반복을 통해 각 숫자들을 10진수로 변경해 단어로 바꾸는 작업을 진행함
    2. 풀이에서는 substring을 통해 원하는 범위만큼을 잘라내고, 기존 문자열을 다시 한번 substring으로 잘라 이후범위부터 작업할수 있도록 함
    3. 문자열 변경 역시 replace함수를 통해 한번에 진행함
    4. 또 10진수 변경과, 반환 문자열 대입까지 반복문 한번에 모두 진행할수 있게 함

Updated: