2015-06-30 24 views
0

我正在編寫程序,它會生成吸血鬼號碼https://en.wikipedia.org/wiki/Vampire_number在自由範圍內生成吸血鬼號碼

我有主要功能numberOfDigits參數,其中必須是甚至。如果numberOfDigits等於4,那麼我們正在搜索1000到9999範圍內的吸血鬼數字 - 四位數字。如果numberOfDigits等於6,那麼我們正在從100000到999999搜索吸血鬼數字 - 這是六位數字。

在以下文件中,當我想要搜索範圍爲10位數的吸血鬼數字時,Java堆空間正在尖叫。請注意,我有內存的默認設置。但是,對於numberOfDigits == 4,6或8,代碼工作正常。 (比較輸出爲https://oeis.org/A014575/b014575.txt,https://oeis.org/A014575)。所以我想問,

  1. 我可以做些什麼來優化此代碼?我曾考慮過使用String中的數字,而不是long/BigInteger。我想「省略」那堆問題。保存大數據文件會太慢,對嗎?

  2. 我的隊友寫了(bigNum.cpp)http://pastebin.com/0HHdE848 - C++中的類,用於處理大數字。也許在社區的幫助下,我可以在我的a.java中實現它?更重要的是 - 它會對我的問題有用嗎?

  3. 編輯:我的目標是產生自由範圍吸血鬼數,如4,6,8 - a.java它可以做到這一點,更是(如果我可以繞過堆空間的問題)。那就是當我的問題來幫助時。

a.java(從johk95排列碼,https://stackoverflow.com/a/20906510

import java.util.ArrayList; 
import java.util.Arrays; 

/** 
* 
* @author re 
*/ 
public class a { 

    /** 
    * 
    * @param numberOfDigits {int} 
    * @return ArrayList of Integer 
    */ 
    public ArrayList<Integer> vdf(int numberOfDigits) { 

     if ((numberOfDigits % 2) == 1) { 
      //or throw Exception of unrecognised format/variable? 
      System.out.println("cant operate on odd argument"); 
      return new ArrayList<>(); 
     } 
     long maxRange = 9; 

     for (int i = 1; i < numberOfDigits; i++) { 
      maxRange *= 10; 
      maxRange += 9; 
     }//numberOfDigits==4 then maxRange==9999, nOD==5 then maxRange==99999,.. 

     long minRange = 1; 

     for (int i = 1; i < numberOfDigits; i++) { 
      minRange *= 10; 
     }//nOD==4 then minRange==1000, nOD==5 then minRange==10000, .. 

     ArrayList<Integer> ret = new ArrayList<>(); 
     for (long i = minRange; i < maxRange; i++) { 

      long a = i; 

      long[] b = new long[numberOfDigits]; 

      for (int j = numberOfDigits-1; j >= 0 ; j--) { 
       long c = a % 10; 
       a = a/10; 
       b[j] = c; 
      } 

      int x = 0; 
      int y = 0; 
      ArrayList<long[]> list = permutations(b); 
      b = null; //dont need now 

      for(long[] s : list) { 
       for (int j = 0; j < numberOfDigits/2; j++) { 
        x += s[(numberOfDigits/2)-j-1] * Math.pow(10, j); 
        y += s[numberOfDigits-j-1] * Math.pow(10, j); 
       } 
       StringBuilder builder = new StringBuilder(); 
       for (long t : s) { 
        builder.append(t); 
       } 
       String v = builder.toString(); 

       if ((v.charAt((v.length()/2)-1) != '0'|| 
        v.charAt(v.length()-1) != '0') && 
        x * y == i) { 
        ret.add(x); 
        ret.add(y); 
        System.out.println(x*y+" "+x+" "+y); 
        break; 
       } 
       x = y = 0; 
      } 
     } 
     System.out.printf("%d vampire numbers found\n", ret.size()/2); 
     return ret; 
    } 

    /** 
    * 
    *@return vdf(4) 
    */ 
    public ArrayList<Integer> vdf() { 
     return vdf(4);//without trailing zeros 
    } 

    /* permutation code copied from 
    * johk95 
    * https://stackoverflow.com/a/20906510 
    */ 
    private static ArrayList<long[]> permutations(long[] lol) { 
     ArrayList<long[]> ret = new ArrayList<>(); 
     permutation(lol, 0, ret); 
     return ret; 
    } 

    private static void permutation(long[] arr, int pos, ArrayList<long[]> list){ 
     if(arr.length - pos == 1) 
      list.add(arr.clone()); 
     else 
      for(int i = pos; i < arr.length; i++){ 
       swap(arr, pos, i); 
       permutation(arr, pos+1, list); 
       swap(arr, pos, i); 
      } 
    } 

    private static void swap(long[] arr, int pos1, int pos2){ 
     long h = arr[pos1]; 
     arr[pos1] = arr[pos2]; 
     arr[pos2] = h; 
    } 

    public static void main(String[] args) { 
     a a = new a(); 
     try{ 
      a.vdf(10); //TRY IT WITH 4, 6 or 8. <<<< 
     }catch (java.lang.OutOfMemoryError e){ 
      System.err.println(e.getMessage()); 
     } 
    } 
} 

EDIThttp://ideone.com/3rHhep - 上面numberOfDigits == 4.

+0

選擇一種語言,C++或Java。這看起來像Java,因爲C++沒有'ArrayList'(除非你寫了它)。 –

+0

@ThomasMatthews文件a.java是我用Java編寫的。我只複製johk95用戶的排列函數。 – nanomader94

回答

1
package testing; 

import java.util.Arrays; 


public class Testing 
{ 
    final static int START = 11, END = 1000; 
    public static void main(String[] args) 
    { 
     char[] kChar, checkChar; 
     String kStr, checkStr; 
     int k; 
     for(int i=START; i<END; i++) { 
       for(int i1=i; i1<100; i1++) { 
        k = i * i1; 

        kStr = Integer.toString(k); 
        checkStr = Integer.toString(i) + Integer.toString(i1); 

        //if(kStr.length() != 4) break; 

        kChar = kStr.toCharArray(); 
        checkChar = checkStr.toCharArray(); 

        Arrays.sort(kChar); 
        Arrays.sort(checkChar); 

        if(Arrays.equals(kChar, checkChar)) { 
         System.out.println(i + " * " + i1 + " = " + k); 
        } 
       } 
      } 
    } 
} 

本工作代碼會產生吸血鬼數字,只需修改開始和結束整數。

+0

感謝您的反饋和您的代碼。但是如果我想要生成14位數的吸血鬼號碼呢?我想要這樣做,就像這樣: generateVampireNumbers(/ * numberOfDigits */12); 我不想每次都編輯文件。我的主要目標是「省略」,或使用一些棘手的方法繞過堆問題。也許弦,正如我在我的問題中提到的? – nanomader94

+0

@ nanomader94這是一個變量,使它不是最終的,只是用代碼來改變它 – stealth9799