这篇文章讲述的是算法趣味整数部分的回文数问题的java实现,参考的书籍为清华大学出版社出版,贾蓓等编著的《c语言趣味编程1000例》,如有错误或者不当之处,还望各位大神批评指正。
问题描述
打印所有不超过n(假设n<256)的其平方具有对称性质的数(也称回文数)
算法分析
先遍历0-n中每一个数,取其平方再判断是不是回文数即可,为了方便可以借助栈(栈的特性是先进后出):
- 将前一半放入栈中
- 取后一半若与栈顶元素相同则出栈
- 判断若栈为空则是回文数
还有一种方式:将元素按位放入数组中,再前后判断
代码实现
第一种方式(借助栈)
- 关于java中栈的实现请见本人另一篇博客
https://blog.csdn.net/u013634252/article/details/80814098
package funnyInteger;
public class Q4_PalindromeNumber {
/**
* 问题描述:打印所有不超过n(假设n<256)的其平方具有对称性质的数(也称回文数)
*
* 算法分析:先遍历0-n中每一个数,取其平方再判断是不是回文数即可,为了方便可以借助
* 栈(栈的特性是先进后出):
* 1. 将前一半放入栈中
* 2. 取后一半若与栈顶元素相同则出栈
* 3. 判断若栈为空则是回文数
* 还有一种方式:将元素按位放入数组中,再前后判断
*/
public static void main(String[] args) {
method1() ;
}
private static void method1(){
/*初始化判断范围*/
int n = 256 ;
int num = 1 ;
/*循环判断0~n(假设n为256)*/
for(int i=0 ; i<=n ; i++){
/*初始化栈*/
Stack stack = new Stack() ;
stack.init();
/*取i的平方*/
int square = i*i ;
/*计算square的长度*/
int length = getLength(square) ;
/*计算底数a 用于取出i的前一半*/
int a = 1 ;
for(int p=0 ; p<length ; p++)
a*=10 ;
/*将n的前一半按位放入栈中*/
int half = length/2 ;
for(int j=0 ; j<half ; j++){ //范围为0~length/2
//System.out.println("push--"+(square%a)/(a/10));
stack.push( (square%a)/(a/10)) ;
a /= 10 ;
}
/*计算底数b 用于取出i的后一半*/
int b = 1 ;
for(int p=0 ; p<half ; p++)
b*=10 ;
/*按位取出n的后一半,若与栈顶相同元素出栈*/
while(stack.getTop().data!=null && b/10 != 0 ){
//System.out.println("top--"+stack.getTop().data);
int data = (square%b)/(b/10) ;
if(stack.getTop().data.equals( data )){
stack.pop();
}
b /= 10 ;
}
/*判断若栈为空,则为回文数,输出*/
if(stack.isEmpty()){
System.out.println("序号:"+num+" 数字:"+i+" 回文数:"+square);
num++ ;
}
}
}
/*求参数number的长度*/
private static int getLength(Integer number){
int length = 1 ;
while(number/10>0){
length++ ;
number /= 10 ;
}
return length ;
}
第二种方式(使用数组)
package funnyInteger;
public class Q4_PalindromeNumber {
/**
* 问题描述:打印所有不超过n(假设n<256)的其平方具有对称性质的数(也称回文数)
*
* 算法分析:先遍历0-n中每一个数,取其平方再判断是不是回文数即可,为了方便可以借助
* 栈(栈的特性是先进后出):
* 1. 将前一半放入栈中
* 2. 取后一半若与栈顶元素相同则出栈
* 3. 判断若栈为空则是回文数
* 还有一种方式:将元素按位放入数组中,再前后判断
*/
public static void main(String[] args) {
method2() ;
}
/*利用数组实现*/
private static void method2(){
/*初始化判断范围*/
int n = 256 ;
int num = 1 ;
/*循环判断0~n(假设n为256)*/
for(int i=0 ; i<=n ; i++){
/*取平方*/
int square = i*i ;
/*求长度*/
int length = getLength(square) ;
/*定义一个数组用于存放分解好的数字结果*/
int []arr = numToArr(square) ;
int offset = 0 ; //定义一个便宜量用来比较数组前后数字
boolean flag = true ;
while(offset <= (length/2)){
int front = 0+offset ;
int behind = length-offset-1 ;
if(arr[front] != arr[behind]){ //若字符中有一个不相同则将标志位制为false
flag = false ;
}
offset++ ;
}
if(flag){
System.out.println("序号:"+num+" 数字:"+i+" 回文数:"+square);
num++ ;
}
}
}
/*求参数number的长度*/
private static int getLength(Integer number){
int length = 1 ;
while(number/10>0){
length++ ;
number /= 10 ;
}
return length ;
}
private static int [] numToArr(int num){
/*获取数字的长度*/
int length = getLength(num) ;
/*初始化存放结果的数组*/
int arr[] = new int [length] ;
/*计算底数用于取出每一位的数*/
int a = 1 ;
for(int j=0 ; j<length ; j++)
a *= 10 ;
int i = 0 ; //存放索引
while(a/10 > 0){
arr[i] = (num%a)/(a/10) ;
a /= 10 ;
i++ ;
}
return arr ;
}
}
样例输出
序号:1 数字:0 回文数:0
序号:2 数字:1 回文数:1
序号:3 数字:2 回文数:4
序号:4 数字:3 回文数:9
序号:5 数字:11 回文数:121
序号:6 数字:22 回文数:484
序号:7 数字:26 回文数:676
序号:8 数字:101 回文数:10201
序号:9 数字:111 回文数:12321
序号:10 数字:121 回文数:14641
序号:11 数字:202 回文数:40804
序号:12 数字:212 回文数:44944