👀 문제 설명
선영이는 C, C++, Java와는 다른 아주 세련된 언어를 만들었다. 선영이는 이 아름답고 예술적인 언어의 이름을 i#으로 정했다.
i#은 기본 변수형과 배열([]), 참조(&), 포인터(*)를 제공한다. 배열, 참조, 포인터는 순서에 상관없이 혼합해서 사용할 수 있다. 즉, int의 참조의 참조의 배열의 포인터도 올바른 타입이다. int&&[]*
i#은 여러 개의 변수를 한 줄에 정의할 수 있다. 공통된 변수형을 제일 먼저 쓰고, 그 다음에 각 변수의 이름과 추가적인 변수형을 쓰면 된다. 예를 들면 아래와 같다.
int& a*[]&, b, c*;
a의 타입은 int&&[]*, b는 int&, c는 int&*이 된다. 변수의 오른편에 있는 변수형은 순서를 뒤집어서 왼편에 붙일 수 있다. 따라서, int*& a는 int a&*와 같다.
변수의 선언이 보기 복잡하고 혼란스럽기 때문에, 앞으로는 한 줄에 변수를 하나씩 선언하려고 한다.
i#의 변수 선언문이 주어진다. 이때, 각각의 변수의 오른편에 있는 변수형을 모두 왼쪽으로 옮기고, 한 줄에 하나씩 선언하는 프로그램을 작성하시오.
입력
첫째 줄에 i#의 변수 선언문이 주어진다. 이 선언문에는 변수가 여러개 포함되어 있을 수도 있다.
선언문의 가장 처음에는 기본 변수형이 주어진다. 그 다음에는 추가적인 변수형이 주어진다. 추가적인 변수형은 없을 수도 있다. 그 다음 공백 이후에는 변수 선언이 하나씩 주어진다. 변수 선언은 콤마와 공백으로 나누어져 있고, ;로 끝난다. 각 변수의 선언 처음에는 기본 변수명이 주어진다. 그 다음에는 추가적인 변수형이 주어진다. 추가적인 변수형은 없을 수도 있다.
기본 변수형과 변수명은 같지 않으며, 알파벳 소문자와 대문자로만 이루어져 있다. 각 줄의 길이는 120글자를 넘지 않는다.
출력
입력으로 주어진 변수 선언문을 문제의 조건에 맞게 변형한 뒤, 한 줄에 하나씩 출력한다. 변수형과 변수명 사이에는 공백이 하나 있어야 한다. 출력은 입력으로 주어진 변수 선언문에서 변수가 선언된 순서대로 출력한다.
예제 입력 1
int& a*[]&, b, c*;
예제 출력 1
int&&[]* a;
int& b;
int&* c;
✍🏻풀이
변수 i#을 입력받아, 공백을 기준으로 문자열을 나눠 vector<string> splitByGap 벡터에 넣는다.
splitByGap.at(0)은 변수형이고, 이후의 원소들은 각각 변수이다.
string variable은 변수를 한 줄로 출력하기 위한 것이다. variable의 초기값은 splitByGap.at(0)이다.
각 변수에 접근하여 이중for문을 사용해 변수의 뒤에서부터 다시 접근한다. (ex. 변수가 a*[]&라면 &부터 접근)
만약, 현재 char가 ; , 이면 아무런 일도 하지 않고 다음으로 넘기고, ]라면 variable에 "[]"를 더해주고, 인덱스를 -1 해준다. ( [ 일 때 아무런 처리도 안하기 위해)
변수명은 영어의 대소문자로만 이루어져있으므로, 만약 현재 char가 영어의 대소문자라면 (아스키 코드 사용) variableName이라는 벡터에 넣어준다.
변수의 for문이 끝났다면, variableName 벡터를 reverse해주고, 이를 variable에 붙여준다.
<알아낸 것>
공백이 포함된 문자열을 입력받을 땐 cin >> str이 아니라 getline(cin, str)을 사용한다!
-> cin은 공백을 문자열이 끝나는 단위로 보기 때문
+ 스택을 사용해서 풀어도 된다!
코드를 너무 더럽게 짜는 것 같다.. + 예외 케이스를 잘 생각해내자
코드
//
// BOJ_3568.cpp
// Algorithm
//
// Created by 조수민 on 2021/01/13.
// Copyright © 2021 조수민. All rights reserved.
//
// iSharp
#include <stdio.h>
#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;
vector<string> split(string input, char delimiter) {
vector<string> answer;
stringstream ss(input);
string temp;
while (getline(ss, temp, delimiter)) {
answer.push_back(temp);
}
return answer;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
// input
string str;
// cin >> str; // 공백이 포함된 문자열을 입력받을 땐 이렇게 하면 안된다!! cin은 공백이 문자열이 끝나는 단위로 보기 때문에, 공백을 만나면 문자열 입력이 끝났다고 생각한다!
getline(cin, str); // 공백이 포함된 문자열을 입력받을 땐 getline을 사용하면 된다!!!
// 공백을 기준으로 잘라준다.
vector<string> splitByGap = split(str, ' '); // { "int&", "a*[]&,", "b,", "c*;" }
string variableType = splitByGap.at(0); // 가장 첫번째에 있는 인자는 변수형이다.
vector<string> answer;
for (int i = 1; i < splitByGap.size(); i++) {
string curStr = splitByGap.at(i); // a*[]&,
string variable = variableType; // int&
vector<char> variableName;
for (int j = curStr.length() - 1; j >= 0; j--) {
if (curStr[j] == ';' || curStr[j] == ',')
continue;
else if (curStr[j] == ']') {
variable += "[]";
j--; // "[]" 쌍이므로 j - 1을 한번 더 한다.
}
else if (((int)curStr[j] >= 65 && (int)curStr[j] <= 90) || ((int)curStr[j] >= 97 && (int)curStr[j] <= 122)) {
variableName.push_back(curStr[j]);
}
else {
variable += curStr[j];
}
}
reverse(variableName.begin(), variableName.end()); // variableName에는 변수명이 거꾸로 들어가있으므로 reverse 해줘야 한다.
variable += " ";
for (int i = 0; i < variableName.size(); i++) {
variable += variableName.at(i);
}
answer.push_back(variable);
}
for (int i = 0; i < answer.size(); i++) {
cout << answer.at(i) << ";" << endl;
}
return 0;
}
'숨막히는 알고말고 > 문제 풀이' 카테고리의 다른 글
[SWEA] 중간 평균값 구하기(Difficulty 2) (0) | 2021.01.18 |
---|---|
[SWEA] 연월일 달력(Difficulty 2) (0) | 2021.01.16 |
[Baekjoon] 봄버맨 (0) | 2021.01.13 |
[Baekjoon] 가장 긴 증가하는 부분 수열 4 (0) | 2021.01.09 |
[Baekjoon] 가장 긴 증가하는 부분 수열 (0) | 2021.01.09 |