예전에는 운영체제에서 크로아티아 알파벳을 입력할 수가 없었다. 따라서, 다음과 같이 크로아티아 알파벳을 변경해서 입력했다.
예를 들어, ljes=njak은 크로아티아 알파벳 6개(lj, e, š, nj, a, k)로 이루어져 있다. 단어가 주어졌을 때, 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력한다. dž는 무조건 하나의 알파벳으로 쓰이고, d와 ž가 분리된 것으로 보지 않는다. lj와 nj도 마찬가지이다. 위 목록에 없는 알파벳은 한 글자씩 센다.
입력
첫째 줄에 최대 100글자의 단어가 주어진다. 알파벳 소문자와 '-', '='로만 이루어져 있다. 단어는 크로아티아 알파벳으로 이루어져 있다. 문제 설명의 표에 나와있는 알파벳은 변경된 형태로 입력된다.
출력
입력으로 주어진 단어가 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력한다.
제출답안
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String words = sc.nextLine();
String[] croatia = {"c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z="};
sc.close();
for(int i=0; i<croatia.length; i++){
// 단어 words 에 크로아티아 배열 인덱스의 단어가 있으면 한글자로 대체
while(words.contains(croatia[i])){
words = words.replaceAll(croatia[i], "A");
}
}
System.out.println(words.length());
}
}
알파벳 소문자로만 이루어진 단어가 주어진다. 이때, 이 단어가 팰린드롬인지 아닌지 확인하는 프로그램을 작성하시오. 팰린드롬이란 앞으로 읽을 때와 거꾸로 읽을 때 똑같은 단어를 말한다. level, noon은 팰린드롬이고, baekjoon, online, judge는 팰린드롬이 아니다.
입력
첫째 줄에 단어가 주어진다. 단어의 길이는 1보다 크거나 같고, 100보다 작거나 같으며, 알파벳 소문자로만 이루어져 있다.
출력
첫째 줄에 팰린드롬이면 1, 아니면 0을 출력한다.
제출 답안1 - 오답
컴파일 에러가 발생했는데, charAt을 통해 한글자씩 떼어낸 문자를 String 타입에 대입하려고 한 것이 문제였다.
import java.util.Scanner;
public class Main{
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int N = str.length();
String A = "";
String B = "";
int count = 0;
for(int i=0; i<N; i++){
A = str.charAt(i);
B = str.charAt(N-i);
if(A.equals(B)) {
count ++;
}
}
if(count >= N){
System.out.println(1);
} else {
System.out.println(0);
}
sc.close();
}
}
문제 자체를 잘못 이해하고있음을 깨달았다.
팰린드롬확인을 위해 한글자씩 역순으로 비교하는 것은 잘못된 접근 방식이다.
문자를 거꾸로 뒤집은뒤 원래 문자와 일치하는지 비교하는게 맞는 접근 방식이었다.
아래의 힌트를 토대로 다시 코드를 작성하였다.
제출답안 : 수정답안, 정답
수정하여 답을 정정했더니 정답 처리 되었다.
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int N = str.length();
String reversedStr = "";
for(int i=N-1; i>=0; i--){
reversedStr += str.charAt(i);
}
if(str.equals(reversedStr)){
System.out.println(1);
} else {
System.out.println(0);
}
sc.close();
}
}
상근이의 할머니는 아래 그림과 같이 오래된 다이얼 전화기를 사용한다. 전화를 걸고 싶은 번호가 있다면, 숫자를 하나를 누른 다음에 금속 핀이 있는 곳 까지 시계방향으로 돌려야 한다. 숫자를 하나 누르면 다이얼이 처음 위치로 돌아가고, 다음 숫자를 누르려면 다이얼을 처음 위치에서 다시 돌려야 한다. 숫자 1을 걸려면 총 2초가 필요하다. 1보다 큰 수를 거는데 걸리는 시간은 이보다 더 걸리며, 한 칸 옆에 있는 숫자를 걸기 위해선 1초씩 더 걸린다.
상근이의 할머니는 전화 번호를 각 숫자에 해당하는 문자로 외운다. 즉, 어떤 단어를 걸 때, 각 알파벳에 해당하는 숫자를 걸면 된다. 예를 들어, UNUCIC는 868242와 같다. 할머니가 외운 단어가 주어졌을 때, 이 전화를 걸기 위해서 필요한 최소 시간을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 알파벳 대문자로 이루어진 단어가 주어진다. 단어의 길이는 2보다 크거나 같고, 15보다 작거나 같다.
출력
첫째 줄에 다이얼을 걸기 위해서 필요한 최소 시간을 출력한다.
제출 답안1 - 오답, 틀린이유
받아온 문자열을 한글자씩 for문으로 돌려 charAt을 이용해 받는데, 이를 문자형식으로 바꾸는데에 문제를 겪었다.
char 로 반환된 데이터 타입을 직접 참고하려고 해서 발생한 오류 같았다.
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String words = sc.nextLine();
String word = "";
int sum = 0;
for(int i=0; i<words.length(); i++){
word = words.charAt(i).toString();
if(word.equals("A") || word.equals("B") || word.equals("C")){
sum += 3; // 2+1
} else if(word.equals("D") || word.equals("E") || word.equals("F")){
sum += 4; // 3+2
} else if(word.equals("G") || word.equals("H") || word.equals("I")){
sum += 5; // 4+2
} else if(word.equals("J") || word.equals("K") || word.equals("L")){
sum += 6; // 5+2
} else if(word.equals("M") || word.equals("N") || word.equals("O")){
sum += 7; // 6+2
} else if(word.equals("P") || word.equals("Q") || word.equals("R") || word.equals("S")){
sum += 8; // 7+2
} else if(word.equals("T") || word.equals("U") || word.equals("V")){
sum += 9; // 8+2
} else if(word.equals("W") || word.equals("X") || word.equals("Y") || word.equals("Z")){
sum += 10; // 9+2
} else {
sum += 0; // 7+2
}
}
System.out.println(sum);
}
}
답안을 수정하며 (1) 번과같이 String.valueOf(); 사용시엔 문제가 없으나
(2) 번과 같이 toString(); 을 호출시 컴파일 에러가 발생함을 발견했다.
둘다 문자열로 변경하는 시도를 하고있는데 왜일까?
검색하니 toString은 객체에 대해서만 호출되는 메서드라고 한다. 이를 원시타입인 char 형태로 다루려고 하니 에러가 발생했다.
입력의 첫 줄에는 테스트 케이스의 개수 T(1 ≤ T ≤ 10)가 주어진다. 각 테스트 케이스는 한 줄에 하나의 문자열이 주어진다. 문자열은 알파벳 A~Z 대문자로 이루어지며 알파벳 사이에 공백은 없으며 문자열의 길이는 1000보다 작다.
출력
각 테스트 케이스에 대해서 주어진 문자열의 첫 글자와 마지막 글자를 연속하여 출력한다.
제출 답안1 - 오답, 틀린이유
입력 문자열이 앞 뒤로 공백을 포함할 수 있고 이를 다루지 않았다.
공백 문자만 포함된 단어는 단어가 입력되는 경우를 고려하지 못했다.
단어의 개수를 세는 방식에 문제가 있다.
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
// 문장 입력받기
String sentence = sc.nextLine(); // 문장 입력
String[] word = sentence.split(" ");
int cnt = 0;
for(int i=0; i<word.length; i++){
cnt++;
}
System.out.println(cnt);
}
}
배열의 길이를 구할때는 length(); 가 아니라 length를 사용하여야 한다.
문자열 배열의 길이를 구할때는 괄호를 붙이지 않는다.
입력 문자열이 앞 뒤로 공백을 포함할 수 있으므로 이를 제거해야 합니다.
공백을 기준으로 문자열을 자를게 아니라, 애초에 공백을 다 잘라놓고 문자열 배열에 저장을 하는것이 효율적이다.
trim() 메서드를 사용하여 입력 문자열의 앞 뒤 공백을 제거한다.
String sentence = sc.nextLine().trim(); // 앞 뒤 공백 제거
split("\\s+")를 사용하여 공백을 기준으로 문자열을 나눈다.
String[] words = sentence.split("\\s+"); // 공백을 기준으로 나누기
공백 문자만 포함된 단어는 단어로 취급하지 말아야 합니다.
for (String word : words) {
if (!word.isEmpty()) { // 공백 문자만 포함된 단어는 제외
cnt++;
}
}
제출답안 : 수정답안, 정답
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
// 문장 입력받기
String sentence = sc.nextLine().trim(); // 문장 입력
String[] words = sentence.split("\\s+");
int cnt = 0;
for(String word : words){
if(! word.isEmpty()){
cnt++;
}
}
System.out.println(cnt);
}
}
문자열 S를 입력받은 후에, 각 문자를 R번 반복해 새 문자열 P를 만든 후 출력하는 프로그램을 작성하시오. 즉, 첫 번째 문자를 R번 반복하고, 두 번째 문자를 R번 반복하는 식으로 P를 만들면 된다. S에는 QR Code "alphanumeric" 문자만 들어있다. QR Code "alphanumeric" 문자는 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\$%*+-./: 이다.
입력
첫째 줄에 테스트 케이스의 개수 T(1 ≤ T ≤ 1,000)가 주어진다. 각 테스트 케이스는 반복 횟수 R(1 ≤ R ≤ 8), 문자열 S가 공백으로 구분되어 주어진다. S의 길이는 적어도 1이며, 20글자를 넘지 않는다.
출력
각 테스트 케이스에 대해 P를 출력한다.
제출 답안1 - 오답, 틀린이유
nextInt() 를 입력받은 후 줄바꿈 문자때문에 발생할 오류를 처리해주지 못했다.
두번째 반복문에서 문자열(words)의 길이만큼 반복하는 것이 아니라, 문자열 길이에 따라 각 문자를 R번 반복해야하는데 적절한 코드를 작성하지 못했다.
String이 수정불가능한 형식이라는것을 간과했다. StringBuilder를 사용해주었어야 했다.
StringBuilder 를 사용하며 java.io.*;를 import 해주지 못했다.
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int wordsNum = sc.nextInt(); // 입력받을 단어개수
for(int i=0; i<wordsNum; i++){ // 입력받은 단어만큼 반복
int num = sc.nextInt(); // 스펠링을 몇번이어붙일건지
String words = sc.nextLine(); // 입력받은 단어
String addWords = ""; // 완성된 단어
for(int y=0; y<words.length(); y++){ // 단어의 스펠링 수만큼 반복
for(int z=0; z<num; z++){ // 반복할 숫자만큼 스펠링을 반복
addWords += words.charAt(z) + ""; //char는 아스키코드값 반환
}
}
System.out.println(addWords);
}
}
}
자꾸 놓치는 부분이다. nextInt()는 입력받은 다음 입력에 영향을 미칠 수 있기 때문에 sc.nextLine()을 사용해 줄바꿈 문자를 소비해 주어야 한다.
int wordsNum = sc.nextInt(); // 입력받을 단어 개수
sc.nextLine(); // 숫자 입력 후의 줄바꿈 문자 소비
for (int i = 0; i < wordsNum; i++) {
int num = sc.nextInt(); // 스펠링을 몇 번 이어붙일 건지
String words = sc.next(); // 공백 없이 단어를 입력받음
또한 아래 반복문 에서는, 단어의 길이만큼 반복하는 것이 아니라, 문자열 길이에 따라 각문자를 n번 반복하는 것이므로 세번째 for문 안에서는 words.charAt(y) 로 수정이 되어야 한다.
또한 StringBuilder를 사용해 문자열의 변경을 할 경우 append 메소드를 사용해 주어야 한다.
for (int i = 0; i < wordsNum; i++) {
int num = sc.nextInt(); // 스펠링을 몇 번 이어붙일건지
String words = sc.next(); // 공백 없이 단어를 입력받음
StringBuilder addWords = new StringBuilder(); // 완성된 단어
for (int y = 0; y < words.length(); y++) {
for (int z = 0; z < num; z++) {
addWords.append(words.charAt(y));
}
}
System.out.println(addWords.toString());
}
또한 StringBuilder형을 문자열로 변환하기 위해서는 toString 메서드를 사용해주어야 한다.
import java.util.*;
import java.io.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int wordsNum = sc.nextInt(); // 입력받을 단어개수
sc.nextLine();
for (int i = 0; i < wordsNum; i++) {
int num = sc.nextInt(); // 스펠링을 몇 번 이어붙일건지
String words = sc.next(); // 공백 없이 단어를 입력받음
StringBuilder addWords = new StringBuilder(); // 완성된 단어
for (int y = 0; y < words.length(); y++) {
for (int z = 0; z < num; z++) {
addWords.append(words.charAt(y));
}
}
System.out.println(addWords.toString());
}
}
}
다른 블로그의 코드도 확인해 볼 수 있었다. print를 이용해 각 문자를 반복해 출력하면 되므로 굳이 StringBuilder를 사용하지않고도 코드를 작성할 수 있다는것을 확인했다.