import java.util.*;
import java.lang.*;
import java.io.*;
class Main {
static String S;
static int pos = 0;
//현재 위치부터 괄호가 끝날 때까지
//알파벳 개수를 세어 반환하는 함수
static long[] parse() {
long[] counts = new long[26]; // 현재 알파벳 개수
long multiplier = 0; //반복할 횟수?
boolean hasMultiplier = false; // 숫자가 있었는지?
// 순회 진행
while (pos < S.length()) {
char c = S.charAt(pos); // 이번 idx 요소 추출
if(c >='0' && c<='9') { // 일단 숫자인지 확인, 숫자인지 확인을 c>='0' 같은 형태로 했네, 둘 다 char끼리의 비교니까 이 경우 비교는 ASCII 로 하나봄
multiplier = multiplier * 10 + (c-'0'); // 이게 좀 어렵네
// 132 이라는 숫자를 가정해보면
//처음에 multiplier = 0*10 + c 니까 1 , 두번째에서 1*10+3으로 13, 다음에 130+2 = 132가 나오네.
//숫자를 처리할 로직.
hasMultiplier = true;
pos ++;
} else if (c=='(') {
// 괄호가 나오면 다음 순서의 숫자를 보고 pos++
// subCounts 에 다음 숫자 처리에 대한 걸 받을거임.
pos ++;
long[] subCounts = parse(); // 새로운 parse에서 만들어진 counts 배열을 받을 것.
long m = hasMultiplier ? multiplier : 1; // (가 시작함에 따라 count배열이 만들어졌는데 그 앞에 수가 있었다면 즉, hasMultiplier가 true라면
// multiplier를 곱해야하고, 안나오면 뭐 넘기고(1을 곱해도 됨)
for (int i=0; i<26; i++) {
counts[i] += subCounts[i] * m;
}
// 여기까지 왔다는게 저기 위의 parse에서 )를 만나 추가적인 작업할 필요 없음, 과정이 끝났으니.
pos++; // 처리가 되면 다음 작업을 위할거고 아래값들을 초기화시킴
multiplier = 0;
hasMultiplier = false;
} else if (c==')') {
break; // 끝내라
} else {
// 이 경우는 (도 아니고 )도 아니고 숫자도 아니고 그럼 문자네. 문자일 때는 아, 여기도 앞의 수를 활용해야하니 multiplier를 다뤄야하구나
long m = hasMultiplier ? multiplier : 1;
counts[c-'a'] += m;
pos ++;
multiplier = 0;
hasMultiplier = false;
}
}
return counts;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
S = br.readLine();
long[] finalCounts = parse();
StringBuilder sb = new StringBuilder();
for (int i=0; i<26; i++) {
char c = (char) (i+'a');
sb.append(c).append(" ").append(finalCounts[i]).append("\n");
}
System.out.print(sb.toString());
}
}
To embed this project on your website, copy the following code and paste it into your website's HTML: