在自由范围内生成吸血鬼数字

时间:2015-06-30 22:08:57

标签: java c++ arrays numbers integer

我正在编写生成吸血鬼数字 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.txthttps://oeis.org/A014575进行比较)。所以我想问一下,

  1. 我可以做些什么来优化此代码?我已经考虑过使用带有数字的String,而不是long / BigInteger。我想“省略”那个堆问题。将大数字保存到文件会太慢,我是对的吗?

  2. 我的伙伴用C ++编写了(bigNum.cpp)http://pastebin.com/0HHdE848 - 类来操作大数字。也许在社区的帮助下我可以在我的a.java中实现它?更重要的是 - 它对我的问题有用吗?

  3. 编辑:我的目标是生成免费范围的吸血鬼号码,例如4,6,8 - a.java 它可以做到这一点,甚至更多(如果我可以绕过堆空间问题)。这就是我提出帮助的问题。

  4. 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());
            }
        }
    }
    

    编辑http://ideone.com/3rHhep - 使用numberOfDigits == 4上面的代码。

1 个答案:

答案 0 :(得分: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);
                    }
                }
            }
    }
}

这将生成吸血鬼数字,只需修改开始和结束整数。