coding test

[파이썬, Java] 3568. iSharp

잔망루피 2021. 6. 21. 16:59

문제

선영이는 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;

 

 

👧 나의 풀이

 

import sys, re
pattern=re.compile("[\[\]\*&]+")	# 배열([]), 참조(&), 포인터(*) 매치
alpha=re.compile("[\w]+")			# 문자, 숫자 매치
input=sys.stdin.readline
i=input().rstrip()        # i#(기본 변수형, 배열, 참조, 포인터 제공)
variable=i.split()    # 변수형, 변수명
for j in variable[1:] :
    temp=''.join(pattern.findall(j))    # 배열, 참조, 포인터
    char=''.join(alpha.findall(j))		# 변수명
    reverse_temp=''.join(reversed(temp))    # 뒤집기
    reverse_temp=reverse_temp.replace("][", "[]")   # 괄호 제대로 맞추기
    ans="{}{} {};".format(variable[0], reverse_temp, char)
    print(ans)

 

한 번에 통과해서 기분좋다😊

정규표현식을 사용했다. 이제 좀 사용하는 방법을 익혔다

"[a-z A-Z]+" 이렇게 대소문자를 매치할 수도 있지만 간단하게 "[\w]+"를 사용했다. 숫자는 입력에 안 들어오니까ㅎ

findall은 문자열을 매치 후 리스트로 반환해준다. join을 사용해서 문자열로 변환했다. 아니면 값이 하나니까 [0]해도 됨

reversed(seq)는 iterator를 뒤집어서 반환한다.

replace로 괄호를 제대로 맞춰줬다.

format으로 문자열을 형식에 맞게 출력할 수 있도록 했다.

 

 

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException{
        InputStreamReader isr=new InputStreamReader(System.in);
        BufferedReader br=new BufferedReader(isr);
        String str = br.readLine();
        str=str.substring(0, str.length()-1);
        String[] variable=str.split(", ");
        String[] first=variable[0].split(" ");  // 공통된 변수형과
        variable[0]=first[1];   // 공통된 변수형 제외
        for(int i=0; i< variable.length; i++){
            String ans="";
            if(variable[i].length() > 1 ) {     // 추가적인 변수가 있으면
                // 추가적인 변수와 변수명 구분하기
                String addv=variable[i].replaceAll("[^\\& \\[ \\] \\*]", "");
                String v=variable[i].replaceAll("[^a-z A-Z]","");
                String reversed=reverse_string(addv);
                reversed=reversed.replaceAll("\\]\\[", "[]");
                ans=first[0]+reversed+" "+v+";";
            } else ans=first[0]+" "+variable[i]+";";    // 추가적인 변수가 없을시
            System.out.println(ans);
        }
    }

    static public String reverse_string(String s){
        StringBuffer reversed=new StringBuffer(s);
        return reversed.reverse().toString();
    }

}

 

replaceAll을 사용해서 추가적인 변수와 변수명을 추출한다.

"[^\\& \\[ \\] \\*]"는 &, [, ], *가 아닌 문자를 의미한다.

"[^a-z A-Z]"는 소문자, 대문자가 아닌 문자를 의미한다.

reverse_string 메소드에서 문자열 s를 뒤집어서 반환한다. 이때 s는 추가적인 변수만 뒤집어야 한다. 

replaceAll("\\]\\[", "[]")는 ][를 []로 변환한다.

 

 

💨 다른 사람 풀이

 

import sys
input=sys.stdin.readline

variables=list(input().split())
answer=[]
for i in range(1, len(variables)) :
    temp=variables[0]
    variable_name=''
    variable_type=''
    for i in variables[i][:-1] :
        if i.isalpha() :
            variable_name+=i    # 변수명
        else :
            variable_type+=i    # * 또는 [] 또는 &
    variable_type=''.join(list(reversed(variable_type)))
    if '][' in variable_type :
        variable_type=variable_type.replace('][', '[]')
    temp+=variable_type+' '+variable_name+';'
    answer.append(temp)

for i in answer : print(i)

 

for문과 if문으로 변수명, * 또는 [] 또는 &를 찾고 문자열에 추가한다.

변수 선언문을 리스트에 다 담은 후 하나씩 출력한다.

 

 

s=input()
s=s.split()
t=s[0]		# 기본 변수형
s=s[1:]
s=list(map(lambda x:x[:-1], s))
for a in s :
    idx=-1
    for i in range(len(a)) :
        if a[i] == '&' or a[i] == '[' or a[i] == '*' :
            idx=i
            break
    if idx == -1 :
        print(t+' '+a+';')
        continue
    tmp=a[idx:][::-1]		# 뒤집기
    for i in range(len(tmp)) :
        if tmp[i] == '[' :
            tmp=tmp[:i]+']'+tmp[i+1:]
        elif tmp[i] == ']' :
            tmp=tmp[:i]+'['+tmp[i+1:]
    print(t+tmp+' '+a[:idx]+';')

 

lambda를 이용해서 리스트 슬라이싱으로 ',' 또는 ';'를 없앤다.

idx는 알파벳 문자와 아닌 것을 구분하는 기준 인덱스다.

& 또는 * 또는 []가 없으면 idx가 -1이므로 바로 출력한다.

그렇지 않으면 문자열 a의 idx부터 거꾸로 뒤집는다.

 

 

 

문제 출처 👉 백준

 

반응형

'coding test' 카테고리의 다른 글

[Python, Java] 프린터  (0) 2021.06.28
[파이썬] 8911. 거북이  (0) 2021.06.21
[파이썬, Java] 2252. 줄 세우기  (0) 2021.06.16
[파이썬] 1197. 최소 스패닝 트리  (0) 2021.06.13
[파이썬] 1916. 최소비용 구하기  (0) 2021.06.11