n位吸血鬼数字的算法

吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。


在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 ;
                             }
                         }
                     }
                 }
        
        
 }

 

 

 

为中华之腾飞做出自己的贡献。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值