力扣12.整数转罗马数字

题目: 传送门
题意: 将一个数字转换成罗马数字,数字的转换,神奇而又充满了趣味。
首先:
在这里插入图片描述
然后在让我们看一下罗马数字的规则:

1、罗马数字的符号一共只有7个:I(代表1)、V(代表5)、X(代表10)、L(代表50)、C代表100)、D(代表500)、M(代表1,000)。这7个符号位置上不论怎样变化,它所代表的数字都是不变的。

2、一个罗马数字符号重复几次,就表示这个数的几倍。如:"III"表示"3""XXX"表示"30"3、在罗马数字的上方加上一条横线或者加上下标的M,表示将这个数乘以1000,即是原数的1000倍;同理,如果上方有两条横线,即是原数的100000010002)倍。

4、同一数码最多只能出现三次,如40不可表示为XXXX,而要表示为XL。由于IV是古罗马神话主神朱庇特(即IVPITER,古罗马字母里没有J和U)的首字,因此有时用IIII代替Ⅳ。

我要知道他的转化规则其实就是分别表示某一位,例如1994,表示的分别是1000、900、90、4,而不是1、9、9、4。现在我们知道规则了,并且题目中数字的范围是小于3999的,那么我们就可以进行转换了,我首先是暴力,数位分离,我们看代码:

#include<iostream>
using namespace std;
class Solution {
    
    
public:
	string intToRoman(int num);
};

string Solution::intToRoman(int num) {
    
    
	string s;
	int x = 1000;
	while (x) {
    
    
		int k = num / x;
		if (k == 0) {
    
    
			x /= 10;
			continue;
		}
		if (x == 1000) {
    
    
			for (int i = 1; i <= k; i++) {
    
    
				s.push_back('M');
			}
		}
		else if (x == 100) {
    
    
			if (k == 9) {
    
    
				s.push_back('C');
				s.push_back('M');
			}
			else if (k >= 5) {
    
    
				s.push_back('D');
				for (int i = 1; i <= k - 5; i++)
					s.push_back('C');
			}
			else if (k == 4) {
    
    
				s.push_back('C');
				s.push_back('D');
			}
			else  {
    
    
				for (int i = 1; i <= k; i++) {
    
    
					s.push_back('C');
				}
			}
		}
		else if (x == 10) {
    
    
			if (k == 9) {
    
    
				s.push_back('X');
				s.push_back('C');
			}
			else if (k >= 5) {
    
    
				s.push_back('L');
				for (int i = 1; i <= k - 5; i++)
					s.push_back('X');
			}
			else if (k == 4) {
    
    
				s.push_back('X');
				s.push_back('L');
			}
			else  {
    
    
				for (int i = 1; i <= k; i++) {
    
    
					s.push_back('X');
				}
			}
		}
		else {
    
    
			if (k == 9) {
    
    
				s.push_back('I');
				s.push_back('X');
			}
			else if (k >= 5) {
    
    
				s.push_back('V');
				for (int i = 1; i <= k - 5; i++)
					s.push_back('I');
			}
			else if (k == 4) {
    
    
				s.push_back('I');
				s.push_back('V');
			}
			else {
    
    
				for (int i = 1; i <= k; i++) {
    
    
					s.push_back('I');
				}
			}
		}
		num %= x;
		x /= 10;
	}
	return s;
}

int main() {
    
    
	int num;
	cin >> num;
	Solution s;
	cout << s.intToRoman(num) << endl;
	return 0;
}

但是我们能够发现,函数有很多重复的if,可以提取出来封装成一个函数,来使程序更加简洁。
我们看代码:

#include<iostream>
using namespace std;
class Solution {
    
    
public:
	string intToRoman(int num);
	void giegie(string& s, int k, char q, char z, char g);///s存放结果的字符串必须使用引用或者指针,我们希望能够保存更新结果
};

string Solution::intToRoman(int num) {
    
    
	string s;
	int x = 1000;
	while (x) {
    
    
		int k = num / x;
		if (k == 0) {
    
    
			x /= 10;
			continue;
		}
		if (x == 1000) {
    
    
			giegie(s, k, 'A', 'A', 'M');//没有5000,10000用A代替
		}
		else if (x == 100) {
    
    
			giegie(s, k, 'M', 'D', 'C');
		}
		else if (x == 10) {
    
    
			giegie(s, k, 'C', 'L', 'X');
		}
		else {
    
    
			giegie(s, k, 'X', 'V', 'I');
		}
		num %= x;
		x /= 10;
	}
	return s;
}

void Solution::giegie(string& s, int k, char q, char z, char g) {
    
    
	if (k == 9) {
    
    
		s.push_back(g);
		s.push_back(q);
	}
	else if (k >= 5) {
    
    
		s.push_back(z);
		for (int i = 1; i <= k - 5; i++)
			s.push_back(g);
	}
	else if (k == 4) {
    
    
		s.push_back(g);
		s.push_back(z);
	}
	else {
    
    
		for (int i = 1; i <= k; i++) {
    
    
			s.push_back(g);
		}
	}
	return ;
}
int main() {
    
    
	int num;
	cin >> num;
	Solution s;
	cout << s.intToRoman(num) << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43840681/article/details/117997510