문자열 관련 문제

WAS·2025년 12월 1일

백준알고리즘

목록 보기
4/4

✅ 문자 찾기

문자열 입력 : 객체.next()
문자 입력 : 객체.next().charAt(0)
공백 포함 문자열 입력 : 객체.nextLine()

문자 -> 문자배열로 변환
char[] 변수명 = 문자열값.toCharArray()

대소문자 구분 없이 라는 말이 나오면
문자열은 toUpperCase() 또는 toLowerCase() 로 통일시키고
문자는 Character.toUpperCase(문자값) 또는 Character.toLowerCase(문자값) 로 통일시킨다

💡 Character : 문자(특히 유니코드 관련) 작업을 도와주는 클래스

String 은 배열처럼 인덱스로 접근할 수 없다 ⮕ charAt(index) 로 접근해야함

아래에 나오는 코드는 for문 방식과 foreach 방식을 둘다 표현하였다

for(int i=0; i<str.length()-1; i++) {
		if(str.charAt(i) == t) {
			answer++;
		}
}

for(char x : str.toCharArray()){
	if(x=t) cnt++;
}

✅ 대소문자 변환

	public String solution(String str) {
		String answer = "";
		
		char[] charArray = str.toCharArray(); // 문자열을 문자배열로 변환
		for(char s : charArray) {
			if(Character.isLowerCase(s)) { // 소문자이면
				answer += Character.toUpperCase(s);
			}else {  // 대문자이면 
				answer += Character.toLowerCase(s);
			}
		}		
		return answer;
	}

대문자와 소문자는 숫자값으로 표현할 수 있으며, 같은 대소문자 차이는 32 크기가 차이난다


✅ 문장 속 단어
한 개의 문장이 주어지면 그 문장 속에서 가장 긴 단어를 출력하는 프로그램
입력 : it is time to study 출력 : study

public String solution(String str) {
		String answer = "";
		int m = Integer.MIN_VALUE; // int) 변수가 가질 수 있는 가장 작은 값
		String[] split = str.split(" ");
		for(String x : split) {
			if(m < x.length()) {
				m = x.length();
				answer = x;
			}
		}
		return answer;
	}

✅ 알파벳 뒤집기
N개의 단어가 주어지면 각 단어를 뒤집어 출력하는 프로그램

입력 : 
3
good
Time
Big

출력 :
doog
emiT
giB
public ArrayList<String> solution(int n, String str[]) {

    ArrayList<String> answer = new ArrayList<>();

    for(String x : str) { // 문자열은 불변이라 문자열 내부의 순서를 바꿀수 없음
        char[] charArray = x.toCharArray(); // 문자열을 -> 문자 배열로 변환
        int lt = 0;
        int rt = charArray.length-1;
        char tmp; // 문자 자리를 바꾸기 위해서 생성

        while(lt < rt) { // 짝수, 홀수개일경우 다 성립
            tmp = charArray[lt];
            charArray[lt] = charArray[rt];
            charArray[rt] = tmp;
            lt++;
            rt--;
        }

        String value = String.valueOf(charArray); // 다시 문자열로 변환
        answer.add(value);
    }
	return answer;
}

// main
int n = in.nextInt();
String str[] = new String[n];
for(int i=0; i<n; i++) {
	str[i] = in.next(); // 문자 배열개수 만큼 입력
}
	    
for(String x : T.solution(n, str)){
	System.out.println(x);
}

✅ 특정 문자 뒤집기
영어 알파벳과 특수문자로 구성된 문자열이 주어지면 영어 알파벳만 뒤집고,
특수문자는 자기 자리에 그대로 있는 문자열을 만들어 출력하는 프로그램
입력 : a#b!GE*T@S 출력 : S#T!EG*b@a

public String solution(String str) {

	String answer = "";
		
	char[] charArray = str.toCharArray();
			
	int lt = 0;
	int rt = charArray.length - 1;
	char tmp;

	while (lt < rt) {
			
		if(!Character.isAlphabetic(charArray[lt])) lt++; // 왼쪽에서부터 오는 문자가 알파벳이 아니면 
		else if(!Character.isAlphabetic(charArray[rt])) rt--; // 오른쪽에서부터 ~~ 알파벳이 아니면
		else { // 왼쪽 오른쪽 둘다 알파벳이면
			tmp = charArray[lt];
			charArray[lt]  = charArray[rt];
			charArray[rt] = tmp;
			lt++;
			rt--;
		}
	}
	answer = String.valueOf(charArray); // 문자배열 상태를 문자열로 변환
	return answer;
}

✅ 중복문자 제거
소문자로 된 한개의 문자열이 입력되면 중복된 문자를 제거하고 출력하는 프로그램
입력 : ksekkset 출력 : kset

3번째 인덱스에 있는 k 값을 보면
i = 3일 때 str.indexOf(str.charAt(3))str.indexOf(str.charAt(k)) 는 0 이 된다
즉 앞에 이미 k가 있기때문에 i값과 indexOf 값이 일치하지 않으면 값이 이미 중복된다는 소리이다
그래서 i값과 indexOf 값이 일치하는 문자만 따로 빼서 저장해야한다

public String solution(String str) {

	String answer = "";
	char[] charArray = str.toCharArray();
		
	for(int i=0; i<str.length(); i++) { 
		if(i == str.indexOf(str.charAt(i))) { 
			answer += str.charAt(i);
		}
	}
	return answer;
}

✅ 회문문자열
앞에서 읽을 때나 뒤에서 읽을 때나 같은 문자열을 회문 문자열이라 함
해당 문자열이 회문 문자열이면 "YES", 회문 문자열이 아니면 “NO"를 출력하는 프로그램
단 회문을 검사할 때 대소문자를 구분 X

// 첫번째 방법
public String solution(String str) {
	String answer = "YES";
	int lt = 0;
	int rt = str.length()-1;
		
	str = str.toLowerCase(); // 대소문자를 구분하지 않아야하므로 다 소문자로 변환
	char[] charArray = str.toCharArray(); // 문자열을 순회하기위해 문자배열로 변환
		
	while(lt < rt) { // 문자열개수가 짝수개든 홀수개든 다 성립
		if(charArray[lt] != charArray[rt]) { // 양쪽의 문자를 비교해서 한번이라도 같지않은 순간
		 	answer = "NO";  // 순회문자열이 아니므로 NO로 바꾼 후 반복문 탈출
			break;
		}
		lt++;
		rt--;
	}
	return answer;
}

// 두번째 방법
public String solution(String str) {

	String answer = "YES";
    // StringBuilder 클래스로 문자열을 변형시켜서 뒤집은 후 문자열로 형태로 바꿔주기
	String tmpString = new StringBuilder(str).reverse().toString(); 
		
     // 뒤집은 문자열과 원본 문자열이 동일하면 순회문자!
	if(!str.equalsIgnoreCase(tmpString)) {  // equalsIgnoreCase : 대소문자 구분없이 비교할 떄 많이 사용
		answer = "NO";
	}
	return answer;
}

✅ 팰린드롬
회문문자열과 동일한 방식인 문자열을 팰린드롬이라고 한다 (앞, 뒤에서 읽을 때 같은 문자열)
문자열이 입력되면 해당 문자열이 팰린드롬이면 "YES", 아니면 “NO"를 출력하는 프로그램
단 회문을 검사할 때 알파벳 이외의 문자들의 무시하고, 대소문자를 구분하지 않음

💡 정규표현식은 replaceAll 로 가능하며 replace 로는 불가능

public String solution(String str) {

	String answer = "YES";
		
    // A-Za-z : 영어 대문자 A~Z, 소문자 a~z
	// ^ : not(부정) 을 의미
    str = str.replaceAll("[^A-Za-z]",""); // 문자열이 대,소문자가 아닌 다른경우 다 공백으로 치환 
	str = str.toLowerCase(); // 대소문자만 남은 문자열을 다 소문자로 치환
	String reverseStr = new StringBuilder(str).reverse().toString();
		
	if(!str.equalsIgnoreCase(reverseStr)) {
		answer = "NO";
	}
	return answer;
}

✅ 숫자만 추출
문자와 숫자가 섞여있는 문자열이 주어지면 그 중 숫자만 추출하여 그 순서대로 자연수 만듬
만약 “tge0a1h205er”에서 숫자만 추출하면 0, 1, 2, 0, 5이고 이것을 자연수를 만들면 1205
하지만 0이 먼저나오면 생략해야함 ex) g0en2T0s8eSoft -> 208

// 첫번째 방법
public int solution(String str) {
	String replaceStr = str.replaceAll("[^0-9]", ""); // 숫자이외의 문자들은 다 공백으로 치환 
		
	int result = Integer.parseInt(replaceStr); // 문자열을 기본형 정수로 변환 (자동으로 앞자리 0 생략)
	return result;
}

// 두번째 방법
public int solution(String str) {
	String answer = "";
	for(char s : str.toCharArray()) { // 문자열 조작을 위해 문자배열로 변환 후 문자 하나씩 조작
		if(Character.isDigit(s)) answer += s;   // 문자가 숫자형태이면 문자열객체에 더해줌
	}
	return Integer.parseInt(answer); // 문자열을 정수형태로 변환
}

✅ 가장 짧은 문자거리
한 개의 문자열 s와 문자 t가 주어지면 문자열 s의 각 문자가 문자 t와 떨어진 최소거리를 출력

public int[] solution(String str, char c) {
		
	int answer[] = new int[str.length()]; // 정수배열 생성
	int s = 1000; // 초기값은 “문자열 길이보다 충분히 큰 값”이어야 한다
	for(int i=0; i<str.length(); i++) { // 왼쪽에서부터 비교
		if(str.charAt(i) == c) {
			s = 0;
			   answer[i] = s;
		}else {
			s++;
			answer[i] = s;
		}
	}
		 
	s = 1000; // 초기값은 “문자열 길이보다 충분히 큰 값”이어야 한다
	for(int j= str.length()-1; j>=0; j--) { // 오른쪽에서 부터 비교
					
		if(str.charAt(j) == c) s = 0;  // 이미 0이므로 또 넣을필요 x
		else {
			s++;
			answer[j] = Math.min(answer[j], s);  // 정수 두개중 더작은값 뽑기
		} 
	}
		 
	return answer;
}

💡 이 문제의 핵심은 첫 값을 크게 잡는것과 왼쪽에서 끝까지 순환했다가
오른쪽에서 처음으로 순환하는것이 포인트


✅ 문자열 압축

	public String solution(String str) {
		
		String answer = "";
		int sum = 1;
		for(int i=0; i<str.length(); i++) {
			
			if(i == str.length()-1) { // 마지막문자일경우 그 문자를 붙이고 현재 sum값에 따라 붙여줌
				answer = answer + str.charAt(i); 
				if(sum > 1) { // 마지막문자에 현재 누적된 sum값이 1이상일때만 붙여줌
					answer = answer + sum;
				}
				break;
			}
			
			if(str.charAt(i) == str.charAt(i+1)) { // 다음문자와 동일한 문자이면
				sum += 1; // sum값 누적
			}else {
				if(sum == 1) { // 동일한 문자가 아닌데, 현재 누적된 sum값이 1이면 
					answer = answer + str.charAt(i); // 문자만 붙이기
					sum = 1;
					continue; // 다시 for문으로 이동
				}
				
				answer = answer + str.charAt(i) + sum;  // sum이 2이상이면 sum값도 붙여주기
				sum = 1;
			}
		}
		return answer;
	}

✅ 암호

	public String solution(int n,String str) {
		
		String answer = "";
		
        // 7개씩추출 + #은 1로, *은 0으로 치환
		for(int i=0; i<n; i++) {
			String tmp = str.substring(0,7).replace("#", "1").replace("*", "0"); 
			
			int num = Integer.parseInt(tmp,2); // 2진수 문자열값을 10진수로 변환
			
 			answer = answer + (char)num; // 정수를 문자형태로 변환하면 아스키코드로변환
			str = str.substring(7); // 뽑아온 문자열부터 다시 시작
			
		}
profile
우측 상단 햇님모양 클릭하셔서 무조건 야간모드로 봐주세요!!

0개의 댓글