본문 바로가기
Programming/C++ - 백준

[백준] 8958번 : OX퀴즈 & 문자열, 배열의 길이 오류 - (C++)

by 지구코드 2023. 4. 20.
반응형


문제


첫 번째 풀이 - 출력값 이상 & 오류 발생

 

#include <iostream>
#include <string>
using namespace std;

int main() {
	int accumulate = 0;
	int T, score = 0;
    	char arr[80];
	cin >> T;

	while (T--) {
		accumulate = 0;
		score = 0;
		int size = 0;

		cin >> arr;
		size = (sizeof(arr) / sizeof(*arr));

		for (int i = 0; i < size; i++) {
			if (arr[i] == 'O') {
				accumulate++;
				score += accumulate;
			}
			else if (arr[i] == 'X') {
				accumulate = 0;
			}
		}

		cout << score << endl;
	}
}

 

① int형의 변수인 accumulate, T, score을 선언하고, char형의 배열인 arr을 선언한다.

 

     accumulate는 O이 반복될 때, 누적 점수를 위한 변수이다.

 

② 테스트케이스 T를 입력받은 후, for문 혹은 while문을 이용해 연산을 반복한다.

 

     이 때, accumulate와 score을 0으로 초기화시켜줘야 한다.

 

③ 다음으로, 변수 size를 선언한 후, 배열의 크기를 for문의 종료문으로 설정해주었다.

 

      (이 때, 문자열의 길이가 아닌, 배열의 크기로 하여 오류가 발생했다.)

 

	int size = (sizeof(arr) / sizeof(*arr));

	for (int i = 0; i < size; i++) {

	}

 

④ for문과 if문을 이용해, O일 경우에는 accumulate를 증가시키고, score에 더하여, 점수를 증가시켰다.

 

    X일 경우에는, 점수가 없기 때문에, accumulate를 0으로 초기화시켰다.

 

		for (int i = 0; i < size; i++) {
			if (arr[i] == 'O') {
				accumulate++;
				score += accumulate;
			}
            
			else if (arr[i] == 'X') {
				accumulate = 0;
			}
		}

 


※ 하지만, 예제를 입력해보았을 때, 아래와 같은 오류가 발생했다.

 

    'OOOOOOOOOO' 예제를 입력하면, 55가 아닌 56이 도출되는 것이였다.

 

(왼쪽) 예제 (오른쪽) 코드 실행 결과

 

    앞의 예제 없이 'OOOOOOOOOO'만 입력하는 경우에는 55라는 정확한 값이 도출되었다.

 

 

    따라서, 코드를 조금 수정하여, 디버깅을 해보았더니, i = 9에서 끝나야 하지만 더 이어지고 있음을 확인 할 수 있었다.

 

노란 체크 부분에서 오류가 발생함.


★ 오류 해결

 

 → 잘못된 출력값이 도출된 이유는 for문의 종료조건을 '배열의 크기'로 했기 때문이였다.

 

 → 문자열의 끝에는 항상 null 문자('\0')가 들어간다.

 

 → char arr[80]로 선언한다면, 80은 문자열의 길이가 아닌 배열의 크기이다. 

 

 →  만약, 문자열의 길이가 배열의 크기보다 짧다면, null 문자를 넘어선 공간에 접근하게 된다.

 

 → 이전에 다른 문자열을 입력받았다면, 그 내용이 초기화되지 않고, 그대로 남아있을 수 있다. 

 

 → 따라서, null 문자가 출력이 되는 경우에도 오류가 발생하고, 이전에 입력받은 다른 문자열로 인해 오류가 발생할 수도 있다.

 

 → 결론: arr에 저장된 문자열을 한 문장씩 확인하기 위해서는 아래와 같이 '문자열의 길이'를 for문의 종료조건으로 해주는 것이 올바른 방법이다.

 

for (int i = 0; arr[i] != '\0'; i++){
	cout << arr[i];
}

for (int i = 0; arr[i]; i++){
	cout << arr[i];
}

  문제를 해결하며 참고한 글을 첨부합니다.

코드 - 정답

#include <iostream>
#include <string>
using namespace std;

int main() {
	int accumulate = 0;
	int T, score = 0;
    	char arr[80];
	cin >> T;

	for (int i = 0; i < T; i++) {
		accumulate = 0;
		score = 0;
		cin >> arr;

		for (int j = 0; arr[j]; j++) {

			if (arr[j] == 'O') {
				accumulate++;
				score += accumulate;
			}
			else {
				accumulate = 0;
			}
		}

		cout << score << endl;
	}
}

결과

 

 

8958번: OX퀴즈

"OOXXOXXOOO"와 같은 OX퀴즈의 결과가 있다. O는 문제를 맞은 것이고, X는 문제를 틀린 것이다. 문제를 맞은 경우 그 문제의 점수는 그 문제까지 연속된 O의 개수가 된다. 예를 들어, 10번 문제의 점수

www.acmicpc.net

 

반응형

댓글