1. 程式人生 > >搜尋吉祥數,在給定的範圍內,例如1~99999,找出吉祥數字,滿足的條件為:全部數字必須由6或者8構成,如66666,66668,668,…

搜尋吉祥數,在給定的範圍內,例如1~99999,找出吉祥數字,滿足的條件為:全部數字必須由6或者8構成,如66666,66668,668,…

題目:在給定的範圍內,例如1~99999,找出吉祥數字,滿足的條件為:全部數字必須由6或者8構成,如66666,66668,668,…

1.一開始想的很雜,考慮了效率:把要查詢的數轉化成String再轉化成char陣列,逐個跟“6”,“8”比較。但是這樣的話,用String會建立許多物件,會消耗許多記憶體資源。

2.想到了將每個需要判斷的位數都轉化成各位上的數,然後%10,得到這個值跟6和8比較。並且做了一些細節上的優化:

將變數都宣告在for迴圈外邊,減少系統在執行期間建立物件的個數,節約系統資源。

程式碼如下:

public class JiXiangSearch {
    public static void 
main(String[] args) { //下邊兩個是主要思路的測試程式碼,有需要的可以解除註釋簡單測試一下。 /*System.out.println(448%10); System.out.println((448/10)%10);*/ //正式部分開始,首先宣告一些需要用到的變數,降低系統資源消耗 int n = 0; //用來接收要查詢的數呼叫toString方法後的長度值 int temp=0; //用來接收—10的冪值 int result=0; //用來接收i/tempi的值 for(Integer i=1;i<=99999
;i++) { //用字串長度的形式來表示i是幾位數 n = i.toString().length(); //這個for迴圈的目的是為了逐位的判斷i的每個位數上的值是不是6或者8 for (int j = 0; j <=n-1; j++) { //用來複制i的值,保證i的值在計算過程中不直接參與,不發生變化。 int copy = i; //Math類的一個方法求一個數的冪,返回值是double型別,需要強制型別轉換 temp = (int)(Math.pow(10, j)); //
每次進入迴圈除以10的冪次方,將要比較的位數轉換成個位數。 result = (copy/temp)%10; if(result==6||result==8){ //吉祥數判斷,判斷當前個位上的數是不是吉祥數字。 //判斷到最後一位,依然成立,輸出i的值, if(j==n-1) { System.out.print(i + " ,"); } }else{ break ; } } } } }

測試結果如下所示:

"C:\Program Files\Java\jdk1.8.0_144\bin\java"
6 ,8 ,66 ,68 ,86 ,88 ,666 ,668 ,686 ,688 ,866 ,868 ,886 ,888 ,6666 ,6668 ,6686 ,6688 ,6866 ,6868 ,6886 ,6888 ,8666 ,8668 ,8686 ,8688 ,8866 ,8868 ,8886 ,8888 ,66666 ,66668 ,66686 ,66688 ,66866 ,66868 ,66886 ,66888 ,68666 ,68668 ,68686 ,68688 ,68866 ,68868 ,68886 ,68888 ,86666 ,86668 ,86686 ,86688 ,86866 ,86868 ,86886 ,86888 ,88666 ,88668 ,88686 ,88688 ,88866 ,88868 ,88886 ,88888 ,

Process finished with exit code 0

寫到這裡的時候我思考了一個問題,如何才能在比較更少的情況下查詢出所有要查詢的數字,

例如:如果將內層迴圈從最高位開始比較,這樣如果最高位不符合要求,會減少很多不必要進行的判斷,嘗試修改程式碼如下:

  我用九位數測試了一下,結果發現從最高位往最低位走的話,比上面的方式時間還要長,這裡有些疑問,不知道為什麼?

老師給出了這樣一個思路,例如千位數,只查詢6666-8888之間的數,感覺很有道理,去做一下試驗:

//正式部分開始,首先宣告一些需要用到的變數,降低系統資源消耗
int n = 0;          //用來接收要查詢的數呼叫toString方法後的長度值
int temp = 0;         //用來接收—10的冪值
int result = 0;       //用來接收i/tempi的值
String[] str = {"1","11","111","1111","11111","111111","1111111","11111111","111111111"};
for(Integer i=1;i<=999999999;i++) {
    //用字串長度的形式來表示i是幾位數
n = i.toString().length();
    int toInt = Integer.parseInt(str[n-1]);
    if(i>=6*toInt&&i<=8*toInt){
        //這個for迴圈的目的是為了逐位的判斷i的每個位數上的值是不是6或者8
for (int j = n-1; j >=0; j--) {
            //用來複制i的值,保證i的值在計算過程中不直接參與,不發生變化。
int copy = i;
            //Math類的一個方法求一個數的冪,返回值是double型別,需要強制型別轉換
temp  = (int)(Math.pow(10, j));
            //每次進入迴圈除以10的冪次方,將要比較的位數轉換成個位數。
result = (copy/temp)%10;
            if(result==6||result==8){        //吉祥數判斷,判斷當前個位上的數是不是吉祥數字。
//判斷到最後一位,依然成立,輸出i的值,
if(j==0) {
                    System.out.print(i + " ,");
                }
            }else{
                break ;
            }
        }
    }else{
        continue;
    }
}

結果顯示在沒有進行判斷之前,九位數需要進行133336ms,優化以後需要87610ms,節省了1/3的時間。

請各位大佬路過時候指點一下文章中紅色字型,我不是太懂!!!謝謝。

做完這道題有了一些感想,演算法的極致大概就是隻讓計算機查詢或者計算工程師們想要查詢的東西吧,除此之外的資料

由工程師負責全部排除掉。節約時間,提高效率。        ——我認為演算法非常有意思!