Java算法:根据输入的数字计算所有的回文数

  • Post author:
  • Post category:java


原创作品,允许转载,转载时请务必以超链接形式标明文章

原始出处

、作者信息和本人声明。否则将追究法律责任。

作者:

永恒の_☆

地址:

http://write.blog.csdn.net/postedit/17849385

问题

如果一个数正着读和反着读一样大,则这个数叫做回文数,例如121是回文数,123454321是回文数。 现给定一个正整数x,输出一个回文数y,要求y > x,并且组成x的所有数字之和与组成y的所有数字之和相等,以及y > x。 x在10^1000以内,因为数字较大,我们用字符串作为输入和输出。 如果无解,请输出Impossible。如果有多个y,输出最小的那个。

解答

1、解决思路

<1>首先要保证输入的数字是正整数,并且大于等于10,小于等于1000;

<2>然后需要计算输入的数字 的所有数字之和;

<3>再根据这个和依次拆分数字组成x的所有数字之和与组成y的所有数字之和相等,首先中间-2,首位和末位+1,然后递归下去直到结束,否则需要考虑-2以前的时候当前数字<10,并且判断回文数的时候需要满足首位与末位相等以外,还要保证y > x;

<4>最后根据返回的拼接字符串判断是否是回文数;

<5>统计所有满足条件的回文数,显示出来。

2、具体实现

import java.util.Scanner;

/**
 * 根据输入的整数返回回文数的demo
 * @author Administrator
 *
 */
public class HuiWenShuDemo {
	public static int huiwenCount = 0;
	
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.print("请输入一个正整数:");
		int num = scanner.nextInt();
		if( ! (num>=10 && num<=1000 ) ){
			System.err.println("输入的整数不满足规范。");
			return;
		}
		int total = calcNumTotal(num);
		calcHuiWenNum(total,num);

		if(huiwenCount==0){
			System.out.println("Impossible");
		}else{
			System.out.println("总共统计出回文数有"+ huiwenCount + "个!");
		}
	}
	
	/**
	 * 根据传递的参数,返回该整数 所有数字之和
	 * @param num
	 * @return
	 */
	public static int calcNumTotal(int num){
		int total = 0;
		String tempStr = String.valueOf(num);
		for (int i = 0; i < tempStr.length(); i++) {
			total = total + Integer.valueOf(tempStr.subSequence(i, i+1).toString());
		}
		return total;
	}
	

	/**
	 * 根据传递的参数判断是否是回文数
	 * @param num
	 * @return
	 */
	public static boolean isHuiWenNum(int newNum, int oldNum){
		if(oldNum >= newNum){
			return false;
		}
		String tempStr = String.valueOf(newNum);
		int tempLoop = tempStr.length() / 2;
		for(int i=0; i < tempLoop; i++){
			//System.out.println(tempStr.subSequence(i, i+1).toString() + "__" + tempStr.subSequence(tempStr.length()-i-1, tempStr.length()-i).toString());
			if(!tempStr.subSequence(i, i+1).toString().equals(tempStr.subSequence(tempStr.length()-i-1, tempStr.length()-i).toString())){
				return false;
			}
		}
		if(calcNumTotal(newNum)!=calcNumTotal(oldNum)){
			return false;
		}
		return true;
	}
	
	/**
	 * 统计所有满足条件的回文数
	 * @param total
	 * @param oldNum
	 */
	public static void calcHuiWenNum(int total, int oldNum){
		int tempLoop = total / 2;
		for(int i = 1; i < tempLoop; i++){
			int index = 1;
			int temp = total - 2 * i;
			calcHuiWenDetail(temp, i, oldNum);
		}	
	}	
	
	/**
	 * 递归拆分当前传递的temp变量,取出满足条件的数字拼接之后匹配是否回文数
	 * @param temp
	 * @param i
	 * @param oldNum
	 */
	public static void calcHuiWenDetail(int temp, int i, int oldNum){
		if(temp >= 0){
			if(temp>9){ //大于9就会出问题,组成x的所有数字之和与组成y的所有数字之和不相等
				//这里还需要做处理,但是不会啊!!
			}
			String jiaVal = "";
			for(int j=0; j<i; j++){
				jiaVal += String.valueOf(i);
			}
			String newNum = jiaVal + String.valueOf(temp) + jiaVal;
			//System.out.println("newNum:" + newNum);
			if(newNum.length()>9){  //如果超过2的31次方就会报转换出错!
				return;
			}
			if(isHuiWenNum(Integer.valueOf(newNum).intValue(),oldNum)){
				System.out.println(newNum + ": 回文数!");
				huiwenCount++;
			}
			int temp_1 = temp - 2 * i;
			calcHuiWenDetail(temp_1, i, oldNum); //如果temp_1大于等于0就表示可以继续拆分。
			//这里还有一个问题,回文数都是成双成对的,比如12321满足,同样21312也满足,可是目前还没有实现。
		}
	}
}

目前测试发现的问题有:

<1>在从最大数开始拆分的时候,被拆分的数如果大于9,组成x的所有数字之和与组成y的所有数字之和不相等,并且这个时候被拆分数仍旧可以继续拆分,这部分现在还没做处理;

<2>在递归拆分的时候考虑不周全,没有把所有的拆分元素加进去,而是通过下标完成的,比如添加的都是11、 22、  33等等元素 ;

<3>这里还有一个问题,回文数都是成双成对的,比如12321满足,同样21312也满足,可是目前还没有实现。

3、简单效果

<1>输入999,效果如下:

<2>输入234,效果如下:


<3>输入3,效果如下:


<4>输入11,效果如下:



版权声明:本文为ch656409110原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。