我正在编写生成吸血鬼编号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)。所以我想问
我可以做什么来优化此代码?我曾考虑过使用带数字的String而不是long / BigInteger。我想“忽略”该堆问题。将大量数字保存到文件中太慢了,对吗?
我的同伴编写(bigNum.cpp)http://pastebin.com/0HHdE848-C ++中的类,以对大数进行运算。也许在社区的帮助下,我可以在a.java中实现它?更重要-对我的问题有用吗?
编辑:我的目标是生成吸血鬼数字的自由范围,例如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());
}
}
}
编辑:http://ideone.com/3rHhep-以上与numberOfDigits == 4的工作代码。
最佳答案
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);
}
}
}
}
}
这将生成吸血鬼编号,只需修改开始和结束整数即可。