本文参考了部分网上的想法,并加入了自己的方法,实现了在1000以后的任意数字的组合。
代码如下
package part4;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import util.Scanner;
/**
* <b>吸血鬼数字</b>
* <br>
*
* 吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,
* 而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。
* <ol>
* <li>以两个0结尾的数字是不允许的;
* <li>针对正整数(起始负数去相反数就行)。
* </ol>
* @author zhu
*
*/
class DanForhan{
private int num;
public DanForhan(int n){
num=n;
}
/**
* 检查输入的值是否符合规范
* 0-不正确
* 1-正确
* @return
*/
public static int checkData(int n){
String s=String.valueOf(n);
//不小于0
if(n<=0){
return 0;
}
//位数为偶数
else if(s.length()%2!=0){
return 0;
}
//结尾不能为两个0
else if(s.substring(s.length()-2, s.length()).equals("00"))
{
return 0;
}
else
return 1;
}
/**
* 将数字拆分成对应的字符
* @param n
* @return
*/
public char[] splitInt(int n){
return String.valueOf(n).toCharArray();
}
/**
* 比较数据
* @param n:带拆分的数
* @return
*/
public String comparData(int n){
int len=String.valueOf(n).length();
char[] c=String.valueOf(n).toCharArray();
char[] c1=new char[len/2];
char[] c2=new char[len/2];
StringBuffer str1=new StringBuffer("1"); //构建相同位数取值范围
StringBuffer str2=new StringBuffer("9"); //构建相同位数取值范围
int i,j,k;
for(i=1;i<len/2;i++)
{
str1.append("0");
str2.append("9");
}
int v1=Integer.parseInt(str1.toString()); //如100
int v2=Integer.parseInt(str2.toString()); //如999
for(j=v1;j<=v2;j++){
for(k=v1;k<=v2;k++)
{
//相等情况
if(n==j*k){
c1=String.valueOf(j).toCharArray();
c2=String.valueOf(k).toCharArray();
//比较组成的数字是否在数字里面
if(isContain(c,c1,c2)){
return n+"="+j+"*"+k;
}
}
}
}
return null;
}
/**
* 如c={1,2,3,4,5,6}中取出三个数组合为a={1,2,3},剩余的数组合为b={4,5,6}
* @param c
* @param c1
* @param c2
* @return
*/
private boolean isContain(char[] c, char[] c1, char[] c2) {
char[] d=new char[c.length];
char[] a=new char[c1.length];
char[] b=new char[c2.length];
int i,j,k,m;
m=0;
for(i=0;i<c.length;i++){
d[i]=0;//标记,0-未匹配,1-已经匹配
}
for(i=0;i<c1.length;i++){
a[i]=0;//同上
}
for(i=0;i<c2.length;i++){
b[i]=-0;//同上
}
for(i=0;i<c.length;i++){
if(d[i]==0){
for(j=0;j<c1.length&&i<c.length;j++){
if(a[j]==0){
if(c[i]==c1[j]){
d[i]=1;
a[j]=1;
m++;
break;
}
}
}
}
if(d[i]==0){
for(k=0;k<c2.length&&i<c.length;k++){
if(b[k]==0){
if(c[i]==c2[k]){
d[i]=1;
b[k]=1;
m++;
break;
}
}
}
}
}
if(m==c.length){
return true;
}
return false;
}
/**
* 查找符合条件的数据
* @return
*/
public List<String> find(){
List<String> list=new ArrayList<String>();
String value=""; //符合条件的值
int i,j;
for(i=1001;i<=num;i++){
j=DanForhan.checkData(i);
switch(j){
case 0:
break;
case 1:
value=comparData(i);
if(null!=value&&value.length()>0){
list.add(value);
}
break;
default :
break;
}
}
return list;
}
public void print(List<String> list){
if(list!=null&&list.size()>0){
System.out.println("吸血鬼数字:");
for(String s: list){
System.out.println(s);
}
}
else
{
System.out.println("没有找到符合条件的数据!");
}
}
}
/**
* 第四章,练习10(吸血鬼数字)
* @author zhu
*
*/
public class Practise_10 {
/**
* @param args
*/
public static void main(String[] args) {
long t1=System.currentTimeMillis();
DanForhan df=new DanForhan(130000);
df.print(df.find());
long t2=System.currentTimeMillis();
System.out.println("用时"+(t2-t1)+"秒");
}
}
本例中计算1001-130000之间吸血鬼数字的情况,如下图:
用时64秒,速度一般般,如果有好的想法,期待交流....