java使用移位运算进行进制转化
2017-03-22 09:44
429 查看
最近在练习进制转换算法,学习了一种使用移位运算进行进制的方法分享给大家。
16进制转换8进制
我一开始的解法,1个16进制数可以转化为4个2进制数,再通过每3个二进制数可以转化为1个8进制数。不过有一点需要注意转化成8进制数要从2进制字符串后面开始,到最前面时需要判断还剩下几位,不够3位要补0。
使用题目给的测试可以通过,我自己设置的测试数据也可以通过,然后去蓝桥杯测试平台上跑结果炸了!去看测试数据,10个16进制数,最长的10万位,估计是溢出了。去调试发现是在2进制转化为8进制的时候出错了,for循环次数太多了。for里还有数值运算比较费时,改了好久测试总是通不过。去百度发现一种运用java移位运算进行转化的,写了试了一下发现可以通过了。
使用java移位运算符进行转化
这种解法的思路是:1位16进制可以代表4位2进制, 1位8进制可以代表3位二进制,得出3位16进制求和入栈输出表示4位8进制,然后出栈输出。由16进制转化为10进制的时候,使用 << 使16进制数转化为8进制。
例子:
这种算法的效率非常高,运算十分较少。可以通过蓝桥杯测试系统的变态数据。
16进制转换8进制
问题描述: 输入格式 输入的第一行为一个正整数n (1<=n<=10)。 接下来n行,每行一个由0~9、大写字母A~F组成的字符串, 表示要转换的十六进制正整数,每个十六进制数长度不超过100000。 输出格式 输出n行,每行为输入对应的八进制正整数。 注意 输入的十六进制数不会有前导0,比如012A。输出的八进制数也不能有前导0。 样例输入 239123ABC 样例 71 4435274
我一开始的解法,1个16进制数可以转化为4个2进制数,再通过每3个二进制数可以转化为1个8进制数。不过有一点需要注意转化成8进制数要从2进制字符串后面开始,到最前面时需要判断还剩下几位,不够3位要补0。
package 十六进制转八进制; import java.text.DecimalFormat; import java.util.Scanner; import java.util.Stack; public class Main { static Scanner scan = new Scanner(System.in); static DecimalFormat decimalFormat=new DecimalFormat("0000"); static DecimalFormat d2=new DecimalFormat("000"); public static void change(String str){ String s = ""; int top = 0; char[] c = str.toCharArray(); for (int k = 0; k < c.length; k++) { if (c[k] >= '0' && c[k] <= '9') { s+=decimalFormat.format(Integer.parseInt(Integer.toBinaryString(c[k]-48))); }else if(c[k] >= 'A' && c[k] <= 'F'){ s+=decimalFormat.format(Integer.parseInt(Integer.toBinaryString(c[k]-55))); } } int num = s.length(); if(num%3==1) s="00"+s; else if(num%3==2) s="0"+s; if(s.substring(0, 3).equals("000")){ s=s.substring(3); } for (int i = 0; i < s.length(); i=i+3) { String xStr = s.substring(i,i+3); System.out.print(Integer.parseInt(xStr.substring(0,1))*4+ Integer.parseInt(xStr.substring(1,2))*2+ Integer.parseInt(xStr.substring(2,3))*1); } } public static void main(String[] args) { int n = Integer.parseInt(scan.nextLine()); String[] strs = new String ; for (int i = 0; i < strs.length; i++) { strs[i] = scan.nextLine(); } for (int i = 0; i < strs.length; i++) { change(strs[i]); System.out.println(); } } }
使用题目给的测试可以通过,我自己设置的测试数据也可以通过,然后去蓝桥杯测试平台上跑结果炸了!去看测试数据,10个16进制数,最长的10万位,估计是溢出了。去调试发现是在2进制转化为8进制的时候出错了,for循环次数太多了。for里还有数值运算比较费时,改了好久测试总是通不过。去百度发现一种运用java移位运算进行转化的,写了试了一下发现可以通过了。
使用java移位运算符进行转化
import java.util.Scanner; public class Main { public static void main(String[] args) { new Main().systemScanner(); } public void systemScanner() { Scanner jin = new Scanner(System.in); while (jin.hasNext()) { int length = jin.nextInt(); for (int i = 0; i < length; i++){ String strTmp=jin.next(); tranform(strTmp.toCharArray(), strTmp.length()); } } } /* * 3位16进制等价于4位8进制 */ int[] stack=new int[40000]; public void tranform(char[] str, int length) { char[] buff = new char[4]; int top = -1; for (int i = length - 1; i >= 0; i -= 3) { int sum = 0; for (int j = 0; j < 3 && i - j >= 0; j++) {// i-j>=0防止不够三个的情况 int tmp = str[i - j] >= '0' && str[i - j] <= '9' ? str[i - j] - '0': str[i - j] - 'A' + 10;//区分是数字,还是字符,进行对应转换 sum+=(tmp<<(4*j));//这句很重要,通过这句就可以从16变成10进制了。 } stack[++top]=sum;//sum的结果是16进制转化10进制的结果,每3个16进制变成10进制,再变8进制 } while(stack[top]==0){//排除前导为0的判断 top--; } for(int i=top;i>=0;i--){ String str1=Integer.toOctalString(stack[i]);//从10进制转化成8进制 if(i!=top&&str1.length()<4){ //不是最左边的一个,就不用去掉前导0,而默认是去掉0的,所以要进行补会 for(int y=0;y<4-str1.length();y++) System.out.print("0"); } System.out.print(str1); } System.out.println(); } }
这种解法的思路是:1位16进制可以代表4位2进制, 1位8进制可以代表3位二进制,得出3位16进制求和入栈输出表示4位8进制,然后出栈输出。由16进制转化为10进制的时候,使用 << 使16进制数转化为8进制。
例子:
0x11 << 4 => 17; /* 11的二进制编码是 1011,个位是1 编码是0001,十位是1 编码也是0001。 根据位数进行移位运算,个位左移(4*0)位还是0001,十位左移(4*1)位变成00010000 */ 0001 << 4*1 = 00010000; 0001 << 4*0 = 0001; /* 整个数就变成了00010001 也就是10001 转换为10进制是为17。这里可以看到一个16进 制数通过按位数分别左移4*(n-1)位就可以转化为10进制数了。具体的原因是每一个整 数左移4位等于这数的二进制表示后面多了4个0,相当于2进制乘法乘了一个二进制10000()。 */ 1*16^1+1*16^0 = 17; /* 10000转化为10进制为16也就是每位乘了16^(n-1)进而把一个16进制数转化为10进制数。 */
这种算法的效率非常高,运算十分较少。可以通过蓝桥杯测试系统的变态数据。
相关文章推荐
- java使用DateUtils对日期进行数学运算
- JAVA中使用P和Q分量计算N和D进行RSA运算
- Java中使用BigDecimal进行精确运算
- java使用DateUtils对日期进行数学运算
- java使用DateUtils对日期进行运算
- java 中使用BigDecimal进行数的四则运算
- Java基础----使用BigDecimal进行精确运算
- Java进阶(四十八)使用BigDecimal对浮点数进行精确运算
- 使用Java把16进制数转化成10进制
- Java中使用BigDecimal进行浮点数运算
- 【java解惑】使用double进行小数运算
- Java使用DateUtils对日期进行数学运算经典应用示例【附DateUtils相关包文件下载】
- 使用Java BigDecimal进行精确运算
- ireport中使用java进行pdf转化,jasper作为模板
- 【java解惑】使用double进行小数运算
- 使用 Shell 运算进行进制转换 16进制转10进制
- 好的JAVA思路——利用补码运算和位运算的巧用来实现进制转化
- JAVA中使用P和Q分量计算N和D进行RSA运算
- javaweb中使用百度、谷歌地图进行定位
- 使用 Java 配置进行 Spring bean 管理