天天看點

OpenJudge---1001:ExponentiationOpenJudge—1001:Exponentiation

OpenJudge—1001:Exponentiation

刷題之百練oj。決定往java方向發展的我希望能用java刷這些oj上的題目;莫名其妙使用了java之後不習慣從底層考慮問題了,一直想要調用什麼方法;然而自己對很多方法都還不了解,是以這個位置很尴尬。不多說了,這個題目其實很簡單,但對于無知的我而言還有很多都不懂,需要總結。

遇到的問題有:

1.如何處理大整數問題?讀入大整數,大整數的乘方運算?

2.計算之後如何處理題目中對輸出結果的要求?如不能有前邊的0?不能有多餘的無意義的0?

3.正規表達式的回顧和使用(還不熟練)?

4.如何找出樣例來debug?

解決過程:

1.首先java中有BigDecimal這個類用來表示精度比較大的數;類中的方法包含的對大整數的加減乘除、乘方等,調用方法和int等數不太一樣;通過查手冊即可了解到。

BigDecimal.pow(int n)
           

2.最開始處理的是結尾的0以及開頭的0的問題,這兩個解決的也很容易,隻需要找到有效位的起點和終點,然後輸出中間部分就可以了。但是出現的問題在于第一步中的結果是用科學記數法表示的,于是需要處理後邊的指數部分和前邊小數點的移位問題。

在這個過程中用到了正規表達式,主要目的是找到小數點移動的位數,進而恢複出原始的資料。下述代碼就找到了最後的指數。

String pattern="(\\d*)(\\.*)(\\d+)(E-)(\\d+)";
Pattern r=Pattern.compile(pattern);
Matcher m=r.matcher(sb);
if(m.find()){
    flag=Integer.parseInt(m.group());
}
           

其實這裡還存在一個問題是,我的這種做法僅限于指數為負。

3.正規表達式的使用,以及正規表達式的定義了。

Pattern、Pattern.compile、Matcher、matcher()、find()

其中Pattern可以了解為定義一個正則規則

Matcher可以了解為字元串對規則進行比對後的結果

此外,在比對的結果中group(0)存放的是整個字元串、剩下的是按括号進行存儲的内容

4.找樣例。本來是想用對拍程式的,有點麻煩,于是自己自動産生大量資料,然後找了一個已經通過的程式,找不同……

收獲

看了其他人的writeup,很多是将大數計算從底層實作了一遍,大緻思路是,将小數點先删掉,并記錄下它的位置以便之後恢複使用。然後剩下的位數進行乘法計算,以字元串的形式進行計算,這部分也是一個難點,涉及到進位等問題;此外将乘方運算簡化為多次乘法運算;最後将小數點放在合适的位置。

java中有兩個方法這裡如果使用的話會很簡便:

stripTrailingZeros():作用是删掉後邊多餘的0

roPlainString():作用是不使用科學記數法輸出

貼代碼

import java.math.*;
import java.util.Scanner;
import java.util.regex.*;
public class Exponentiation {
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        String pattern="(\\d*)(\\.*)(\\d+)(E-)(\\d+)";
        Pattern r=Pattern.compile(pattern);

        while(sc.hasNext()){
            BigDecimal bd=sc.nextBigDecimal();
            int x=sc.nextInt();
            BigDecimal re=bd.pow(x);
            String sb=re.toString();
            //System.out.println(sb);
            int start=,end=sb.length()-,flag=;
            Matcher m=r.matcher(sb);
            if(m.find()){
                flag=Integer.parseInt(m.group());
                sb=m.group()+m.group()+m.group();
                end=end--m.group().length();
            }
            //System.out.println(flag);
            if(sb.charAt()=='0'){
                start=;
                //end=;
                //flag=;
            }
            while(end!=){
                if(sb.charAt(end)=='0'){
                    end--;
                }
                else{
                    break;
                }
            }
            if(sb.charAt(end)=='.'){
                end--;
            }
            if(flag!=&&sb.charAt(start)!='0'){
                System.out.print('.');
                for(int k=;k<flag;k++){
                    System.out.print("0");
                }
                System.out.print(sb.charAt());
                start=;
            }
            for(int i=start;i<=end;i++){
                System.out.print(sb.charAt(i));
            }
            System.out.println();
        }
        sc.close();
    }
}