12. Integer to Roman

Qi标准下的充电协议及其记忆技巧 记忆无线充电协议中的。 阅读详情

12. Integer to Roman
Difficulty: Medium

Given an integer, convert it to a roman numeral. Input is guaranteed
to be within the range from 1 to 3999.
给定一个整数,转化为罗马数字。输入的数字范围为1~3999.

重点
罗马数字与整数之间的转换规则:

  1. 左减右加,IV=4=5-1
  2. 左减不能跨越一个位数,99=90+9=XCIX(正确), =100-1=IC(错误)
  3. 左减不能超过1位,8=VIII(正确), =10-1-1=IIX(错误)
  4. 右加不能超过3位,14=10+4=XIV(正确), =10+1+1+1+1=XIIII(错误)
  5. 左减数字仅限于I,X,C,45=40+5=XLV(正确), =50-5=VL(错误)
  6. L不能左减I,D不能左减X,所以
    49=40+9=XLIX(正确), =50-1=IL(错误)
    490=400+90=CDXC(正确), =500-10=XD(错误)

解法1
缺点:逻辑复杂,不容易理解,代码冗长,特殊情况太多,不适用。

const int Count = 7;
const int roman[Count] = { 1, 5, 10, 50, 100, 500, 1000 };
const string str_roman[Count] = {"I","V","X","L","C","D","M"};

class Solution {
private:
    int CalcNums(int a);

public:
    string intToRoman(int num);
};

//计算并返回整数a的位数
int Solution::CalcNums(int a)
{
    int nums = 0;
    while (a > 0)
    {
        a /= 10;
        nums++;
    }
    return nums;
}
//整数转为罗马数字
string Solution::intToRoman(int num) 
{
    string str;
    if (num <= 0)
    {
        return str;
    }
    if(num==49)
    {
        return "XLIX";
    }
    else if(num==490)
    {
        return "CDXC";
    }
    int note = 0;
    int sign = 0;
    int temp;

    while (note < Count)
    {
        if (num <= roman[note])
            break;
        note++;
    }

    if (note == Count)  //大于1000,相加
    {
        sign = 1;
    }
    else if (num == roman[note])  //已经找到
    {
        str = str_roman[note];
        return str;
    }

    if (roman[note] - roman[note - 1] > num) //减一次仍太大(左减不能超过1位),只能相加
    {
        sign = 1;
    }

    if (sign == 0)  //相减
    {
        temp = roman[note] - num;
        for (int k = note - 1; k >= 0; k--)
        {
            if (temp == roman[k])
            {
                int n1 = CalcNums(roman[note]);
                int n2 = CalcNums(roman[k]);
                if ((n1 - n2 > 1)||(k!=0 && k!=2 && k!=4))  //左减不能跨越一个位数,左减的数字仅限于I、X、C,否则只能相加
                {
                    sign = 1;
                    break;
                }
                else
                {
                    str = str_roman[k];
                    str += str_roman[note];
                    return str;
                }               
            }
            else if (temp > roman[k]) //找不到可以左减的值,只能相加
            {
                sign = 1;
                break;
            }
        }
    }
    if (sign == 1) //相加
    {
        int k = 0;
        temp = num;     
        while (k < 3)   //检查是否可由相同数字相加得到(右加不能超过3位)
        {
            temp -= roman[note - 1];
            k++;
            if (temp < 0)
                break;
            if (temp == 0)
            {
                for (int i = 0; i < k; i++)
                {
                    str += str_roman[note - 1];
                }
                return str;
            }
        }
        int n = CalcNums(num);   //不同数字相加
        if (n == 1)  //只有1位,整数6-8
        {
            str = "V";
            num -= 5;
            while (num > 0)
            {
                str += "I";
                num--;
            }
        }
        else   //两位以上
        {
            int sep1;
            int sep2;
            temp = num % (int)pow(10, n - 1);
            if (temp == 0)
            {
                sep1 = roman[note - 1];
                sep2 = num - sep1;
                str = str_roman[note - 1];
                str += intToRoman(sep2);  //递归
            }
            else
            {
                sep2 = num % (int)pow(10, n - 1);  //分成两部分
                sep1 = num - sep2;
                str = intToRoman(sep1);  //递归
                str += intToRoman(sep2);  //递归
            }                   
        }
        return str;
    }
    return str;
}

解法2
优点:逻辑清晰,简洁
思路:化减为加

基本数字:
I—-1
V—5
X—10
L—50
C—100
D—500
M—1000

根据规则2,3,5,6,可以左减的搭配为
IV—-4
IX—-9
XL—40
XC—90
CD—400
CM—900

扩展为13个基本数字,且基本数字之间组合相加可以得到结果,不需要再考虑相减的情况。
根据贪心算法,每次求最优解,每次匹配最大值

class Solution {
public:
    string intToRoman(int num);
};

const int roint[13]={1000,900,500,400,100,90,50,40,10,9,5,4,1};  //化减为加
const string rostr[13]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
string Solution::intToRoman(int num)
{
    string ret;
    int i=0;
    //贪心算法,每次匹配最大值
    while(num>0)
    {
        if(num>=roint[i])
        {
            num-=roint[i];
            ret+=rostr[i];
        }
        else
        {
            i++;
        }
    }
    return ret;
}

问题扩展:罗马数字转数字,范围为1~3999。
(另外一篇博客有过解答,这里提供更简洁的方法)
思路:比右边大,为 +;比右边小,为 - 。

class Solution {
private:
    int funTrans(char c);
public:
    int romanToInt(string s) {

        int num=0;
        int i;
        for(i=0;i<s.size()-1;i++)
        {
            if(funTrans(s[i])>=funTrans(s[i+1]))  //比右边大,为+
            {
                num+=funTrans(s[i]);
            }
            else                                  //比右边小,为 -
            {
                num-=funTrans(s[i]);
            }
        }
        num+=funTrans(s[i]);
        return num;
    }
};

int Solution::funTrans(char c)   //也可以用hash表代替
{
    int num;
    switch(c)
    {
        case 'I':return 1;
        break;
        case 'V':return 5;
        break;
        case 'X':return 10;
        break;
        case 'L':return 50;
        break;
        case 'C':return 100;
        break;
        case 'D':return 500;
        break;
        case 'M':return 1000;
        break;
        default:return 0;
    }
}
《open3D+pyqt》点云读取、显示与保存 《open3D+pyqt》第一章:点云读取与显示一、效果展示二、环境配置三、代码3.1 qt designer设置3.2 生成ui,qrc的py文件3.3 py文件代码 一、效果展示 二、环境配置 环境配置:Anconda+pycharm+pyqt+open3d+pyqtgraph 显示界面:这里选择pyqtgraph 参考网上教程 三、代码 3.1 qt designer设置 界面布局参照《PCL+QT》教程,界面设置:布局如下: 布局参数参考: 3.2 生成ui,qrc的py文件 3.3 py 阅读详情

相关推荐

智能体在车联网中的应用:第19天 智能体理论与初步实践 D30:阶段小结——在SUMO中使用TraCI控制预编程智能体

本文介绍了如何将强化学习从算法仿真迁移到交通系统实践,重点讲解了SUMO微观交通仿真平台与TraCI实时控制接口的架构。通过构建一个预编程驾驶智能体,演示了车辆从起点到目标点的导航控制。文章详细解析了TraCI的双向通信机制和事件驱动模型,对比了其与传统RL环境的差异,并提供了完整的Python实现框架,包括路网配置、车辆控制和基于向量场的导航逻辑。该实践为后续开发高级学习型交通智能体奠定了基础。

IT深耕十余载,大道之简 1478

LeetCode 12 Integer to Roman题解

题目地址: https://leetcode.com/problems/integer-to-roman/ 题目: Given an integer, convert it to a roman numeral. 给定一个数,将它转化为罗马数值。 Input is guaranteed to be within the range from 1 to 3999.

赞美月亮的专栏 634

GPU服务器选购避坑指南:从硬件配置到场景化性能调优

本文提供GPU服务器选购的全面指南,涵盖硬件架构解析、应用场景配置策略和性能调优实践。针对大模型训练、推理服务和科学计算等场景,详细分析GPU选型、内存带宽匹配和散热设计等关键因素,帮助技术决策者避免常见配置误区,实现成本效益最大化。

peace的博客 1030

12、Integer to Roman

解法一 /** * @param {number} num * @return {string} */ var intToRoman = function(num) {     let roman='';     if(Math.floor(num/1000) &gt;=1 ){ // 比1000大         for (let i=0;i&lt;Math.floor(num/1000);i...

sunmagine的博客 215

如何在iPhone上本地运行SmolVLM?5亿参数模型实战指南(附Swift代码)

本文详细介绍了如何在iPhone上本地部署和运行轻量高效的SmolVLM多模态模型。通过实战指南,分享了使用Swift和MLX框架进行环境配置、模型加载、内存优化以及实现实时图像分析与文本生成的完整流程,帮助开发者在移动端高效运行AI视觉语言模型。

echo99的专栏 654

新手小白 必须精进的 “ FLASH分区管理Code and Data ” !!!最强文章解析!!!

FLASH“代码区”和“数据区”不是每个项目都必须显式管理,但只要你的产品功能越来越丰富,对可靠性和扩展性要求提高,就一定要学会科学划分和使用。这也是嵌入式工程师进阶路上的必修课!

qq_75157958的博客 933

12. Integer to Roman。

今天刚开始看《数学之美》在其中有提到数字的起源,当看到关于罗马数字的介绍,终于解开了多年的困惑,为什么IV是4而VI是5。。。之前一直是死记硬背的,现在终于搞明白了缘由。书中的介绍:但其中介绍的也并不是很详细,以下内容摘自百度百科: (1)相同的数字连写、所表示的数等于这些数字相加得到的数、如:Ⅲ=3; (2)小的数字在大的数字的右边、所表示的数等于这些数字相加得到的数、 如:Ⅷ=8、Ⅻ=

繁城落叶 566

OpenRubrics:自动化评估工具优化LLM对齐效果

在大型语言模型(LLM)应用中,模型输出与人类价值观的对齐是关键挑战。传统人工反馈强化学习(RLHF)依赖大量标注,成本高且一致性差。OpenRubrics作为开源工具,通过结构化准则实现自动化评估,显著提升效率。其核心原理是将主观评价转化为可量化的多维指标,支持动态权重调整,并兼容主流RLHF框架。该工具在降低标注成本的同时,通过Fleiss' Kappa系数等指标保证评估一致性,适用于多语言和医疗等专业领域,为LLM对齐提供了工程化解决方案。

weixin_28730037的博客 358

[LeetCode] 12. Integer to Roman

Given an integer, convert it to a roman numeral.Input is guaranteed to be within the range from 1 to 3999.枚举。。class Solution { private String getThousand(int thousands){ switch (thousands)...

Nayido的博客 268

C#的GDI+绘图详解

/消除锯齿 或 AntiAlias。// 1.在窗体或控件的Paint事件中,用PaintEventArgs e 创建绘图对象 ---- 控件或窗体重绘时。//为控件创建绘图对象。//--------------------以上方法三选一。//2.创建绘图对象 panel1中绘图。

weixin_50920631的博客 3457

UNet改进(12):融合小波变换与注意力机制的图像分割新方法

本文提出了一种改进的WaveletAttentionUNet架构,通过结合小波变换和注意力机制来增强传统UNet的多尺度特征提取能力。该网络使用分组卷积模拟小波分解,将输入通道扩展为4个子带(LL、LH、HL、HH),并通过通道注意力机制自适应加权各子带特征。网络保留了UNet的编码器-解码器结构,在关键位置集成了WaveletAttention模块。实验证明该方法在医学图像分割等任务中能更好地保持边缘细节和复杂纹理特征,同时保持计算效率。

2501_91516851的博客 758

leetcode 12 Integer to Roman

数字转换为罗马数字

ghoshorn的专栏 403

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

LeetCode12题——integer to roman

问题描述 oman numerals are represented by seven different symbols: I, V, X, L, C, D and M. Symbol Value I 1 V 5 X 10 L 50 C 100 D ...

apollo_steve的博客 305

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

LeetCode 12. Integer to Roman

LeetCode 12.Integer to Roman

sophie__的博客 300

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【12】Integer to Roman

按9 5 4 1一点一点减 string intToRoman(int num) { string res=""; int c=num/1000; res+=string(c,'M'); num-=(c*1000); if(num>=900){res+="CM";num-=900;} else if(num>=500){res+="D";num-=

LSbiubiubiu的博客 438

12 Integer to Roman

1 题目 Roman numerals are represented by seven different symbols:I,V,X,L,C,DandM. Symbol Value I 1 V 5 X 10 L 50 C 100 D ...

weixin_39145266的博客 128

12. Integer to Roman 13. Roman to Integer

12. Integer to Roman 题目描述 Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. Symbol Value I 1 V 5 X 10 L 50 C ...

qq_39029148的博客 150
上一篇: 38. Count and Say
下一篇: 2. Add Two Numbers
cyndi2011
博客等级 码龄13年 38粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值