- C언어 : 기본수학1(8)
15.JUL.2022
두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
첫째 줄에 A와 B가 주어진다. (0 < A,B < 1010000)
#include <stdio.h>
#include <string.h>
void reverse(char arr[]) { // 문자열을 넘겨받아 뒤집어주기
char tmp;
// 뒤집는다==문자열의 반만 서로 순서를 뒤바꾸면 된다. (streln /2)
for (int i = 0; i < strlen(arr) /2; i++)
{
tmp = arr[i];
arr[i] = arr[strlen(arr) - i - 1]; // -1=='\0' 빼주기
arr[strlen(arr) - i - 1] = tmp;
}
}
int main() {
// 숫자 a,b를 문자열로 받아 처리
// a+b를 담을 sum의 범위는 당연히 a+b보다 크게 해준다.
char a[10001] = { 0 }, b[10001] = { 0 }, sum[10005] = { 0 };
int len, num, carry = 0;
scanf("%s %s", a, b); // 두 숫자를 문자열로 입력받기
// reverse() == 문자열 뒤집어주기
reverse(a);
reverse(b);
// 길이가 더 긴 문자열로 범위를 잡기
len = strlen(a) > strlen(b) ? strlen(a) : strlen(b);
for (int i = 0; i < len; i++) {
// 문자열의 맨 앞(숫자의 일의 자리)부터 둘을 더하기
// 문자열 상태이므로 '0'을 빼줘야 자기 본래의 값이 들어간다.
// carry == 올림수
num = a[i] - '0' + b[i] - '0' + carry;
// a,b의 길이가 다른 경우, a[i] 또는 b[i]의 값은 null, 애꿎은 '0'값이 마이너스
// num이 음수가 되버리므로, 다시 양수로 만들어준다.
while (num < 0)
num += '0';
// 만약 a+b가 올림 수가 발생한다면, 다음 num에 계산할 수 있도록 1로 바꿔줌
if (num >= 10) carry = 1;
else carry = 0;
// 둘을 더한 값의 일의 자리 수만 결과 배열에 저장
sum[i] = num % 10 + '0';
}
// 둘을 더한 후 마지막 올림수가 있을 때 배열 저장
if (carry) sum[len] = '1';
// 다시 원래의 순서로
reverse(sum);
printf("%s", sum);
}
그래 인정합니다. 처음에 unsigned long long으로 풀고 좋다고 있다가 장렬하게 틀렸다.
구글링 해보고 아 저 얘기가 아니었구나 머쓱타드...나만 그런 거 아니라고 믿고 싶어...한 명쯤은..한 명쯤은.....😧
// 숫자 a,b를 문자열로 받아 처리
// a+b를 담을 sum의 범위는 당연히 a+b보다 크게 해준다.
char a[10001] = { 0 }, b[10001] = { 0 }, sum[10005] = { 0 };
int len, num, carry = 0;
scanf("%s %s", a, b); // 두 숫자를 문자열로 입력받기
sum 배열의 범위를 더 크게 해주라는 말을 왜 썼냐하면 내가 바로 범위를 똑같이 설정했다가 틀렸기 때문이다. 아주 당당하구나. 항상 vs로 풀이하고 제출하는데, vs에서는 돌아가길래 아무 생각이 없었다.
void reverse(char arr[]) { // 문자열을 넘겨받아 뒤집어주기
char tmp;
// 뒤집는다==문자열의 반만 서로 순서를 뒤바꾸면 된다. (streln /2)
for (int i = 0; i < strlen(arr) /2; i++)
{
tmp = arr[i];
arr[i] = arr[strlen(arr) - i - 1]; // -1=='\0' 빼주기
arr[strlen(arr) - i - 1] = tmp;
}
}
숫자를 문자열로 입력받고 난 후, 뒤집어주는 부분은 함수로 만들었다.
넘겨받은 문자열의 반을 나눠 순서를 바꿔주면 되기 때문에 strlen(arr)/2가 범위가 된다. 굳이 예를 들자면 12345를 52341, 54321로 바꾸는 느낌??
main으로 돌아와 보자.
for (int i = 0; i < len; i++) {
num = a[i] - '0' + b[i] - '0' + carry;
while (num < 0)
num += '0';
if (num >= 10) carry = 1;
else carry = 0;
sum[i] = num % 10 + '0';
}
if (carry) sum[len] = '1';
a,b 둘 중 길이가 더 긴 문자열로 범위를 잡고, 거꾸로 돌린 이 문자열들을 맨 앞에서부터 더해 본다. 맨 앞이 숫자로 쳤을 때는 일의 자리가 되고, 일의 자리를 더했을 때 발생하는 올림 수는 carry로 저장한다.
a,b의 길이가 다른 경우에는 a, b 둘 중 하나가 null일 것이다. 그런데 -'0'이 하나가 더 들어가 있으니, 아스키 값 48이 한 번 더 빠져 num은 음수가 된다. 이런 상태를 방지하기 위해 num이 음수일 때는 양수로 만들어 준다.
둘 사이를 더해 올림수가 발생하면 이 수는 carry에 저장해 다시 for문을 돌 때 다음 num에 더해 올림수 역할을 해준다.
sum 배열에는 둘을 더한 값인 num의 일의 자리 숫자를 넣어준다.(%10)
for문을 나와 carry가 1일 때, 즉 마지막 올림 수도 고이 저장해주자.
이 모든 과정을 거치면 sum 배열을 다시 거꾸로 돌려 원래의 숫자로 만들고 출력하면 된다.