1. 程式人生 > >巨大的16進位制數轉到8進位制數

巨大的16進位制數轉到8進位制數

以下是原題

問題描述

  給定n個十六進位制正整數,輸出它們對應的八進位制數。

輸入格式
  輸入的第一行為一個正整數n (1<=n<=10)。
  接下來n行,每行一個由0~9、大寫字母A~F組成的字串,表示要轉換的十六進位制正整數,每個十六進位制數長度不超過100000。

輸出格式
  輸出n行,每行為輸入對應的八進位制正整數。

【注意
  輸入的十六進位制數不會有前導0,比如012A。
  輸出的八進位制數也不能有前導0。

樣例輸入
  2
  39
  123ABC

樣例輸出
  71
  4435274

提示

  先將十六進位制數轉換成某進位制數,再由某進位制數轉換成八進位制。

一、首先,我沒有考慮到資料長度有100000的情況,然後就涼了,下面是第一次的程式碼:

import java.util.Scanner;
import java.util.Stack;

/**
 * @author QiangweiLuo
 */
public class T0011 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int loop = sc.nextInt();

        while (loop-- > 0) {
            Long in = Long.parseLong(sc.next(), 16);
            //System.out.println(in);
            StringBuilder sb = new StringBuilder();
            Stack<Long> st = new Stack<>();
            while(true){
                long temp = in % 8;
                in /= 8;
                st.push(temp);
                if(in < 8){
                    st.push(in);
                    break;
                }
            }
            while(st.size() > 0)
                sb.append(st.pop());

            System.out.println(sb.toString());
        }
    }
}

二、以下是考慮後的程式碼:

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Scanner;

/**
 * @author QiangweiLuo
 */
public class T0011_1 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int loop = sc.nextInt();
        ArrayList<String> a = new ArrayList<>();
        for(int i = 0; i < loop; i++){
            String in = sc.next();
            StringBuilder sb = new StringBuilder();
            for(int j = in.length() - 1; j >= 0; j-=3){
                String ch = null;
                if(j > 1)
                    ch = "" + in.charAt(j - 2) + in.charAt(j - 1) + in.charAt(j);
                else if(j == 1)
                    ch = "" + in.charAt(j - 1) + in.charAt(j);
                else
                    ch = "" + in.charAt(j);
                int temp = Integer.valueOf(ch, 16);
                String tStr = Integer.toOctalString(temp);
                //System.err.println(tStr);
                if(tStr.length() < 4 && j > 1) tStr = "0" + tStr;
                if(tStr.length() < 4 && j > 1) tStr = "0" + tStr; // 取巧的方法.....
                if(tStr.length() < 4 && j > 1) tStr = "0" + tStr; // 取巧的方法.....
                if(tStr.length() < 4 && j > 1) tStr = "0" + tStr; // 取巧的方法.....
                sb.insert(0, tStr);
            }
            //System.err.println(sb.toString());
            a.add(sb.toString());
        }

        for(int i = 0; i < a.size(); i++){
            System.out.println(a.get(i));
        }
    }
}

我的思路是:

    3的16進位制數可以直接化為相當於4個二進位制數(一個16進位制數4位,一個8進位制數3位,4*3/3=4個8進位制數)。

    轉化從16進位制數的末尾開始,設數長為k,分別取k-2,k-1,k這3個16進位制數,通過Integer.valueOf()方法轉化成10進位制,然後再通過Interger.toOctalString()轉化成8進位制,最後轉化的結果如果沒有4個字長,且沒有取到k-k這個16進位制數,補0直到字長4位。 然後接著取 k-5,k-4,k-3這3個16進位制數...

    需要做個判斷,如果讀取到了最後,只有1位或2位的時候,只取那1位或2位二進位制數進行轉換。

    轉換的依次放入字串的前面,字串初值是"" 

三、最簡單,但是會超時的方法:

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Scanner;

public class T0011_2 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int loop = sc.nextInt();
        ArrayList<String> a = new ArrayList<>();
        for(int i = 0; i < loop; i++){
            a.add(new BigInteger(sc.next(), 16).toString(8));
        }

        for(int i = 0; i < a.size(); i++){
            System.out.println(a.get(i));
        }
    }
}