본문 바로가기

컴퓨터/알고스팟 알고리즘

알고스팟 알고리즘: XHAENEUNG [C++]

문제 출처: https://algospot.com/judge/problem/read/XHAENEUNG

 

algospot.com :: XHAENEUNG

째능 교육 문제 정보 문제 산업 기능 요원 복무를 무사히 마치고 학교로 돌아온 xhae는 최근 복학을 위한 많은 지출로 인해 자금난에 허덕이고 있었다. 이러한 xhae가 선택한 일은 다름 아닌 째능

algospot.com

1. 코드

#include <iostream>
#include <string>

using namespace std;

string arabiaToeng(int n)
{
	string r;
	if (n == 0) r = "zero";
	else if (n == 1) r = "one";
	else if (n == 2) r = "two";
	else if (n == 3) r = "three";
	else if (n == 4) r = "four";
	else if (n == 5) r = "five";
	else if (n == 6) r = "six";
	else if (n == 7) r = "seven";
	else if (n == 8) r = "eight";
	else if (n == 9) r = "nine";
	else if (n == 10) r = "ten";
	return r;
}
int arabia(string s)
{
	int r;
	if (s == "zero") r = 0;
	else if (s == "one") r = 1;
	else if (s == "two") r = 2;
	else if (s == "three") r = 3;
	else if (s == "four") r = 4;
	else if (s == "five") r = 5;
	else if (s == "six") r = 6;
	else if (s == "seven") r = 7;
	else if (s == "eight") r = 8;
	else if (s == "nine") r = 9;
	else if (s == "ten") r = 10;
	return r;
}

int operation(int a, int b, char op)
{
	int r;
	switch (op)
	{
	case '+':
		r = a + b;
		break;
	case '-':
		r = a - b;
		break;
	case '*':
		r = a * b;
		break;
	default:
		break;
	}
	return r;
}
int main(void)
{
	int t;
	cin >> t;

	while (t--)
	{
		string A, B, result, com;
		char op, temp;
		int a, b;
		cin >> A >> op >> B >> temp >> result;
		a = arabia(A);
		b = arabia(B);
		a = operation(a, b, op);
		com = arabiaToeng(a);
		if (com.length() != result.length() || (a < 0 && a > 10))
		{
			cout << "No" << endl;
			continue;
		}
		int cnt = 0;
		int memo[10];
		for (int i = 0; i < com.length(); i++)
		{
			for (int j = 0; j < result.length(); j++)
			{
				int k = -1;
				for (int q = 0; q < i; q++) {
					if (memo[q] == j) 
					{
						k = j;
						break;
					}
				}
				if (k == j) {
					continue;
				}
				if (com[i] == result[j])
				{
					memo[i] = j;
					cnt++;
					break;
				}
			}
		}
		if (cnt == com.length()) cout << "Yes" << endl;
		else cout << "No" << endl;
	}
}

(실행)

2. 풀이

1. 문자열로 입력받은 피연산자들을 숫자로 변환시켜서 저장합니다.
2. 연산자에 맞게 연산을 진행합니다.
3. 연산 결과를 문자열로 변환시켜줍니다.
4. 연산 결과의 문자열과 처음 입력했던 결과를 예측한 문자열과 길이를 비교 후 같지 않거나 결괏값이 0 이하 10을 초과할 경우 No라는 메시지를 출력합니다.
5. 길이가 같다면 두 문자열의 값이 전부 존재하는지 확인 후 존재한다면 Yes 아니라면 No 메시지 출력합니다.

string A, B, result, com;
char op, temp;
int a, b;
cin >> A >> op >> B >> temp >> result;
a = arabia(A);				//수로 변환
b = arabia(B);
a = operation(a, b, op);	//연산 진행
com = arabiaToeng(a);		//결과값 문자열로 변환

피연산자들을 아라비아 숫자로 변환한 후 입력한 연산자에 맞추어 연산을 진행한 뒤 해당 연산 결과를 영어로 다시 변환한다.

if (com.length() != result.length() || (a < 0 && a > 10))	//길이가 다르거나 값이 초과했을 경우
{
	cout << "No" << endl;
	continue;
}

계산을 통해 구한 결과와 입력한 결과의 길이가 동일하지 않거나 계산 결과 0 미만이고 10 초과라면 No 메시지를 출력한다.

int cnt = 0;
int memo[10];	//j값 중복 방지
for (int i = 0; i < com.length(); i++)
{
	for (int j = 0; j < result.length(); j++)
	{
		int k = -1;
		for (int q = 0; q < i; q++) {
			if (memo[q] == j)		//이미 전에 j값과 같은 값을 인식했을 경우
			{
				k = j;
				break;
			}
		}
		if (k == j) continue;		//해당 j 제외
		if (com[i] == result[j])	//같은 문자일 경우
		{
			memo[i] = j;			//현재 위치의 j값 저장(중복 방지)
			cnt++;					//같은 값이 몇개인지 확인
			break;
		}
	}
}

memo 배열은 같은 위치에 있는 문자를 비교하는 것을 방지하는 용도이며 이중 반복문을 통해 계산으로 구한 결과와 입력에 의한 결과에 동일한 문자가 존재하는지 확인하는 작업을 진행한다.

먼저 해당 위치를 검사한 적인 있는지 확인 후 있다면 다른 문자 요소로 넘어가고 그렇지 않다면 같은 문자인지 확인을 해주며 만약 같다면 memo에 체크를 해주고 cnt 값을 증가시킨다.

if (cnt == com.length()) cout << "Yes" << endl;	//같은 값이 문자열 길이와 동일하다면
else cout << "No" << endl;

문자열을 전부 비교 후 동일한 문자의 개수가 계산에 의한 결과의 길이가 동일한 경우 Yes를 출력 후 아니라면 No를 출력해준다.

3. 느낀점

코드를 더 간결하게 만들 수 있을 것 같지만 아직 실력이 부족하여 길어진 것 같아 조금 더 노력해야겠다.