爱吃菠萝包 发表于 2025-5-22 22:14:13

每日一问?

num=[]
def words(I,V,X,L,C,D,M):
    roman
    _input=input('请输入一个罗马字符:').upper()
   
    for i in _input:
      num.append(i)

    if len(num)>=2:
      if num=='I':
            if num in ['V','X']:
                answer=roman_to_value(num)-I
            elif num in ['L','C']:
                answer=roman_to_value(num)-X
            elif num in ['D','M']:
                answer=roman_to_value(num)-C
            else:
                answer=roman_to_value(num)+roman_to_value(num)#感觉这串很多余,是否可以删掉?
      else:
            answer=roman_to_value(num)+roman_to_value(num)
    elif len(num)==1:
      answer=roman_to_value(num)
    else:
      answer=0

    print('转换后的结果是:',answer)
    return answer

def roman_to_value(char,roman_dict=None):#这下面一串就是AI改的了,感觉太复杂了,能不能改简单点?而且关键是我没看懂
    if roman_dict is None:
      roman_dict={'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
    return roman_dict.get(char,0)

words(I=1,V=5,X=10,L=50,C=100,D=500,M=1000)#这里不用对roman_to_value进行补充了吗?

#还有一个灵魂拷问:如果自己打出与小甲鱼给出答案不同的代码,那还要不要花时间去研究答案呢?

FishC 发表于 2025-5-22 22:15:04


罗马数字转换代码问题分析

主要问题:

[*]num= 未初始化为列表(应改为 num=[])
[*]if num=='I' 判断对象错误(num是列表,应该判断单个字符)
[*]roman_to_value() 多次错误传递列表参数(应该传单个字符)
[*]复杂的if-elif结构无法处理罗马数字减法规则(如IV=4,IX=9等)


优化后代码:

def roman_to_int(s):
    roman = {'I':1, 'V':5, 'X':10, 'L':50,
             'C':100, 'D':500, 'M':1000}
    total = 0
    prev_value = 0
   
    for char in reversed(s.upper()):
      value = roman.get(char, 0)
      if value < prev_value:
            total -= value
      else:
            total += value
      prev_value = value
   
    return total

print(roman_to_int('MCMXCIV'))# 测试输出1994


代码特点:

[*]逆向遍历字符串,简化减法规则判断
[*]使用字典直接查询字符值
[*]时间复杂度O(n),空间复杂度O(1)


关于灵魂拷问的回答:

[*]先自己测试代码的正确性(用各种边界值测试)
[*]对比不同实现的时间复杂度和可读性
[*]重点理解算法核心思想(如这里的减法规则实现方式)
[*]不同解法可能各有优劣,关键是掌握问题本质


小技巧:罗马数字转换核心规律是"当前字符值小于右边字符值时需要做减法",逆向遍历可以避免复杂的边界判断。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

爱吃菠萝包 发表于 2025-5-22 22:21:03

FishC 发表于 2025-5-22 22:15

罗马数字转换代码问题分析



优化固然是好,但你把我的思路改的面目全非,我都不认识了。那毫无成就感呀,所以能不能保留我的基本逻辑

xiaoniugogogo 发表于 2025-5-23 09:08:25

第一点: answer=roman_to_value(num)+roman_to_value(num)这行代码是用来处理输入为II的情况,不能删;
第二点:
def roman_to_value(char,roman_dict=None):#这个函数是将 字符型 按照 roman_dict 映射转成 整型 ;
    if roman_dict is None://如果没有 自定义字典 比如roman_to_value(‘I’),则 roman_dict 默认为下面的值;
      roman_dict={'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
    return roman_dict.get(char,0)//返回转化后的值,如果 char 不在字典中 返回0;
你也可以自定义一个map,如map={'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000},然后这样调用roman_to_value(‘I’,map);
第三:你这个处理不了长度为三及以上的罗马数字输入,如XXX,应该输出30但是你的输入是20。

爱吃菠萝包 发表于 2025-5-23 18:02:49

本帖最后由 爱吃菠萝包 于 2025-5-24 17:25 编辑

xiaoniugogogo 发表于 2025-5-23 09:08
第一点: answer=roman_to_value(num)+roman_to_value(num)这行代码是用来处理输入为II的情况,不能 ...

首先我问的是第17行,好像不是说输入为II的情况吧?还是我没理解
其次我没有看懂你的第二点哎
最后,那么大佬怎么改呀

xiaoniugogogo 发表于 2025-5-26 09:41:08

爱吃菠萝包 发表于 2025-5-23 18:02
首先我问的是第17行,好像不是说输入为II的情况吧?还是我没理解
其次我没有看懂你的第二点哎
最后, ...

你的这段代码当num和num都等于‘I’时就会跳到answer=roman_to_value(num)+roman_to_value(num)这,所以不是多余的;
if num=='I':
            if num in ['V','X']:
                answer=roman_to_value(num)-I
            elif num in ['L','C']:
                answer=roman_to_value(num)-X
            elif num in ['D','M']:
                answer=roman_to_value(num)-C
            else:
                answer=roman_to_value(num)+roman_to_value(num)#感觉这串很多余,是否可以删掉?
第二点简单说就是把单个罗马字符转成阿拉伯数字;
要改的话你就按AI给的答案吧,因为你转化逻辑是有问题的,你可以网上问一下AI罗马数字转阿拉伯数字的逻辑是怎样的
页: [1]
查看完整版本: 每日一问?