以下程序采用输入数k并生成大于k的回文。输入数字k可以是1000000位。
我使用java.math.BigInteger
类使用jdk 1.6在Java中实现了上述程序。
以下是代码:
import java.math.BigInteger;
class Palindrome
{
private BigInteger reverse(BigInteger inputNumber)
{
BigInteger reversedNumber = new BigInteger("0");
while(inputNumber.compareTo(BigInteger.ZERO) > 0)
{
reversedNumber = reversedNumber.multiply(BigInteger.TEN);
reversedNumber = reversedNumber.abs().add(inputNumber.mod(BigInteger.TEN));
inputNumber = inputNumber.divide(BigInteger.TEN);
}
return reversedNumber;
}
public BigInteger nextPalindrome(BigInteger inputNumber)
{
BigInteger i = new BigInteger(inputNumber.toString());
for(i=i.add(BigInteger.ONE);;i=i.add(BigInteger.ONE))
{
if(i.equals(reverse(i)))
return i;
}
}
}
public class NextPalindrome {
public static void main(String args[]) throws Exception
{
java.util.Scanner input = new java.util.Scanner(System.in);
Palindrome p = new Palindrome();
BigInteger inputNumber = input.nextBigInteger(); //To store 1000000 digit number
System.out.println(p.nextPalindrome(inputNumber));
}
}
该代码适用于以下输入:
输入:808,输出:818
输入:1311,输出:1331
输入:123456789,输出:123464321
但输入时:123456789123456789,未生成输出
如何针对更大的输入优化代码?
答案 0 :(得分:0)
编写自己的自定义算法。不要像你那样使用BigInteger
。你使用的当前算法:1)是直截了当,琐碎的,相当蛮力; 2)使用BigInteger
可以在不使用它的情况下使用它。
答案 1 :(得分:0)
我假设问题是在输入后返回 next 回文。
这是一种有效的方法:
将BigInteger
转换为char[]
。通过反映上半部分来更改char[]
的后半部分。将结果转换为BigInteger
。如果此BigInteger
大于原始版本,请将其返回。否则,将char[]
的第一个 half 转换为BigInteger
,添加一个,转换回char[]
,反映它,转换回{{ 1}},并将其归还。
这是基本算法,但有两个可能的陷阱。 (1)您必须注意确保算法适用于偶数和奇数长度的字符串。 (2)你还必须特别注意数字以9s开头的情况(在这种情况下,结果的数字可能比原始数字多)。
祝你好运!答案 2 :(得分:0)
我可能根本不会使用BigInteger
,主要是因为这里没有涉及算术。数字是否为回文可以通过将数字转换为字符串,并将字符串与反向进行比较来完成。
所以,第一个选择是你写一个这样的方法:
private static boolean isPalindrome(String number) {
return new StringBuilder(number).reverse().toString().equals(number);
}
从开始的每个BigInteger
,将其转换为字符串,并调用此方法,直到你得到回文。
但是这种方法仍然很重,因为您将继续创建新的BigInteger
对象(通过继续添加1
)。因此,诀窍是,通过在结束索引处设置字符来转换给定数字(作为字符串),匹配相应起始索引的字符。
让我们考虑你的号码123456789
。这个过程是这样的:
start = 0
,end = str.length() - 1
如果end
char大于start
char,请将结束字符设置为start char。因此,在这种情况下,当前startChar为'1'
,endChar为'9'
。因此,大于此数字的最小回文将'1'
作为最后一个字符,因此我们将'9'
替换为'1'
。该数字变为: 12345678 1 。
(一个)。如果end
char大于start
char和end == start + 1
,则只需将start
char设置为end
char并退出。
但是我们通过将最后一个索引设置为较低的值来减少数量。所以,让我们将end - 1
索引增加1
。数字 12345678 1 将更改为 - > 1234567的 9 强> 1
end
索引处的字符小于start
索引处的字符。123464321
。start > end
。这里算法将停止。结果为123464321
。但假设您的号码是:126456389
,那么在第5步,您的号码将是: 12 6 456 4 21 (使用start = 2
和end = str.length() - 2
)
继续第5步:
一旦start > end
条件到达,你就会将你的回文记录在字符串中。
以下是上述算法的代码:
public static String getNextPalindrome(String number) {
char[] str = number.toCharArray();
int front = 0;
int back = str.length - 1;
while (front < back) {
if (str[back] > str[front]) {
if (back == front + 1) {
str[front] = str[back];
} else {
str[back] = str[front];
str[back - 1] = (char) (str[back - 1] + 1);
}
} else if (str[back] < str[front]) {
str[back] = str[front];
}
front++;
back--;
}
return new String(str);
}
注意:上述算法尚未考虑数字已经是回文的情况。我会把它留给你(虽然这是一件小事)。