OOP-Addition römischer Zahlen (Eingabe- und Ausgabeüberladung + Typkonvertierung)

【id:287】【10分】G. OOP 罗马数字之加法(输入输出重载+类型转换)
时间限制
1s
内存限制
128MB
题目描述

罗马数字比阿拉伯数字早 2000 多年,起源于古罗马。它的产生标志着一种古代文明的进步。只是没有数字0。
其采用七个罗马字母作基本数字,即:I(1), V(5), X(10), L(50), C(100), D(500), M(1000)
记数的方法:
1. 相同的数字连写,所表示的数等于这些数字相加得到的数。如:III=3
2. 小数字在大数字的右边('大''小'),所表示的数等于这些数字相加得到的数。如:VIII=8
3. 小数字(仅限I,X和C)在大数字的左边('小''大'),所表示的数等于大数减小数得到的数。如:IX=9, CD=400
4. 在一个数的上面画一条横线,表示这个数增值1000倍。
组数规则: 
I,X,C,M 连写或放在大数左边不能超过3个:LIIII是非法的,应表示为 LIV (54)
I,X,C 放在大数左边只能用1个:CCM是非法的,应表示为 MCCC (800)
V,L,D 放在大数的右边只能用1个:CLL是非法的,应直接表示为 CC (200)
V,L,D 不能放在大数的左边:DM是非法的,应直接表示为 D (500)
此外,表示2900,不能写成CMMM,而应写成MMCM (因为CM(90)比M(100)小) 
表示900,不能写成DCD,而应写成CM (相比DCD,CM更简洁易算)
为避免打印横线,输入数据及运算结果范围保证为 [1,3999]
部分数字有两种写法,比如: 490(CDXC or XD)  3999(MMMCMXCIX or MMMIM) 等
本题采用较长的写法,即 CDXC(400+90) 等写法,而不是 XD(490) 写法 
整数[1,3999]转罗马数字方法如下:
using value_t = unsigned short;
/// 表1: 490 = CDXC (本题使用该表)
static const pair<value_t, string> valueSymbols[] = {
	{1000, "M"}, {900, "CM"},
	{ 500, "D"}, {400, "CD"},
	{ 100, "C"}, { 90, "XC"},
	{  50, "L"}, { 40, "XL"},
	{  10, "X"}, {  9, "IX"},
	{   5, "V"}, {  4, "IV"},
	{   1, "I"}
};
/// 表2: 490 = XD 
//static const pair<value_t, string> valueSymbols[] = {
//	{1000, "M"}, {999, "IM"}, {990, "XM"}, {900, "CM"},
//	{ 500, "D"}, {499, "ID"}, {490, "XD"}, {400, "CD"},
//	{ 100, "C"}, { 99, "IC"}, { 90, "XC"},
//	{  50, "L"}, { 49, "IL"}, { 40, "XL"},
//	{  10, "X"}, {  9, "IX"},
//	{   5, "V"}, {  4, "IV"},
//	{   1, "I"}
//};
/// 贪心, 处理罗马数字[1, 3999]
static string int2Roman(value_t num) {
	string roman;
	// for (const auto& [value, symbol] : valueSymbols) { // 8.1以上gcc编译器 
	//     for (; num >= value; num -= value) {
	//         roman += symbol;
	//     }
	//     if (num == 0) break;
	// } 
	for (int i=0; i<13; ++i) {
		value_t value = valueSymbols[i].first;
		string symbol = valueSymbols[i].second;
		for (; num>=value; num-=value) {
			roman += symbol;
		}
	}
	return roman;
}
1. 要求实现一个RomanNumber类,在"不重载" operator+ 方法的情况下实现RomanNumber的加法
2. 为RomanNumber对象重载输入输出
主函数如下: (不可修改) 
int main() {
	int n;
	cin >> n;
	while (n--) {
		RomanNumber ra, rb, rc;
		cin>>ra>>rb;
		rc = ra+rb;
		cout << ra <<'+'<< rb <<'='<< rc <<'('<< ra+rb <<')'<<endl;
	}
	return 0;
}

输入

第1行: 1个正整数n,表示测试次数 
以下n行: 每行两个正整数,用空格分隔

输出

(参见样例输出) 
对于每个测试用例,输出运算表达式(使用罗马数字表示)

样例查看模式 
正常显示
查看格式
输入样例1 <-复制
4
1 3
8 8
409 90
666 3333
输出样例1
I+III=IV(4)
VIII+VIII=XVI(16)
CDIX+XC=CDXCIX(499)
DCLXVI+MMMCCCXXXIII=MMMCMXCIX(3999)

Hier verwenden wir die Methode zum Konvertieren eines vorzeichenlosen Kurzschlusses in einen Konstruktor

Beim Überschreiben der Additionsoperation wird keine Klasse, sondern ein vorzeichenloser Kurzschluss zurückgegeben.

Hierbei ist zu beachten, dass bei der Klassenzuweisung nach der Operation und der Ausgabe nach der Operation die Auswirkungen der Addition oberflächlich betrachtet unterschiedlich sind.

Aber Sie können die Vielfalt der Konstrukteure nutzen

Die Additionsoperation des Ausgangs kann nicht geändert werden

Beim Überladen des Eingabeoperators >> muss ein Zeiger und keine Klassenvariable übergeben werden.

In RomanNumber &romanNumber müssen Sie das kaufmännische Und hinzufügen

Freund istream &operator>>(istream &in, RomanNumber &romanNumber) {

in >> romanNumber.value;

zurückkehren in;

}

Beim Überladen des Ausgabeoperators << kann & hinzugefügt werden oder nicht.

#include <iostream>
#include "map"

using namespace std;


class RomanNumber {
public:
    unsigned short value;
    using value_t = unsigned short;
/// 表1: 490 = CDXC (本题使用该表)
    static pair<value_t, string> valueSymbols[];

     RomanNumber(unsigned short value);

    RomanNumber();

/// 表2: 490 = XD
//static const pair<value_t, string> valueSymbols[] = {
//	{1000, "M"}, {999, "IM"}, {990, "XM"}, {900, "CM"},
//	{ 500, "D"}, {499, "ID"}, {490, "XD"}, {400, "CD"},
//	{ 100, "C"}, { 99, "IC"}, { 90, "XC"},
//	{  50, "L"}, { 49, "IL"}, { 40, "XL"},
//	{  10, "X"}, {  9, "IX"},
//	{   5, "V"}, {  4, "IV"},
//	{   1, "I"}
//};
/// 贪心, 处理罗马数字[1, 3999]
    static string int2Roman(value_t num) {
        string roman;
        // for (const auto& [value, symbol] : valueSymbols) { // 8.1以上gcc编译器
        //     for (; num >= value; num -= value) {
        //         roman += symbol;
        //     }
        //     if (num == 0) break;
        // }
        for (int i = 0; i < 13; ++i) {
            value_t value = valueSymbols[i].first;
            string symbol = valueSymbols[i].second;
            for (; num >= value; num -= value) {
                roman += symbol;
            }
        }
        return roman;
    }


    friend ostream &operator<<(ostream &out, RomanNumber romanNumber) {
        out << int2Roman(romanNumber.value);
        return out;
    }

    friend istream &operator>>(istream &in, RomanNumber &romanNumber) {
        in >> romanNumber.value;
        return in;
    }


    friend unsigned short operator+(RomanNumber one, RomanNumber two) {
        RomanNumber res(one.value + two.value);
        return one.value + two.value;
    }
};

pair<unsigned short, string> RomanNumber::valueSymbols[] = {
        {1000, "M"},
        {900,  "CM"},
        {500,  "D"},
        {400,  "CD"},
        {100,  "C"},
        {90,   "XC"},
        {50,   "L"},
        {40,   "XL"},
        {10,   "X"},
        {9,    "IX"},
        {5,    "V"},
        {4,    "IV"},
        {1,    "I"}
};

RomanNumber::RomanNumber(unsigned short value) : value(value) {}

RomanNumber::RomanNumber() {}


int main() {
    int n;
    cin >> n;
    while (n--) {
        RomanNumber ra, rb, rc;
        cin >> ra >> rb;
        rc = ra + rb;
        // cout << ra.value << endl;
        // cout << rb.value << endl;
        // cout << rc.value << endl;
        cout << ra << '+' << rb << '=' << rc << '(' << ra + rb << ')' << endl;
    }
    return 0;
}

Ich denke du magst

Origin blog.csdn.net/m0_62288512/article/details/131549992
Empfohlen
Rangfolge