罗马数字与阿拉伯数字相互转换
2015-09-22 22:25
387 查看
罗马数字规则简明
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;}。比如IV = 5 - 1
如果当前位对应的值小于上一位的(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. 罗马单个数字共有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;}。比如IV = 5 - 1
如果当前位对应的值小于上一位的(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代码
/** * @author Rust Fisher * Reverse number to Roman or reverse Roman to number */ public class RomanAndInt { /** * @param s - String Roman * @return int number */ public static int romanToInt(String s) { if (s.length() < 1) return 0; int result = 0; int current = 0; int pre = singleRomanToInt(s.charAt(0)); int temp = pre; for (int i = 1; i < s.length(); i++) { current = singleRomanToInt(s.charAt(i)); if (current == pre) temp += current; else if (current > pre){ temp = current - temp; } else if (current < pre){ result += temp; temp = current; } pre = current; } result += temp; return result; } /** * @param c single Roman * @return single number */ public static int singleRomanToInt(char c){ switch (c) { case 'I': return 1; case 'V': return 5; case 'X': return 10; case 'L': return 50; case 'C': return 100; case 'D': return 500; case 'M': return 1000; default: return 0; } } /** * @param n - input single int * @param nth must start from 1; 1 <= nth <= 4 * @return String single Roman */ public static String singleDigitToRoman(int n, int nth){ if (n == 0) { return ""; } nth = 2 * nth - 1; // nth must start from 1 char singleRoman[] = {'I','V','X','L','C','D','M','Z','E'}; // never use 'Z' & 'E' StringBuilder rsb = new StringBuilder(""); if (n <= 3) { for (int i = 0; i < n; i++) { rsb.append(singleRoman[nth-1]); } return rsb.toString(); } if (n == 4) { rsb.append(singleRoman[nth-1]); rsb.append(singleRoman[nth]); return rsb.toString(); } if (n == 5) { return singleRoman[nth] + ""; } if (n >= 6 && n <= 8) { rsb.append(singleRoman[nth]); for (int i = 0; i < (n - 5); i++) { rsb.append(singleRoman[nth-1]); } return rsb.toString(); } if (n == 9) { rsb.append(singleRoman[nth-1]); rsb.append(singleRoman[nth+1]); return rsb.toString(); } return "ERROR!!!"; } /** * @param num - input number within range 1 ~ 3999 * @return String Roman number */ public static String intToRoman(int num) { if (num < 1 || num > 3999) { return "ERROR input number is 1 ~ 3999"; } int temp = num; String singleRoman[] = {"","","",""}; StringBuilder result = new StringBuilder(""); int digits = 0; // 1 ~ 4 while (temp != 0){ temp = temp/10; digits++; } temp = num; int[] singleInt = new int[digits]; for (int i = 0; i < digits; i++) { singleInt[i] = temp%10; singleRoman[i] = singleDigitToRoman(temp%10,i+1); temp /= 10; } for (int i = digits-1; i >= 0; i--) { result.append(singleRoman[i]); } return result.toString(); } /** * test main */ public static void main(String args[]){ for (int i = 0; i < 4; i++) { int input = (int) (Math.random()*Math.pow(10, i+1)); if (input > 3999) { input = 3999; } System.out.println(input + " = " + intToRoman(input)); } } }
小结
转换的思路在于截取数字,一位一位来处理,最后拼接或相加得到结果
这两个过程都用到了处理单个数字的方法;化整为零,循环处理整个数字;把处理细节的方法封装起来,便于调用
相关文章推荐
- Java抽象类
- 每天一个css 伪类
- C#实现文件下载的几种方式
- Linux LVM空间拓展演示
- 信息安全系统设计基础第二周学习总结
- ps -ef | grep **
- 算法系列——向量空间模型计算模板选择
- 3.分析Linux内核的启动过程
- el表达式的小知识点
- HDU 5459 Jesus Is Here (递推,组合数学)
- swift中,Optional、?与!之间的关系
- jQuery的学习笔记2
- SharedPreference.Editor的apply和commit方法区别
- xcode
- Fang Fang hdoj 5455 (字符串)
- ZOJ 3811
- Anagrams问题
- oracle 基本技能
- 面对对象思想1
- java将捕获的异常写入日志