PS/Programmers

[프로그래머스] 2021 위클리 챌린지 4주차_ 문자열 파싱 substr, stringstream

kth990303 2021. 8. 25. 20:50
반응형

https://programmers.co.kr/learn/courses/30/lessons/84325

 

코딩테스트 연습 - 4주차

개발자가 사용하는 언어와 언어 선호도를 입력하면 그에 맞는 직업군을 추천해주는 알고리즘을 개발하려고 합니다. 아래 표는 5개 직업군 별로 많이 사용하는 5개 언어에 직업군 언어 점수를 부

programmers.co.kr

프로그래머스에서 진행되는 위클리 챌린지 문제를 풀어보았다.

문제 자체는 어렵지 않으나, 다른 사람의 코드를 보면서 배운 점이 있어서 포스팅해보려한다.

 

이번 문제는 문자열을 파싱하여 적절한 구현을 요구하는 문제였다.

table이나 languages 벡터의 길이가 최대 10이므로 시간복잡도를 걱정할 필요가 전혀 없는 문제이나,

문자열파싱에 조금 애먹을 수 있는 문제였다.

문자열파싱하는 방법에는 무엇이 있을까?

 

1. str.find(), str.substr()

대부분의 사람들이 흔히 알고 있는 방법이다.

str.find(' '); 와 같이 작성할 경우, 문자열 str 내에서 공백이 위치하는 처음 인덱스를 반환해준다.

만약 공백이 존재하지 않을 경우 -1을 반환한다.

주의할 점은, 공백이 여러 개 있더라도 반드시 처음 공백이 존재하는 위치의 인덱스만 반환한다는 점이다.

 

그렇다면 공백이나, 우리가 찾는 문자가 여러 개 있을 때에는 어떻게 해야 할까?

str.find(' ', idx); 와 같이 작성하면 idx번째 이후에 존재하는 ' '의 위치를 반환하므로 for문을 통해 idx를 갱신하여 적절하게 처리하면 모든 공백의 인덱스를 반환하게 할 수 있다.

 

이후, str.substr(idx, length); 를 통해 문자열 str의 idx번째부터 길이 length에 해당하는 만큼의 문자열을 얻음으로써 파싱할 수 있다.

 

#include <iostream>
#include <string>
using namespace std;

int main() {
	string s="Hello C++ Programming Coder! Nice To Meet You!";
	
	cout << "첫 공백의 위치: " << s.find(' ') << "\n";
	int idx=s.find(' ');
	while (1) {
		int findSpaceIdx=s.find(' ', idx);
        	// 존재하지 않을 경우 -1을 반환한다.
		if(findSpaceIdx==-1)
		    break;
		cout<<findSpaceIdx<<" ";
		idx=findSpaceIdx+1;
	}
}

2. stringstream

이번 위클리 챌린지를 통해 배운 새로운 파싱법이다.

공백이 계속 이어질경우, 위와 같이 처리하기 좀 귀찮을 것이다.

특정 문자나 공백이 반복돼서 주어지는 경우 stringstream을 사용하면 굉장히 편리하다!

stringstream을 사용하기 위해서는 #include <sstream>을 삽입해주어야 한다.

 

평상시에 백준에서 string str; cin>>str; 을 사용했던 것과 유사하게 사용할 수 있기 때문이다.

stringstream으로 str화 시키기만 하면 cin과 유사하게 사용할 수 있다.

 

아래 코드를 참고하자.

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
	string s1="Hello C++ Programming Coder! Nice To Meet You!";
	string s2="I'm not C++ Programmer. I'm Java Programmer!";
	string str;
	
    	// ss.str(s1);
	// 또는 아래와 같이 ss.str(s1);을 할 수도 있다.
	stringstream ss(s1);
	while(ss >> str){
		cout<<str<<" ";
	}
	// stringstream 초기화는 clear로 가능하다.
	ss.clear();
	ss.str(s2);	// ss(s2);와 같이 str화는 불가능하다.
	while(ss >> str){
		cout<<str<<" ";
	}
}

채점 결과

사진 첨부를 위해 다시 들어가서 채점했더니, 이미 AC받은 코드라서 그런지 채점 때 테스트케이스들을 바로 통과시켜 채점시간은 정확하지 않을 수 있다.

둘 다 익혀두는 것이 정신건강에 좋을 것이다.

만약 둘 다 모른다면... 파싱 문제를 만났을 때 많이 힘들 것이다. 특히나 요즘같이 시간제한이 빡빡하고 문자열 파싱이 많이 나오는 코딩테스트 기조라면 더더욱. (그리고 특히 특히 카카오 코테!)

 

열공해서 코테에 발목잡히지 않고 개발에 집중할 수 있도록 하자!

 

*프로그래머스 정책에 따라 풀이 코드는 올리지 않습니다.*

반응형