[演算法][JavaScript]演算法挑战系列(6)-Integer to Roman

哈哈哈,先笑一下后开始文章,这次的题目虽然也是中级,不过就稍微简单一点(说不定是我脑子变灵活了XD),主要就是把数字转换成字串而已,如果有时间的话可以试试看,也可以顺便学一下关于罗马数字的知识(其实我做过就忘了XD)!那以下正文:

题目名称:Integer to Roman
难易度:中
题目内容:传入一个0~3999之间的数字,并依规则将其转为罗马数字的格式。
规则:
(1)对照表:

罗马数字数字I1V5X10L50C100D500M1000(2)罗马数字由大排到小。(3)2是由I+I所组成,875由D(500)+CCC(300)+L(50)+XX(20)+V(5)组成。(4)如果遇到4的话,不是显示为IIII,而是用5-1的方式写作IV,所以48的话会由XL(40)+V(5)+III(3)组成。(5)如果遇到9个话,不是显示为VIIII或VIV,而是用10-1的方式写作IX,所以496的话会由CD(400)+XC(90)+V(5)+I(1)组成。

PS.怕解释得不清楚,如果有可以改进的麻烦各位大大在留言告诉我。

例如:
1.传入1465会回传MCDLXV
2.传入3958会回传MMMCMLVIII

那以下是这次的解法:

var intToRoman = function (num) {    //用来装要回答的罗马字元    let strRoman = "";    //罗马字元,从小排到大,代表1的和代表5的分开    let arrRoman = ['I', 'X', 'C', 'M', 'V', 'L', 'D'];    //判断有几位数    let intLen = String(num).length-1;    //每位数个别处理    for (let i=intLen; i>=0 ; i--) {        /*取目前处理的数字,从大位数处理到小位数          String(num)[intLen-i]这个配合迴圈,          会从数字的最左边取到最右边*/        let nowNum = String(num)[intLen-i];        //如果小于4的话就直接用迴圈跑目前位数的罗马字元        if(nowNum<4){            for(let j=0; j<nowNum; j++){                strRoman += arrRoman[i];            };            continue;        };        //如果等于4的话就把目前位数的罗马字元和该位数代表5的罗马字元摆在一起        if(nowNum==4){            strRoman += arrRoman[i] + arrRoman[i+4];                continue;        };        //如果等于9的话就把目前位数的罗马字元和该位数再进位的罗马字元摆在一起        if(nowNum==9){            strRoman += arrRoman[i] + arrRoman[i+1];             continue;           };        /*如果大于4的话,就先填上该位数代表5的罗马字元,          再跑迴圈填入剩下个数的罗马字元*/        if(nowNum>4){            strRoman += arrRoman[i+4];             for(let j=0; j<nowNum-5; j++){                strRoman += arrRoman[i];            }        };        /*以上的if内都加上continue是因为for迴圈内由4个不同的if做处理,          所以就算他进入了第一个if也会跑其他3个判断,          因此考虑到效能问题,让他处理完后就继续下一次的迴圈,不再做多余的if判断,          加上continue也可以避免掉处理9的时候进入“nowNum==9”后又进入“nowNum>4”中作多余的处理*/    };    //处理完所有位数后回传    return strRoman;};

接着也分享一下这次的成绩,执行时间大概在152ms左右:
http://img2.58codes.com/2024/201069354FwNMgvjhh.jpg
然后我在讨论区中看到一个超级简洁的写法(怎么当初没有想到XD),一样我加上了注解,也让大家看看:
原解答网址

//先把各种状况存进阵列中const ROMANS = [    ["M", 1000],    ["CM", 900],    ["D", 500],    ["CD", 400],    ["C", 100],    ["XC", 90],    ["L", 50],    ["XL", 40],    ["X", 10],    ["IX", 9],    ["V", 5],    ["IV", 4],    ["I", 1]]var intToRoman = function(num) {    let result = "";    //直接去跑阵列的长度,从1000、900、500、400...处理到1    for (let i = 0; i < ROMANS.length; i++) {        //把这一次处理的数字放进变数中        let [ roman, n ] = ROMANS[i];        /*跑迴圈,如果num,比这次要处理的数字还大就继续跑,          如果num比较小就会跳出这次的迴圈,要处理的数字会慢慢变小,直到1*/        while (num >= n) {            //进入后先加上这次处理数字对应的罗马字元            result += roman;            //之后num就减掉处理过的数字,所以num会越来越小            num -= n;        }    }    //跑完后num会剩0,result也会是处理对应完的罗马字元    return result;};

看来我还是很难去解释别人的程式码http://img2.58codes.com/2024/emoticon13.gif,怎么打注解都觉得很奇怪,还请各位大大包容,再给我几次时间练习一定会进步的!这礼拜依然是熟悉的JavaScript,我也有在想下一次试着用别的语言解解看,不知道这样会不会比较有新奇感,哈哈哈,下礼拜没有意外的话,应该会分享SQL的题目转换个心情XD,也请各位大大如果文章中有提的不清楚的地方、手误或是哪里可以改得更好,也请留言告诉我,我都会儘速修改的!谢谢大家!http://img2.58codes.com/2024/emoticon41.gif

最后让我题外话推坑一下,最近看到还不错的活动:The F2E - 前端修练精神时光屋,主要是在练习前端和切版,每个礼拜都会出一道题目,让我们试着去做出相同的功能,当然如果没时间的话,最低标準就是完成单一页面就可以提交了!像这礼拜的题目是做个「todolist」,弱弱的我只来得及完成画面操作而已,还没有功能XD(以后有机会再分享),那这个活动会持续九个礼拜,也就是有九个题目,有兴趣的大大都可以进去看看!最后一个礼拜前都来得及哦!


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章