[백준] 2588번 : 곱셈 - [C++]
https://www.acmicpc.net/problem/2588
-
문제
매우 간단한 문제다!
- 3개의 풀이 방법을 제시한다.
이 문제는 하나로 입력된 문자(숫자)를 분리하여 연산을 할 수 있는지를 확인하는 문제다.
그래서 필자가 문제 접근 방법을 두 가지로 나누어서 제시하고자 한다.
- 알고리즘
첫 번째 입력으로 들어오는 세 자리수 정수에 두 번째 입력으로 들어오는 정수를 분리하여 각 각 곱한 값을 출력(3~5) 한 뒤 마지막에는 원래 식의 연산 값을 출력해주어야 한다.
그럼 두 번째 입력값을 어떻게 분리해주어야 하냐의 문제인데 방법은 크게 2가지가 있다.
- char[] 로 문자열을 다뤄 string[index] 으로 하나씩 꺼내 쓰는 방법
- 문자열(std::string)을 이용하여 string.at() 또는 string[index] 으로 하나씩 꺼내 쓰는 방법
- 나머지와 나눗셈 연산을 통해 각 자릿수를 구하여 쓰는 방법
여기서 1번과 2번의 방법은 문자열로 입력받기 때문에 가장 마지막 출력(6) 에서는 연산하기 위해서 int형으로 변환해주어야 한다.
가장 일반적으로 가장 쉽고 많이 쓰는 방법이 3번이라고 생각된다.
그럼 각각의 방법으로 풀어보자.
- 풀이
- 방법 1
#include <iostream>
#include <cstdlib> // atoi 함수가 선언된 헤더파일
using namespace std;
int main(int argc, char const *argv[]) {
int A;
char B[4];
cin >> A;
cin >> B;
cout << A * (B[2] - '0') << "\n";
cout << A * (B[1] - '0') << "\n";
cout << A * (B[0] - '0') << "\n";
cout << A * atoi(B) << "\n";
return 0;
}
먼저 A는 int로, B는 char[] 으로 입력받는다.
그리고 B는 인덱스를 통해 각 자리수를 참조해준다.
즉, 문자열의 인덱스 위치에 있는 문자(Character) 값을 반환한다.
그림으로 쉽게 이해해보자면
위 배열에 abcdef 가 저장되어있을 때 문자열을 문자들이 모인 배열이라고 보고 인덱스를 참조하여 해당 문자를 반환하는 것이다.
이때 반환되는 값은 아스키코드값인 문자 (char)이다.
char num[] = "345"; 가 있다고 하자.
int result = num[0];라고 하면 result = 3 으로 착각할 수 있으나 실은 문자의 '3' 이지 숫자 3 이 아니라는 것이다.
즉, result = 51 이 저장되는 것이다.
아스키 코드값을 보려면 아래 사진을 참고하면 된다.
그렇기에 풀이 방법에도 각각의 문자열 인덱스를 참조한 뒤 -'0' 을 해주는 이유 또한 우리가 문자로 저장된 숫자가 아닌 우리가 보는 숫자 그대로의 값을 쓰기 위한 것이다.
마지막 출력은 전체 곱한 결과를 출력하면 되므로 우리가 입력받은 문자열을 숫자로 바꿔주는 atoi() 함수를 통해 문자열을 int형으로 바꿔주어 A와 곱해준 값을 출력하면 문제는 끝난다.
이 때 atoi() 함수는 cstdlib 에 있다. (또는 stdlib.h 으로 대체해도 무방하다.)
만약 C언어 스타일로 코딩한다고 한다면 다음과 같이 수정할 수 있다.
#include <stdio.h>
#include <stdlib.h> // atoi 함수가 선언된 헤더파일
int main(int argc, char const *argv[]) {
int A;
char B[4];
scanf("%d", &A);
scanf("%s", B);
printf("%d\n", A * (B[2] - '0'));
printf("%d\n", A * (B[1] - '0'));
printf("%d\n", A * (B[0] - '0'));
printf("%d\n", A * atoi(B));
return 0;
}
- 방법 2
C++는 Java나 Python 처럼 문자 배열이 아닌 문자열로 다룰 수 있게 구현되어있다.
std::string 클래스를 이용하면 되는데, 이 방법으로 풀이하는 방식은 이 문제에 한하여는 방법 1과는 크게 다를 것은 없지만, 이후 문자열 처리에 있어 매우 손쉽게 다룰 수 있는 좋은 클래스다.
이 때 조금 다른 부분이라 함은 마지막에 문자열 B를 정수(int)로 바꾸어야 하는데, string은 C++에서만 지원하는 클래스라 C언어에서 쓰는 stdlib 의 atoi() 함수를 못쓴다.
대신에 string 헤더파일 안에 string을 int형으로 바꾸어 주는 함수가 있다.
바로 stoi() 함수인데, 이름도 비슷해서 헷갈릴 수 있으니 조심하시길 바란다.
아래 코드를 보자.
#include <iostream>
#include <string> // string, stoi()을 쓰기 위한 헤더파일
using namespace std;
int main(int argc, char const *argv[]) {
int A;
string B;
cin >> A;
cin >> B;
cout << A * (B[2] - '0') << "\n";
cout << A * (B[1] - '0') << "\n";
cout << A * (B[0] - '0') << "\n";
cout << A * stoi(B) << "\n"; // string -> int(10진수) 로 변환
return 0;
}
- 방법 3
숫자를 수학적으로 접근하여 푸는 방법이다.
이 문제의 포인트는 B에 들어오는 입력값을 각 자릿수 별로 얻어오는 것이다.
그럼 두번째 입력으로 들어오는 385 의 각 자릿수 값을 어떻게 구할까?
일의 자리 5의 경우 385 % 10 을 해주면 10으로 나눠준 값의 나머지를 구하니 5가 반환이 될 것이다.
십의자리 8은 385 % 100 을 해주면 85 가 나오고 이걸 10으로 나누면, 즉 85 / 10 을 하면 8이 반환 될 것이다.
백의자리 3은 385 / 100 을 하면 3이 나온다.
아래 코드를 보자.
#include <iostream>
using namespace std;
int main(int argc, char const *argv[]) {
int A, B;
cin >> A >> B;
cout << A * (B % 10) << "\n";
cout << A * ((B % 100) / 10) << "\n";
cout << A * (B / 100) << "\n";
cout << A * B;
return 0;
}
아마 이 방법이 가장 쉬울 것이다.
- 성능 차이
위에서 부터 순서대로
채점 번호 : 26779068 - 방법 3
채점 번호 : 26779066 - 방법 2
채점 번호 : 26779063 - 방법 1
- 정리
문자열 입출력 part 는 이걸로 끝이다.
대체적으로 쉬운 문제인 만큼 입출력에 대해 여러 방법들을 익히고 기초를 단단히 할 수 있었으면 좋겠다.
'C++ - 백준 [BAEK JOON] > 입출력과 사칙연산' 카테고리의 다른 글
[백준] 18108번 : 1998년생인 내가 태국에서는 2541년생?! - [C++] (0) | 2022.07.01 |
---|---|
[백준] 10926번 : ??! - [C++] (0) | 2022.06.30 |
[백준] 10430번 : 나머지 - [C++] (5) | 2021.02.25 |
[백준] 10869번 : 사칙연산 - [C++] (0) | 2021.02.24 |
[백준] 1008번 : A/B - [C++] (12) | 2021.02.23 |