整数转罗马数字

力扣第12题:整数转罗马数字

题目描述

罗马数字由七种字符组成:I(1),V(5),X(10),L(50),C(100),D(500)和 M(1000)。例如,数字 2 写作 II ,即为两个并列的 1。数字 12 写作 XII ,即为 X + II 。数字 27 写作 XXVII ,即为 XX + V + II

现代的罗马数字在一些特定的规则下,允许用一些较小的数字放在较大的数字前面表示差值。例如:

  • 数字 4 写作 IV ,即 V - I
  • 数字 9 写作 IX,即 X - I

给定一个整数,将其转换为罗马数字。

示例

示例 1:

输入: num = 3
输出: "III"

示例 2:

输入: num = 1994
输出: "MCMXCIV"
解释: 1994 = 1000 + 900 + 90 + 4,因此 MCMXCIV 表示 1994。

解题思路

罗马数字的转换可以通过“贪心算法”来完成:从最大值的罗马字符开始匹配,尽可能多地减去当前值,并将对应的罗马数字拼接到结果中,直到整数转换完成。为了实现这一过程,我们首先需要定义罗马数字符号及其对应的数值。通过循环匹配符号并更新输入数字,直到将所有的数字转换为罗马数字。

步骤解析

  1. 罗马数字符号与数值的映射:将所有的罗马数字及其对应的数值以数组形式存储,并按从大到小的顺序排列,以便从大到小依次匹配。

  2. 贪心算法:从最高数值开始,逐步减去该数值,并将对应的罗马符号添加到结果字符串中。

  3. 拼接结果:使用 strcat 函数将罗马符号拼接到结果字符串中,直到所有的数字都转换完毕。

代码实现

#include <stdio.h>
#include <string.h>

char* intToRoman(int num) {
    // 定义罗马数字符号及其对应值
    char* roman_symbols[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
    int values[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
    
    // 定义用于存储结果的字符串
    static char result[20];
    int i = 0;
    result[0] = '\0'; // 初始化字符串为空
    
    // 依次匹配每个罗马数字符号
    while (num > 0) {
        while (num >= values[i]) {
            strcat(result, roman_symbols[i]);
            num -= values[i];
        }
        i++;
    }
    
    return result;
}

int main() {
    int num = 1994;
    printf("Roman numeral for %d is: %s\n", num, intToRoman(num));  // 输出: MCMXCIV
    return 0;
}

代码解释

  1. intToRoman 函数

    • 使用两个数组存储罗马数字符号与对应的数值,并确保它们按从大到小的顺序排列,以便每次都能匹配到最大的数值。
    • 通过 while 循环,当输入数字 num 大于等于当前值时,将该值从 num 中减去,并将对应的罗马字符添加到结果字符串中。
  2. strcat 函数

    • 用于拼接字符串。在每次匹配到罗马数字时,将其符号添加到最终结果中。
  3. 主函数

    • 测试 intToRoman 函数,并输出对应的罗马数字。

优化思路

该算法使用了贪心思想,即每次优先匹配大的数值,并逐步减少输入的数字。由于罗马数字的表示是有限且规则的,该算法的效率很高。时间复杂度为 O(1),因为我们最多需要遍历13个不同的罗马符号,且每个符号的匹配次数是有限的。

总结

这道题通过贪心算法有效地将整数转换为罗马数字。利用符号与数值的对应关系,并结合循环和字符串拼接操作,可以轻松实现题目要求的转换。该算法具有较好的时间和空间复杂度,适用于绝大多数整数转罗马数字的场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值