编程思路:
求回文数,最简单直接的方法,就是对回文数进行分解后判断,或者将数作为字符串形式完全倒置后比较是否相等。常用的做法有,对数进行循环除以10后取余数,生成新的数来比较,其中可用堆栈来处理。对求一个具体的数是否回文,此法可行,但如果是对某个数值段求回文数,此法要对每个数进行比较,时间复杂度较高。
对于数值段内的回文数,根据字符串特点构造回文数是一种较快的做法。本程序则是通过构造回文数来完成。本题要求十进制与二进制表示均为回文数,通过观察发现,在同一数值段中,二进制回文数的数量比十进制回文数的数量要小,所以,本程序先构造二进制回文数,再反过来验证对应的十进制数是否回文数,来提高效率。
package Palindrome;
/**Palindrome用于求出十进制与二进制表示都是回文数的数
* @author 郭坤06250171
* @version 1.0
*/
import java.io.*;
public class Palindrome {
/**将字符串表示的二进制数转换成十进制数
* @param strBin 用字符串表示的二进制数
*/
public static int binTodec(StringBuffer strBin){
int len;
int i;
int rValue;
//求出以字符串形式表示的二进制串的长度
len=strBin.length();
//循环求出十进制数值
rValue=0;
for(i=0;i<len;i++){
rValue=(int) (rValue+Integer.valueOf(String.valueOf(strBin.charAt(i)))*Math.pow(2, len-i-1));
}
return(rValue);
}
/**将用二进制对称表示的数,进行递归收缩,并求其和,构造出二进制表示是回文数的数;
* 并判断其十进制数是否回文,若回文且小于max,则输出。
* 构造回文数的公式:
* 当len=5时,
* 公式1:10001+01010*0+00100*0
* 公式2:10001+01010*0+00100*1
* 公式3:10001+01010*1+00100*0
* 公式4:10001+01010*1+00100*1
* @param value 递归调用前已求出的二进制对称数
* @param len 整个二进制串的字符串长度
* @param startLoc 当前设置为1的起始位置
* @param max 最大数范围
*/
public static void getPalindromebyBinary(int value,int len,int startLoc,int max){
//构造一个长度为len的字符串,每个字符设置为0
StringBuffer sBin;
int loc;
sBin=new StringBuffer();
//初始化二进制字符串
for(int i=1;i<=len;i++){
sBin.append('0');
}
//根据startLoc将对应位置的字符设置为1
sBin.setCharAt(startLoc, '1');
sBin.setCharAt(len-startLoc-1, '1');
//判断长度是奇数还是偶数
//loc用于控制是否结束循环设置1的判断
if(len%2==0){
//偶数
loc=1; }
else{
//奇数
loc=0;
}
//判断是否到最后一个二进制字符串,若是则生成最后的二进制字符串
if(startLoc==len/2-loc){
//分支0
int value0;
int value1;
value0=value + binTodec(sBin)*0;
if(String.valueOf(Integer.toBinaryString(value0)).length()==len){
StringBuffer sbvalue=new StringBuffer(String.valueOf(value0));
//判断二进制对应的十进制数是否为回文
if(sbvalue.reverse().toString().equals(String.valueOf(value0))){
if(value0<=max){
System.out.println("双回文数,十进制表示:" + value0 + ",二进制表示:" + Integer.toBinaryString(value0));
}
else{
return;
}
}
}
//分支1
value1=value + binTodec(sBin)*1;
if(String.valueOf(Integer.toBinaryString(value1)).length()==len){
StringBuffer sbvalue=new StringBuffer(String.valueOf(value1));
//判断二进制对应的十进制数是否为回文
if(sbvalue.reverse().toString().equals(String.valueOf(""+value1))){
if(value1<=max){
System.out.println("双回文数,十进制表示:" + value1 + ",二进制表示:" + Integer.toBinaryString(value1));
}
else{
return;
}
}
}
}
else{
//递归调用,产生下层数据
getPalindromebyBinary(value+binTodec(sBin)*0,len,startLoc+1,max);
getPalindromebyBinary(value+binTodec(sBin)*1,len,startLoc+1,max);
}
}
public static void main(String[] args) {
int max;
int i=1;
max=0;
System.out.println("***************************************************");
System.out.println("求十进制与二进制表示均为回文数的演算。");
System.out.println("姓名:郭坤 学号:06250171 班级:MSE2006B");
System.out.println("***************************************************");
System.out.print("请输入最大数:");
try{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
max=Integer.valueOf(br.readLine());
}
catch(IOException e){
System.out.println("错误提示:"+e.toString());
}
for(i=1;i<=Integer.toBinaryString(max).length();i++){
getPalindromebyBinary(0,i,0,max);
}
}
}