罗马数字与阿拉伯数字相互转换
来源:互联网 发布:日本留学融入 知乎 编辑:程序博客网 时间:2024/05/19 18:42
罗马数字规则简明
1. 罗马单个数字共有7个,即I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000)
2.一个罗马数字重复几次,就表示这个数的几倍。但同一数码不能出现三次以上。
3.遵循右加左减的规则。
左减的数字有限制,仅限于I、X、C。比如45不可以写成VL,只能是XLV
但是,左减时不可跨越一个位数。比如,99不可以用IC(100 - 1)表示,
而是用XCIX([100 - 10] + [10 - 1])表示。(等同于阿拉伯数字每位数字分别表示。)
左减数字必须为一位,比如8写成VIII,而非IIX。
Roman to Int
基本思路:把输入的罗马数字分段处理,分段相加。从左到右,一个个检测过去。
设置 当前位current,上一位pre,分段值temp。
如果当前位对应的值和上一位的一样(current == pre),那么分段值加上当前值{temp += current;}。比如III = 3
如果当前位对应的值大于上一位的(current > pre),说明分段值应该是当前值减去现有的分段值{temp = current - temp;}。比如IIV = 5 – 2
如果当前位对应的值小于上一位的(current < pre),那么可以先将当前分段值加到结果中,重新开始记录分段值{result += temp;temp = current;}。比如XI = 10 + 1
Int to Roman
思路是把数字拆成单独的部分,最后拼接起来
1. 判断输入数字共有几位,digits
2. 拆分数字,把每一位数字存入数组singleInt[i]中
3. 把每位数字单独转换singleDigitToRoman成罗马数字,存入罗马数字数组singleRoman[i]中
4. 最后拼接起来result.append(singleRoman[i])
单独转换方法singleDigitToRoman(int n, int nth)接收2个参数,一个是输入数字,一个是当前数字的位数
singleDigitToRoman方法中,把罗马数字单个存放在char数组里,方便调用
char singleRoman[] = {'I','V','X','L','C','D','M','Z','E'}; // never use 'Z' & 'E'
数组中'Z' 和 'E'都只是用来占位的,避免数组越界;正常情况下都不会出现
根据输入数字n,分段判断;每段有不同的拼接方式
假设输入数字的范围1~3999,以下是完整的Java代码
1 /** 2 * @author Rust Fisher 3 * Reverse number to Roman or reverse Roman to number 4 */ 5 public class RomanAndInt { 6 /** 7 * @param s - String Roman 8 * @return int number 9 */ 10 public static int romanToInt(String s) { 11 if (s.length() < 1) return 0; 12 int result = 0; 13 int current = 0; 14 int pre = singleRomanToInt(s.charAt(0)); 15 int temp = pre; 16 for (int i = 1; i < s.length(); i++) { 17 current = singleRomanToInt(s.charAt(i)); 18 if (current == pre) 19 temp += current; 20 else if (current > pre){ 21 temp = current - temp; 22 } 23 else if (current < pre){ 24 result += temp; 25 temp = current; 26 } 27 pre = current; 28 } 29 result += temp; 30 return result; 31 32 } 33 /** 34 * @param c single Roman 35 * @return single number 36 */ 37 public static int singleRomanToInt(char c){ 38 switch (c) { 39 case 'I': 40 return 1; 41 case 'V': 42 return 5; 43 case 'X': 44 return 10; 45 case 'L': 46 return 50; 47 case 'C': 48 return 100; 49 case 'D': 50 return 500; 51 case 'M': 52 return 1000; 53 default: 54 return 0; 55 } 56 } 57 /** 58 * @param n - input single int 59 * @param nth must start from 1; 1 <= nth <= 4 60 * @return String single Roman 61 */ 62 public static String singleDigitToRoman(int n, int nth){ 63 if (n == 0) { 64 return ""; 65 } 66 nth = 2 * nth - 1; // nth must start from 1 67 char singleRoman[] = {'I','V','X','L','C','D','M','Z','E'}; // never use 'Z' & 'E' 68 StringBuilder rsb = new StringBuilder(""); 69 if (n <= 3) { 70 for (int i = 0; i < n; i++) { 71 rsb.append(singleRoman[nth-1]); 72 } 73 return rsb.toString(); 74 } 75 if (n == 4) { 76 rsb.append(singleRoman[nth-1]); 77 rsb.append(singleRoman[nth]); 78 return rsb.toString(); 79 } 80 if (n == 5) { 81 return singleRoman[nth] + ""; 82 } 83 if (n >= 6 && n <= 8) { 84 rsb.append(singleRoman[nth]); 85 for (int i = 0; i < (n - 5); i++) { 86 rsb.append(singleRoman[nth-1]); 87 } 88 return rsb.toString(); 89 } 90 if (n == 9) { 91 rsb.append(singleRoman[nth-1]); 92 rsb.append(singleRoman[nth+1]); 93 return rsb.toString(); 94 } 95 return "ERROR!!!"; 96 } 97 /** 98 * @param num - input number within range 1 ~ 3999 99 * @return String Roman number100 */101 public static String intToRoman(int num) {102 if (num < 1 || num > 3999) {103 return "ERROR input number is 1 ~ 3999";104 }105 int temp = num;106 String singleRoman[] = {"","","",""};107 StringBuilder result = new StringBuilder("");108 int digits = 0; // 1 ~ 4109 while (temp != 0){110 temp = temp/10;111 digits++;112 }113 temp = num;114 int[] singleInt = new int[digits];115 for (int i = 0; i < digits; i++) {116 singleInt[i] = temp%10;117 singleRoman[i] = singleDigitToRoman(temp%10,i+1);118 temp /= 10;119 }120 for (int i = digits-1; i >= 0; i--) {121 result.append(singleRoman[i]);122 }123 return result.toString();124 }125 /**126 * test main127 */128 public static void main(String args[]){129 for (int i = 0; i < 4; i++) {130 int input = (int) (Math.random()*Math.pow(10, i+1));131 if (input > 3999) {132 input = 3999;133 }134 System.out.println(input + " = " + intToRoman(input));135 }136 }137 }
小结
转换的思路在于截取数字,一位一位来处理,最后拼接或相加得到结果
这两个过程都用到了处理单个数字的方法;化整为零,循环处理整个数字;把处理细节的方法封装起来,便于调用
- 罗马数字与阿拉伯数字相互转换
- 罗马数字与阿拉伯数字的相互转换
- 罗马数字与阿拉伯数字的相互转化
- Python 罗马数字与阿拉伯数字的转换
- 经典题:罗马数字和阿拉伯数字的相互转换
- Java经典题:罗马数字和阿拉伯数字的相互转换
- 罗马数字转换成阿拉伯数字
- 罗马数字转换为阿拉伯数字
- 阿拉伯数字转换成罗马数字
- 阿拉伯数字转换成罗马数字
- 罗马数字转换成阿拉伯数字
- 对一个罗马数字与阿拉伯数字转换算法的分析
- 将阿拉伯数字转换为罗马数字
- 将阿拉伯数字转换为罗马数字
- 将罗马数字转换成阿拉伯数字
- 将阿拉伯数字转换成罗马数字
- 罗马数字转换阿拉伯数字0~3999
- 罗马数字与整数相互的转换
- iOS9适配
- AFNetworking判断当前手机的网络状态
- Linux使用expect脚本实现远程机器自动登录
- ios xcode开发工具快捷键
- Android中通信协议大全
- 罗马数字与阿拉伯数字相互转换
- 第4章 虚拟机性能监控与故障处理工具
- [logstash-input-log4j]插件使用详解
- 欢迎使用CSDN-markdown编辑器
- WIFI基本知识整理
- UVA 12670 数位DP
- Android Studio快捷键
- 【实验】两个有序顺序表的合并
- VMware提示:此虚拟机似乎正在使用中,取得该虚拟机的所有权失败错误的解决方案