吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。
在java编程思想发现了一道吸血鬼数字算法的题目,自己分别写出了4位和6位的算法,特别地,自己增加了一个n位的吸血鬼算法,来满足我对算法的狂热。
功能1:判断这个数字是否为吸血鬼数字
功能2:查找n位范围内的吸血鬼数字
解决吸血鬼数字的算法的关键在于对一串数字进行成熟与被乘数的拆分以及对拆分后的数字进行全排列。
例如一串数字12345678 可拆分为
被乘数 乘数
1234 5678
1235 4678
1236 4578
1237 4568
1238 4567
.。。 。。。
1678 2345
接下来进行数字的全排列
例如被乘数部分 1234 组成形式有16中形式
1234,1243,1324,1342,1423,1432
2134,2143,2314,2341,2413,1431
3124,3142,3214,3241,3412,3421
4123,4132,4213,4231,4312,4321
然后用集合把以上数字存储
乘数部分同上
每得到一个乘数便与集合的数字进行乘积,结果判断是否与原数字一样即可。
而难点在于对算法的优化,此代码可以进一步优化,年假期间我会对此代码进行更新。
package test1;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Bloodsucker_Method {
private static List<Character> numList=new ArrayList<Character>();
private static List<Character> sortList=new ArrayList<Character>();
private static List<Long> multiplierList=new ArrayList<Long>();
private static int numHalfLength;
private static long startNum=1;
private static boolean falg=false;
private static boolean satisfy=false;
public static void main(String[] args) {
int numLength;
long endNum;
System.out.println("1:查询一个数字是否是吸血鬼数字?\n2:查询n位数的所有吸血鬼数字");
@SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
if(scanner.next().equals("1")){
while(true) {
System.out.println("输入你想查询的数字");
String number = scanner.next();
if (number.length()%2!=0){
System.out.println("输入位数不是偶数,不满足吸血鬼数字规则");
}
else {
numHalfLength=number.length()/2;
startNum=Integer.parseInt(number);
f(number);
if(!satisfy) System.out.println(startNum+"不是吸血鬼数字");
break;
}
}
}
else {
while(true) {
System.out.println("输入你想查询n位数的所有吸血鬼数字");
numLength = scanner.nextInt();
if (numLength%2!=0){
System.out.println("输入位数不是偶数,不满足吸血鬼数字规则");
}
else { break; }
}
numHalfLength = numLength / 2;
for (long i = 1; i < numLength; i++) {
startNum *= 10;
}
endNum = startNum * 10;
while (startNum < endNum){
numList.clear();
sortList.clear();
multiplierList.clear();
String number = Long.toString(startNum);
f(number);
satisfy = false;
startNum++;
}
}
}
private static void f(String number){
char[] chars = number.toCharArray();
int k=0;
StringBuffer buffer=new StringBuffer();
buffer.append(chars[0]);
prepareSplit(chars,k,buffer,number);
}
private static int prepareSplit(char a[],int k,StringBuffer buffer,String number){
int length=2*numHalfLength;
for (int i=k+1,j=0;j<=numHalfLength&&i<length;i++,j++){
buffer.append(a[i]);
if(buffer.length()>=numHalfLength){
multiplierSpilt(buffer,number);
if(satisfy)return length;
}
else {
k= prepareSplit(a, i, buffer, number);
if(satisfy)return length;
}
}
if(buffer.length()>0) {
buffer.deleteCharAt(buffer.length() - 1);
}
return k;
}
private static void multiplierSpilt(StringBuffer buffer,String rigthNum){
String leftNum=buffer.toString();
buffer.deleteCharAt(buffer.length()-1);
for(int i=0;i<numHalfLength;i++) {
rigthNum= rigthNum.replaceFirst(leftNum.charAt(i) + "", "");
}
prrepareSort(leftNum,rigthNum);
}
private static void prrepareSort(String leftNum,String rigthNum){
falg=false;
for(int i=0;i<numHalfLength;i++){
numList.add(leftNum.charAt(i));
}
sortNumberlist();
numList.clear();
falg=true;
for(int i=0;i<numHalfLength;i++){
numList.add(rigthNum.charAt(i));
}
sortNumberlist();
numList.clear();
multiplierList.clear();
}
private static void sortNumberlist(){
List<Character> list2= new ArrayList<>();
list2.addAll(numList);
int len1=sortList.size();
int len2=len1+1;
for (Character o : sortList) {
list2.remove(o);
}
for (Character o : list2) {
sortList.add(o);
if(len2==numHalfLength){
validation();
if(satisfy)return;
}
else{ sortNumberlist();
}
sortList.remove(len1);
if(satisfy)return ;
}
}
private static void validation() {
Long num;
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < numHalfLength; i++) buffer.append(sortList.get(i));
num = Long.parseLong(buffer.toString());
if(!falg) {
multiplierList.add(num);
}
else {
for ( long o : multiplierList) {
if(o*num==startNum){
satisfy=true;
System.out.println(startNum+"是吸血鬼数字");
System.out.println(o+" * "+num+"="+startNum);
return ;
}
}
}
}
}
为中华之腾飞做出自己的贡献。