본문 바로가기

별걸다하는 IT/알고리즘 문제풀이

[백준 BAEKJOON]10172번 개,11718번 그대로 출력하기 문제, 오답원인

백준(BAEKJOON) 알고리즘 문제 풀기- 난이도: 하

 

역시 기초라 그런가 알고리즘 보다는 프로그래밍을 아나 확인하는 문제에 가깝군요 ㅎㅎ

단순 문자열 출력입니당

[10172] 개

----------------------------------------------------------------------------------------

 

문제: 아래 예제와 같이 개를 출력하시오

시간제한: 1초, 메모리 제한 256MB

 

입력: 없음

출력: 개를 출력한다.

예시:

----------------------------------------------------------------------------------------

[11718] 그대로 출력하기

----------------------------------------------------------------------------------------

문제: 입력받은대로 출력하는 프로그램을 작성하시오

시간제한: 1초, 메모리 제한 256MB

입력: 입력이 주어진다. 입력은 최대 100줄로 이루어져 있고, 알파벳 소문자, 대문자, 공백, 숫자로만 이루어져 있다. 각 줄은 100글자를 넘지 않으며, 빈 줄은 주어지지 않는다. 또, 각 줄은 공백으로 시작하지 않고, 공백으로 끝나지 않는다.

예시:

Hello

Baekjoon

Online Judge

 

출력: 입력받은 그대로 출력한다.

예시:

Hello

Baekjoon

Online Judge

 

 

ANSWER

특수문자를 그대로 출력하려면 어떻게 해야하는지 알고 있나~~ 물어보는 문제네요

특수문자 그대로 출력하려면 '\'이거 앞에 붙여줘야 해요! ㅎㅎ

즉 "는 원래 문자열임을 알려주고 싶을 때 사용하는 기호지만, 그런 의도에서 말고 진짜 "를 출력하고 싶으면 \" 이렇게 써줘야 하는거죠.

 

두 번째 문제 '그대로 출력하기'의 경우에는 입력도 들어갔네요!

입출력함수가 워낙 다양하니 다양한 방법이 있겠죠. 하나하나 살펴볼테니 작성해보면서 습득하도록 합시다. 더 좋은 알고리즘 해답 있으면 알려주세요~:)

 

[10172- C언어]

#include <stdio.h>
int main()
{
    printf("|\\_/|\n");
    printf("|q p|   /}\n");
    printf("( 0 )\"\"\"\\\n");
    printf("|\"^\"`    |\n");
    printf("||_/=\\\\__|\n");
    return 0;
}

메모리: 1116KB

시간: 0ms

코드 길이: 199KB

 

조심해야할 것은 뒤에 "\n"까묵지 말라는거랑 타자 오타 주의 정도?

 

[10172 - C++언어]

#include <iostream>

int main()
{
    std::cout<<"|\\_/|"<<std::endl;
    std::cout<<"|q p|   /}"<<std::endl;
    std::cout<<"( 0 )\"\"\"\\"<<std::endl;
    std::cout<<"|\"^\"`    |"<<std::endl;
    std::cout<<"||_/=\\\\__|"<<std::endl;
    return 0;
}

메모리: 1116KB

시간: 0ms

코드 길이: 262KB

 

자바의 경우 출력 부분만 System.out.println(" ");이 메서드로 대체해주면 돼요.

특수문자 출력 방법은 똑같으니까요!

 

[11718문제 C언어 - scanf, printf]

가장 먼저 하나 읽고 하나 출력하고

다시 하나 읽고 하나 출력하고 반복할 수 있겠죠?

#include<stdio.h>
int main() {
    char c;
    while (scanf("%c", &c) != EOF) {
        printf("%c", c);
    }
}

EOF가 무엇을 의미하는지 혹시 처음 본 분들께서는 짚고 넘어갑시다

사실 EOF는 -1이예요. -1이라고 매크로로 정의되어 있는 상수랍니다. 근데 왜 여기서 -1이 나오느냐~

scanf를 입력받는데만 써서 많이 모르는데 scanf는 정수형을 반환해주는 반환함수입니다.

평소에는 포맷 형식 갯수를 반환하는데 파일 끝에 도달하면 EOF라는 값을 반환해줘요 (윈도우일 경우 종료를 의미하는 Ctrl+Z가 입력되면 EOF가 반환됩니다.)

즉 저 코드는 파일 끝에 도달하면 출력을 멈추겠다가 되므로 Good~

 

[11718문제 C언어 - 정규식]

100글자를 넘지 않는다는 조건이 있으니까 배열타입으로 풀어볼게요.

문자열이니까 여기에도 당연히 정규식으로 패턴을 활용한 입력이 가능하겠죠? scanf의 리턴 특징과 정규식을 이용해서 풀 수도 있어요.

#include <stdio.h>
int main()
{
    char str[110]; //넉넉하게 110으로 줬음
    while(scanf("%[^\n]\n", str)==1){
        printf("%s", str);
    }
    return 0;
}

간단하게 설명을 하자면? 대괄호안에 있는 ^는 부정을 의미해요.즉 개행으로 시작하지 않는 모든 문자를 입력받으라는 건데 마지막이 \n로 끝나야 함으로 한 줄을 입력받으라는 뜻이 되는거죠!

주의해야할점은 대괄호 이후에 '\n'를 넣어주지않으면 다음 반복문에서 str에 개행이 들어가버려요 ㅎㅎ 그래서 개행까지 받아줘야한답니다. 포맷에 맞는 패턴을 찾으면 1을 반환해주겠죠?! :)

 

[11718문제 C++언어 - getline, cout, puts]

C++의 string클래스의 getline함수를 이용할 수도 있어요. getline은 한 줄을 읽어들이는 함수입니다.

iostream의 getline함수도 있고 string의 getline함수도 있으니 헷갈리지 말고 정리해놓기 !

getline 정리한 포스팅 보러가려면 클릭

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string line;
    getline(cin, line);
    while (line.length()>0)
    {
        cout<<line<<endl;
        getline(cin, line);
    }
    return 0;
}

이번에는 EOF말고 입력한 문자열의 길이로 문자열이 비었는지 안비었는지 판별해봤어요 ㅎㅎ

#include <iostream>
#include <string>
using namespace std;
int main(){
    string str;
    getline(cin, str);
    while(str!= "\0"){
        puts(str.c_str());
        getline(cin, str);
    }
    return 0;
}

또는 이렇게 구현할 수도 있습니다. 이번에는 문자열이 NULL인지 아닌지를 기준으로 반복을 할지 말지 판단해줬습니다. 주의할점이 있다면 puts를 사용할 때는 puts가 C언어 함수 즉 C-Style 배열 형식으로 문자열을 받아들이기 때문에 string을 문자열배열형식으로 변환해서 출력해줘야해요 (c_str())

 

[11718번 Java 자바 - BufferedReader, BufferedWriter]

아무래도 가장 먼저 생각나는건 bufferedWriter랑 Scanner겠죠?

bufferedReader와 Scanner는 readLine과 nextLine이라는 메서드를 가지고 있기 때문에 가장 먼저 떠오르지 않았나 생각해봅니다. 자주써서 익숙하기두하고..ㅎ한 줄을 읽어온다는 점에서 간편하기도 하고 ㅎㅎ

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Main {
     public static void main(String[] args) throws IOException {
         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
         BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
         String str ="";
         while((str = br.readLine()) != null) {
             bw.write(str);
             bw.newLine();
             bw.flush();
         }
         br.close(); bw.close();
     }
}

bufferedReader 사용시 주의해야할 점이 있다면..?

readLine()은 String값으로 개행 문자(엔터값)을 포함해 한 줄을 전 부 읽어온뒤 마지막 문자를 버려요

즉 개행이 버려지기 때문에 write(str);만 사용하면 안됩니당 write(str+"\n");을 해주던? 위의 코드처럼 newLine()으로 개행을 따로 출력해줘야 완벽히 인풋과 아웃풋이 일치하게 됩니다.

 

[11718번 Java 자바 - Scanner, System.out.println]

이번에는 단순히 Scanner를 사용해봅시다

import java.util.Scanner;
import java.io.IOException;
public class Main {
     public static void main(String[] args) throws IOException {
         String str ="";
         Scanner sc = new Scanner(System.in);
         while(sc.hasNextLine()){
             str=sc.nextLine();
             System.out.println(str);
         }
     }
}

BufferedReader랑 Scanner는 비슷하면서도 해야하는 처리가 엄연히 다릅니다! 사용법의 차이점을 확실하게 이해하고 갑시다

자바의 BufferedReader.nextLine()은 파일 마지막에 도달하면 null을 반환하는데 scanner의 nextLine()은 null이 아니라 NoSuchElementException을 던집니다.

따라서 아래처럼 작성하면 틀린 코드가 됩니다. ㅎㅎ 그리고 해당 문제는 개행을 입력해도 개행을 출력해줘야 하기 때문에 isEmpty()로 반복문을 계속 돌지 구분하는 것도 오답의 원인이 됩니다.

import java.util.Scanner;
import java.io.IOException;
public class Main {
     public static void main(String[] args) throws IOException {
         String str ="";
         Scanner sc = new Scanner(System.in);
         while((str = sc.nextLine())!=null){
             System.out.println(str);
         }
     }
}

오늘은 여기까지입니다.~ 그 외에도 앞에 C로 예시들었던 것처럼 자바의 read라는 함수로 한 글자씩 읽어와서 비교대조해볼 수 있어요 ㅎㅎ

다음 알고리즘 문제에서 또 만나요. 도움이 되셨다면 공감 클릭, 댓글 작성, 광고 클릭 ! (열띠미 뚜뚠 알고리즘별로 작성한 수고를 봐서 좋은마음으로 해주면 좋은 거! ㅎㅎ)