Ajout de chiffres romains POO (surcharge d'entrée et de sortie + conversion de type)

【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)

Ici, nous utilisons la méthode de conversion d'un short non signé en constructeur

Lors de la substitution de l'opération d'addition, ce qui est renvoyé n'est pas une classe, mais un short non signé.

Ce qu'il faut noter ici, c'est que dans l'attribution de classe post-opération et dans la sortie post-opération, les effets de l'addition sont différents en surface.

Mais vous pouvez profiter de la diversité des constructeurs

L'opération d'addition de la sortie ne peut pas être modifiée

Lors de la surcharge de l'opérateur d'entrée >>, ce qui doit être transmis est un pointeur, pas une variable de classe.

Dans RomanNumber &romanNumber, vous devez ajouter l'esperluette

ami istream &opérateur>>(istream &in, RomanNumber &romanNumber) {

dans >> romanNumber.value;

rentrer;

}

Lors d'une surcharge, l'opérateur de sortie <<, & peut être ajouté ou non.

#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;
}

Je suppose que tu aimes

Origine blog.csdn.net/m0_62288512/article/details/131549992
conseillé
Classement