任意进制之间的转换

文章目录

  • 摘要
  • 任意进制转十进制
  • 十进制转任意进制
  • 二进制转十六进制
  • 十六进制转二进制

摘要

本文主要讲解整数的进制转换问题。方便的是,对于低精度整数,java中的整型基类IntegerLong中的parseXXX()方法和valueOf()方法可以将2 ~ 36进制的字符串转化为十进制整数,toString()方法可以将10进制数转化为2 ~ 36进制的字符串。对于高精度数,java中的大数类中也包含可以将2 ~ 36进制的字符串转化为BigInteger的构造函数。

任意进制转十进制

对于二进制数 1001 1001 1001,将其转化为十进制的一般做法: 1 ∗ 2 3 + 0 ∗ 2 2 + 0 ∗ 2 1 + 1 ∗ 2 0 1*2^3 + 0*2^2 + 0*2^1 + 1*2^0 123+022+021+120

同样,对于一个 P P P进制的数,我们同样可以这样做。

将一个 P P P进制的数 a 1 a 2 . . . a n a_1a_2...a_n a1a2...an转化为十进制的数 Y Y Y的通式: Y = a 1 ∗ p n − 1 + a 2 ∗ p n − 2 + . . . + a n ∗ p 0 Y = a_1*p^{n-1} + a_2*p^{n-2} +...+ a_n*p^{0} Y=a1pn1+a2pn2+...+anp0

但是,一般我们需要转化的进制都是大于10进制的,一般用A表示10,B表示11,以此类推。此时我们只需要特殊判断一下该字母对应的数字是几就可以了。

先给出使用java类中的内置方法的代码:

    // 如果题目要进行转化的进制在2~36之间的话直接调用库函数就行了。
	String s = in.readLine();	
    int a = Integer.parseInt(s, 16) // 将16进制的字符串转化十进制数
    //BigInteger a = new BigInteger(s, 16);// 高精度数
    
    out.write(Integer.toString(a, 8));	// 转化为8进制输出
  	//out.write(a.toString(8));
    out.flush();

使用进制转化通式:

public static int Int(char c)
{
    if(c >= '0' && c <= '9') return c - '0';
    return c >= 'a' && c <= 'z' ? c - 'a' + 10 : c - 'A' + 10; 
}
    
public static long ToTen(String x, int p) throws IOException{    	
    long y = 0, b = 1;
    	
    for(int i = x.length() - 1; i >= 0; i--)
    {
    	y += Int(x.charAt(i))*b;
    	b *= p;
   	}

    return y;
}

十进制转任意进制

同样,我们先类比十进制转二进制,也就是用除2取余法。

对于十进制数 17 17 17, 转化为2进制:

任意进制之间的转换_第1张图片
倒序排列余数,得到: 10001 10001 10001

对于十进制转化为任意进制的数,仍用取余法。

将十进制数 X X X转化为 P P P进制的数 Y Y Y:用 X X X P P P取余,直到商为0,倒序排列余数.

代码:

public static String f(int c)
{
    if(c >= 0 && c <= 9) return  String.valueOf(c);
    return c >= 0 && c <= 9 ? String.valueOf(c) : String.valueOf((char)('A' + c - 10));
}
    
public static String ToP(int x, int p) throws IOException{    	
	String y = ""; 
    	
    while(true)
    {
    	y = f(x % p) + y;
    	x /= p;
    	
   		if(x == 0) break;
   	}
    	
   	return y;
}
    

例题1: 基础练习 十进制转十六进制
例题2: 基础练习 十六进制转十进制
例题3: 基础练习 十六进制转八进制


  1. 十进制转十六进制:
import java.io.*;
import java.math.*;

public class Main{
	
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
    
    
    public static String f(int c)
    {
    	if(c >= 0 && c <= 9) return  String.valueOf(c);
    	return c >= 0 && c <= 9 ? String.valueOf(c) : String.valueOf((char)('A' + c - 10));
    }
    
    public static String ToP(int x, int p) throws IOException{    	
    	String y = ""; 
    	
    	while(true)
    	{
    		y = f(x % p) + y;
    		x /= p;
    		
    		if(x == 0) break;
    	}
    	
    	return y;
    }
    
    public static void main(String[] args )throws IOException{ 
    	String s = in.readLine();
    	
    	out.write(ToP(Integer.parseInt(s), 16) + "");
    	out.flush();
    }

	
}
  1. 十六进制转十进制
import java.io.*;
import java.math.*;

public class Main{
	
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
    
    
    public static int Int(char c){
    	if(c >= '0' && c <= '9') return c - '0';
    	return c >= 'a' && c <= 'z' ? c - 'a' + 10 : c - 'A' + 10; 
    }
    
    public static long ToTen(String x, int p) throws IOException{    	
    	long y = 0, b = 1;
    	
    	for(int i = x.length() - 1; i >= 0; i--)
    	{
    		y += Int(x.charAt(i))*b;
    		b *= p;
    	}
    	
    	return y;
    }
    
    public static void main(String[] args )throws IOException{ 
    	String s = in.readLine();
   
    	out.write(ToTen(s, 16) + "");
    	out.flush();
    }

	
}
  1. 十六进制转八进制

此题有两种做法,第一种使用java大数类的进制转化方法。 第二种先将十六进制转化为二进制,然后再转化为八进制。
为什么不转化为十进制呢? 因为本题涉及到高精度数,转化为10进制数需要用到高精度算法,比较麻烦。

方法一:

因为字符串长度很大,所以用快速输入输出。

import java.util.*;
import java.io.*;
import java.math.*;

public class Main{
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
	public static void main(String[] agrs) throws IOException{
		String s = in.readLine();
		int n = Integer.parseInt(s);
		for(int i = 0; i < n; i++){
			s =  in.readLine();
			BigInteger b = new BigInteger(s, 16);
			out.write(b.toString(8).toUpperCase()+"\n");
			out.flush();
		}
	}
}

方法二:

二进制转十六进制

先转化为二进制然后转化为八进制,二进制数每4位对应一个16进制数,每3位对应一个八进制数。
二进制转十六进制: 1010001 1010001 1010001 转化为十六进制就是:

任意进制之间的转换_第2张图片
所以 101000 1 2 = 5 1 16 1010001_2 =51_{16} 10100012=5116

十六进制转二进制

十六进制转二进制:就是将以上过程颠倒一下,十六进制数的每一位都对应四位的二进制数,然后将所有的二进制数拼接起来就是最终答案。

十六进制数 163 163 163转化为二进制:
任意进制之间的转换_第3张图片
所以 16 3 16 = 10110001 1 2 163_{16} = 101100011_{2} 16316=1011000112

对于二进制转八进制,也是同样的方法,只不过是3位二进制数对应一位八进制数。

具体看代码:



import java.io.*;
import java.util.*;

public class Main {
	
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
	
	static Map<String, String> m = new HashMap<>();
	static Map<String, String> m1 = new HashMap<>();
	static{
		m.put("0", "0000");
		m.put("1", "0001");
		m.put("2", "0010");
		m.put("3", "0011");
		m.put("4", "0100");
		m.put("5", "0101");
		m.put("6", "0110");
		m.put("7", "0111");
		m.put("8", "1000");
		m.put("9", "1001");
		m.put("A", "1010");
		m.put("B", "1011");
		m.put("C", "1100");
		m.put("D", "1101");
		m.put("E", "1110");
		m.put("F", "1111");
	}
	static{
		m1.put("000", "0");
		m1.put("001", "1");
		m1.put("010", "2");
		m1.put("011", "3");
		m1.put("100", "4");
		m1.put("101", "5");
		m1.put("110", "6");
		m1.put("111", "7");
	}
	public static int Int(String s){
		return Integer.parseInt(s);
	}
	
	public static void slove(String s) throws IOException{
		
		StringBuilder res = new StringBuilder();
		StringBuilder ans = new StringBuilder();
		
		int lens = s.length();

		for(int i = 0; i < lens; i++){ // 转化为2进制串
			res.append(m.get(s.substring(i,i+1)));
		}
		
		int lenres = res.length(); // 长度
		
		StringBuilder s1 = new StringBuilder();
		int cnt = lenres % 3;
		
		if(cnt != 0){ //如果需要补零
		
			while(cnt < 3){
				s1.append("0");
				cnt += 1;
			}
			s1.append(res.substring(0, lenres%3));
		}
	
		if(s1.length() != 0 && !s1.toString().equals("000")){
			ans.append(m1.get(s1.toString()));
		}
		
		for(int i = lenres%3; i <= lenres-3; i+=3){
			ans.append(m1.get(res.substring(i, i+3)));
		}
		
		while(ans.length() > 0 && ans.charAt(0) == '0') ans.delete(0, 1);
		out.write(ans + "\n");
		out.flush();
	}
	
	public static void main(String[] args) throws IOException{
		int n;
		n = Int(in.readLine());
		while(n --> 0){
			String s = in.readLine();
			slove(s);
		}
		out.flush();
	}
}

你可能感兴趣的:(蓝桥杯,算法,进制转化,蓝桥杯,jdk)