使用更好的算法寻找一个数字字符串的下一个回文数

17

首先,这是问题:

如果一个正整数在十进制下从左往右读和从右往左读都相同,则称其为回文数。对于给定不超过 1000000 位数的正整数 K,写出比 K 大的最小回文数并输出。数字不会有前导零。

输入:第一行包含整数 t,表示测试用例数。接下来的 t 行中给出了整数 K。

输出:对于每个 K,输出比 K 大的最小回文数。 示例

输入:

2

808

2133

输出:

818

2222

其次,这是我的代码:

// I know it is bad practice to not cater for erroneous input,
// however for the purpose of the execise it is omitted
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.lang.Exception;
import java.math.BigInteger;

public class Main
{    
    public static void main(String [] args){   
        try{
            Main instance = new Main(); // create an instance to access non-static
                                        // variables
        
            // Use java.util.Scanner to scan the get the input and initialise the
            // variable
            Scanner sc=null;

            BufferedReader r = new BufferedReader(new InputStreamReader(System.in));

            String input = "";

            int numberOfTests = 0;

            String k; // declare any other variables here
            
            if((input = r.readLine()) != null){
                sc = new Scanner(input);
                numberOfTests = sc.nextInt();
            }

            for (int i = 0; i < numberOfTests; i++){
                if((input = r.readLine()) != null){
                    sc = new Scanner(input);
                    k=sc.next(); // initialise the remainder of the variables sc.next()
                    instance.palindrome(k);
                } //if
            }// for
        }// try

        catch (Exception e)
        {
            e.printStackTrace();
        }
    }// main

    public void palindrome(String number){

        StringBuffer theNumber = new StringBuffer(number);
        int length = theNumber.length();
        int left, right, leftPos, rightPos;
        // if incresing a value to more than 9 the value to left (offset) need incrementing
        int offset, offsetPos;
        boolean offsetUpdated;
        // To update the string with new values
        String insert;
        boolean hasAltered = false;

        for(int i = 0; i < length/2; i++){
            leftPos = i; 
            rightPos = (length-1) - i;
            offsetPos = rightPos -1; offsetUpdated = false;
            
            // set values at opposite indices and offset
            left = Integer.parseInt(String.valueOf(theNumber.charAt(leftPos)));
            right = Integer.parseInt(String.valueOf(theNumber.charAt(rightPos)));
            offset = Integer.parseInt(String.valueOf(theNumber.charAt(offsetPos)));

            if(left != right){
                // if r > l then offest needs updating
                if(right > left){
                    // update and replace
                    right = left;
                    insert = Integer.toString(right);

                    theNumber.replace(rightPos, rightPos + 1, insert);
                
                    offset++; if (offset == 10) offset = 0;
                    insert = Integer.toString(offset);

                    theNumber.replace(offsetPos, offsetPos + 1, insert);
                    offsetUpdated = true;
               
                    // then we need to update the value to left again
                    while (offset == 0 && offsetUpdated){ 
                        offsetPos--;
                        offset =
                            Integer.parseInt(String.valueOf(theNumber.charAt(offsetPos)));
                        offset++; if (offset == 10) offset = 0;
                        // replace
                        insert = Integer.toString(offset);
                        theNumber.replace(offsetPos, offsetPos + 1, insert);
                    }
                    // finally incase right and offset are the two middle values
                    left = Integer.parseInt(String.valueOf(theNumber.charAt(leftPos)));
                    if (right != left){
                        right = left;
                        insert = Integer.toString(right);
                        theNumber.replace(rightPos, rightPos + 1, insert);
                    }
                }// if r > l
                else
                    // update and replace
                    right = left;
                    insert = Integer.toString(right);
                    theNumber.replace(rightPos, rightPos + 1, insert);           
            }// if l != r
        }// for i
        System.out.println(theNumber.toString());
    }// palindrome
}

最后是我的说明和问题。
My code compares either end and then moves in
    if left and right are not equal
        if right is greater than left
            (increasing right past 9 should increase the digit
             to its left i.e 09 ---- > 10) and continue to do
             so if require as for 89999, increasing the right
             most 9 makes the value 90000
        
             before updating my string we check that the right
             and left are equal, because in the middle e.g 78849887
             we set the 9 --> 4 and increase 4 --> 5, so we must cater for this.

这个问题来自 spoj.pl,一个在线判题系统。我的代码可以通过所有提供的测试,但是当我提交它时,我得到了一个超时错误并且我的答案没有被接受。

有人能给我一些建议如何改进我的算法吗?写这个问题的时候,我想到了一个方法,可以使用布尔值来确保我在下一个[i]迭代中增加偏移量,而不是使用 while (offset == 0 && offsetUpdated) 循环。确认我的更改或任何建议将不胜感激,也请让我知道是否需要让我的问题更清晰明了。


2
你的代码似乎无法处理测试用例(808被处理不正确)。 - n. m.
非常好的观点,但是将输入加一可以解决这个问题,而且也不会影响效率。 - Mead3000
10个回答

44

看起来这是很多的代码。你尝试过最简单的方法吗?检查一个字符串是否为回文其实非常简单。

private boolean isPalindrome(int possiblePalindrome) {
    String stringRepresentation = String.valueOf(possiblePalindrome);
    if ( stringRepresentation.equals(stringRepresentation.reverse()) ) {
       return true;
    }
}

虽然这可能不是最高效的代码,但它为您提供了一个非常简单的起点:

private int nextLargestPalindrome(int fromNumber) {
    for ( int i = fromNumber + 1; ; i++ ) {
        if ( isPalindrome( i ) ) {
            return i;
        }
    }
}

如果速度还不够快,您可以将其用作参考实现,并努力降低算法复杂度。

实际上,应该存在一种常数时间(在输入数字的位数上是线性的)的方法来查找下一个最大回文数。我将提供一个假设数字长度为偶数(但可以扩展到奇数位数)的算法。

  1. 找到输入数字的十进制表示(“2133”)。
  2. 将其分成左半部分和右半部分(“21”,“33”);
  3. 比较左半部分的最后一位和右半部分的第一位。
    a. 如果右侧大于左侧,则增加左侧并停止。 (“22”)
    b. 如果右侧小于左侧,则停止。
    c. 如果右侧等于左侧,则重复步骤3,使用左侧的倒数第二个数字和右侧的第二个数字(以此类推)。
  4. 取左半部分并将其反转后附加到左半部分。那就是您的下一个最大回文数。(“2222”)

应用于更复杂的数字:

1.    1234567887654322
2.    12345678   87654322
3.    12345678   87654322
             ^   ^         equal
3.    12345678   87654322
            ^     ^        equal
3.    12345678   87654322
           ^       ^       equal
3.    12345678   87654322
          ^         ^      equal
3.    12345678   87654322
         ^           ^     equal
3.    12345678   87654322
        ^             ^    equal
3.    12345678   87654322
       ^               ^   equal
3.    12345678   87654322
      ^                 ^  greater than, so increment the left

3.    12345679

4.    1234567997654321  answer

这似乎与您描述的算法有些相似,但它从内部数字开始并移动到外部。


3
该数字最多可能有1000000位数,因此整数类型无法使用。 使用您的算法,例如对于像8999这样的数字,在第二半部分增加值应该会对第一半产生影响。 - Mead3000
1
@Mead:这可能意味着你可以排除天真的方法。对于我发布的算法,没有任何东西说您需要将它们存储为二进制数字。您可以一直使用字符串进行处理。 - Mark Peters
3
如果您拆分整个字符串/字符特征,反转RHS子字符串并比较它们,就可以改进此内容。 如果RHS更大,则将LHS增加一。 然后结果是LHS ^ LHS_reversed。对于奇数#数字,只需弄清楚中间字符是否必须递增,然后执行明显的操作即可。 - b.buchhold
我在String类中没有看到任何reverse()方法。 - Anirban Nag 'tintinmj'
@tintinmj:你说得对,那部分是错误的;我只是想给出算法的一个想法。你可以使用StringBuilder.reverse()来反转一个字符串。 - Mark Peters
显示剩余15条评论

18

当仅需要进行一次简单的加法运算时,没有理由去玩弄单个数字。以下代码基于Raks的答案

该代码强调简单性而非执行速度,这是有意为之的。

import static org.junit.Assert.assertEquals;

import java.math.BigInteger;
import org.junit.Test;

public class NextPalindromeTest {

    public static String nextPalindrome(String num) {
        int len = num.length();
        String left = num.substring(0, len / 2);
        String middle = num.substring(len / 2, len - len / 2);
        String right = num.substring(len - len / 2);

        if (right.compareTo(reverse(left)) < 0)
            return left + middle + reverse(left);

        String next = new BigInteger(left + middle).add(BigInteger.ONE).toString();
        return next.substring(0, left.length() + middle.length())
             + reverse(next).substring(middle.length());
    }

    private static String reverse(String s) {
        return new StringBuilder(s).reverse().toString();
    }

    @Test
    public void testNextPalindrome() {
        assertEquals("5", nextPalindrome("4"));
        assertEquals("11", nextPalindrome("9"));
        assertEquals("22", nextPalindrome("15"));
        assertEquals("101", nextPalindrome("99"));
        assertEquals("151", nextPalindrome("149"));
        assertEquals("123454321", nextPalindrome("123450000"));
        assertEquals("123464321", nextPalindrome("123454322"));
    }
}

这是一个惊人的解决方案!非常感谢!! - MyName
2
这是一段非常优美的代码。不知道为什么没有得到点赞? - Ashish K Agarwal
只是确认一下,中间.length()的长度总是0(对于偶数长度数字)或1(对于奇数长度数字),是这样吗? - Gautam Tyagi
是的,middle.length() 总是 0 或 1。 - Roland Illig
一个问题:为什么在最后一行中考虑了左侧和中间的长度 next.substring(0, left.length() + middle.length()) - Saurav Sahu
@SauravSahu:你会怎么样不同地编写它? - Roland Illig

14

我有一个恒定的回文数解决方案(至少是k阶,其中k是数字的位数)

让我们举几个例子 假设n=17208

从中间将数字分为两部分,并可逆地将最重要的部分写到较不重要的部分。 即,17271 如果生成的数字大于您的n,则它就是回文数,否则只需增加中心数字(支点),即您得到17371

其他例子

n=17286 回文尝试=17271(因为它小于n,在这种情况下增加支点2) 所以回文=17371

n=5684 回文1=5665 回文=5775

n=458322 回文=458854

现在假设n = 1219901 回文1=1219121 在这里增加支点会使我的数字变小 因此也增加相邻支点的数字 1220221

并且这个逻辑可以扩展


我使用了相同的逻辑。然而,有许多需要处理的特殊情况。例如,如果n=999或n=22或n=10920怎么办。 - Ashish K Agarwal
如果您查看我实现此确切答案的代码,您将看到一个单独的if语句足以涵盖所有“许多特殊情况”。 - Roland Illig

1
public class NextPalindrome 
{   
    int rev, temp;
    int printNextPalindrome(int n) 
    {
        int num = n;
        for (int i = num+1; i >= num; i++) 
        {
            temp = i;
            rev = 0;
            while (temp != 0) 
            {
                int remainder = temp % 10;
                rev = rev * 10 + remainder;
                temp = temp / 10;
            }
            if (rev == i) 
            {
                break;
            }
        }
        return rev;
    }
    public static void main(String args[]) 
    {
        NextPalindrome np = new NextPalindrome();
        int nxtpalin = np.printNextPalindrome(11);
        System.out.println(nxtpalin);
    }



}

1
这是一个可怕的答案。 - Mox
1
@Mox 你至少应该说一下为什么这个答案是糟糕的。它之所以糟糕是因为:(1) 它只适用于最多11位数字的数字 (2) 使用字段比使用本地变量更合适 (3) “temp”从不是一个字段的适当名称;当用于交换操作时,该名称变量的最大可接受范围为大约3行的块 (4) 算法计算下一个10位回文数需要很长时间 (5) 名称“NextPalindrome”不适合用于类,尽管对于方法来说是合适的 (6) 方法“printNextPalindrome”没有打印任何东西。 - Roland Illig
@RolandIllig 谢谢您的反馈。该评论已经将近2年了。 - Mox

1

这是我的Java代码。整个想法来自这里

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        System.out.println("Enter number of tests: ");
        int t = sc.nextInt();

        for (int i = 0; i < t; i++) {
            System.out.println("Enter number: ");
            String numberToProcess = sc.next(); // ne proveravam dal su brojevi
            nextSmallestPalindrom(numberToProcess);
        }
    }

    private static void nextSmallestPalindrom(String numberToProcess) {
        

        int i, j;

        int length = numberToProcess.length();
        int[] numberAsIntArray = new int[length];
        for (int k = 0; k < length; k++)
            numberAsIntArray[k] = Integer.parseInt(String
                    .valueOf(numberToProcess.charAt(k)));

        numberToProcess = null;

        boolean all9 = true;
        for (int k = 0; k < length; k++) {
            if (numberAsIntArray[k] != 9) {
                all9 = false;
                break;
            }
        }
        // case 1, sve 9ke
        if (all9) {
            whenAll9(length);
            return;
        }

        int mid = length / 2;
        if (length % 2 == 0) {
            i = mid - 1;
            j = mid;
        } else {
            i = mid - 1;
            j = mid + 1;
        }
        
        while (i >= 0 && numberAsIntArray[i] == numberAsIntArray[j]) {
            i--;
            j++;
        }
        // case 2 already polindrom
        if (i == -1) {
            if (length % 2 == 0) {
                i = mid - 1;
                j = mid;
            } else {
                i = mid;
                j = i;
            }
            addOneToMiddleWithCarry(numberAsIntArray, i, j, true);

        } else {
            // case 3 not polindrom
            if (numberAsIntArray[i] > numberAsIntArray[j]) { // 3.1)
                
                while (i >= 0) {
                    numberAsIntArray[j] = numberAsIntArray[i];
                    i--;
                    j++;
                }
                for (int k = 0; k < numberAsIntArray.length; k++)
                    System.out.print(numberAsIntArray[k]);
                System.out.println();
            } else { // 3.2 like case 2
                if (length % 2 == 0) {
                    i = mid - 1;
                    j = mid;
                } else {
                    i = mid;
                    j = i;
                }
                addOneToMiddleWithCarry(numberAsIntArray, i, j, false);
            }
        }
    }

    private static void whenAll9(int length) {
        
        for (int i = 0; i <= length; i++) {
            if (i == 0 || i == length)
                System.out.print('1');
            else
                System.out.print('0');
        }
    }

    private static void addOneToMiddleWithCarry(int[] numberAsIntArray, int i,
            int j, boolean palindrom) {
        numberAsIntArray[i]++;
        numberAsIntArray[j] = numberAsIntArray[i];
        while (numberAsIntArray[i] == 10) {
            numberAsIntArray[i] = 0;
            numberAsIntArray[j] = numberAsIntArray[i];
            i--;
            j++;
            numberAsIntArray[i]++;
            numberAsIntArray[j] = numberAsIntArray[i];
        }
        
        if (!palindrom)
            while (i >= 0) {
                numberAsIntArray[j] = numberAsIntArray[i];
                i--;
                j++;
            }
        
        for (int k = 0; k < numberAsIntArray.length; k++)
            System.out.print(numberAsIntArray[k]);
        System.out.println();
    }

}

1
我敢打赌,有一种方法可以让这段代码更短,并且可以通过单元测试进行测试。 - Roland Illig

0

试试这个

public static String genNextPalin(String base){
    //check if it is 1 digit
    if(base.length()==1){
        if(Integer.parseInt(base)==9)
            return "11";
        else
            return (Integer.parseInt(base)+1)+"";
    }
    boolean check = true;
    //check if it is all 9s
    for(char a: base.toCharArray()){
        if(a!='9')
            check = false;
    }
    if(check){
        String num = "1";
        for(int i=0; i<base.length()-1; i++)
            num+="0";
        num+="1";
        return num;
    }

    boolean isBasePalin = isPalindrome(base);
    int mid = base.length()/2;
    if(isBasePalin){
        //if base is palin and it is odd increase mid and return
        if(base.length()%2==1){
            BigInteger leftHalf = new BigInteger(base.substring(0,mid+1));
            String newLeftHalf = leftHalf.add(BigInteger.ONE).toString();
            String newPalin = genPalin2(newLeftHalf.substring(0,mid),newLeftHalf.charAt(mid));
            return newPalin;
        }
        else{
            BigInteger leftHalf = new BigInteger(base.substring(0,mid));
            String newLeftHalf = leftHalf.add(BigInteger.ONE).toString();
            String newPalin = genPalin(newLeftHalf.substring(0,mid));
            return newPalin;
        }
    }
    else{
        if(base.length()%2==1){
            BigInteger leftHalf = new BigInteger(base.substring(0,mid));
            BigInteger rightHalf = new BigInteger(reverse(base.substring(mid+1,base.length())));

            //check if leftHalf is greater than right half
            if(leftHalf.compareTo(rightHalf)==1){
                String newPalin = genPalin2(base.substring(0,mid),base.charAt(mid));
                return newPalin;
            }
            else{
                BigInteger leftHalfMid = new BigInteger(base.substring(0,mid+1));
                String newLeftHalfMid = leftHalfMid.add(BigInteger.ONE).toString();
                String newPalin = genPalin2(newLeftHalfMid.substring(0,mid),newLeftHalfMid.charAt(mid));
                return newPalin;
            }
        }
        else{
            BigInteger leftHalf = new BigInteger(base.substring(0,mid));
            BigInteger rightHalf = new BigInteger(reverse(base.substring(mid,base.length())));

            //check if leftHalf is greater than right half
            if(leftHalf.compareTo(rightHalf)==1){
                return genPalin(base.substring(0,mid));
            }
            else{
                BigInteger leftHalfMid = new BigInteger(base.substring(0,mid));
                String newLeftHalfMid = leftHalfMid.add(BigInteger.ONE).toString(); 
                return genPalin(newLeftHalfMid);
            }
        }
    }
}

public static String genPalin(String base){
    return base + new StringBuffer(base).reverse().toString();
}
public static String genPalin2(String base, char middle){
    return base + middle +new StringBuffer(base).reverse().toString();
}

public static String reverse(String in){
    return new StringBuffer(in).reverse().toString();
}

static boolean isPalindrome(String str) {    
    int n = str.length();
    for( int i = 0; i < n/2; i++ )
        if (str.charAt(i) != str.charAt(n-i-1)) 
            return false;
    return true;    
}

那是非常复杂的代码。肯定有更优雅的写法。 - Roland Illig

-1

我已经写了注释来解释这段Python代码中每个步骤的作用。

需要考虑的一件事是,输入可能非常大,我们不能简单地对其执行整数操作。因此,将输入作为字符串然后进行操作会更加容易。

tests = int(input())
results = []
for i in range(0, tests):
    pal = input().strip()
    palen = len(pal)
    mid = int(palen/2)
    if palen % 2 != 0:
        if mid == 0: # if the number is of single digit e.g. next palindrome for 5 is 6 
            ipal = int(pal)
            if ipal < 9:
                results.append(int(pal) + 1)
            else:
                results.append(11) # for 9 next palindrome will be 11
        else:
            pal = list(pal)
            pl = l = mid - 1
            pr = r = mid + 1
            flag = 'n' # represents left and right half of input string are same
            while pl >= 0:
                if pal[pl] > pal[pr]:
                    flag = 'r' # 123483489 in this case pal[pl] = 4 and pal[pr] = 3 so we just need to copy left half in right half
                    break      # 123484321 will be the answer
                elif pal[pl] < pal[pr]:
                    flag = 'm' # 123487489 in this case pal[pl] = 4 and pal[pr] = 9 so copying left half in right half will make number smaller
                    break # in this case we need to take left half increment by 1 and the copy in right half 123494321 will be the anwere
                else:
                    pl = pl -1
                    pr = pr + 1
            if flag == 'm' or flag == 'n': # increment left half by one and copy in right half
                if pal[mid] != '9': # if mid element is < 9 the we can simply increment the mid number only and copy left in right half
                        pal[mid] = str(int(pal[mid]) + 1)
                        while r < palen:
                            pal[r] = pal[l]
                            r = r + 1
                            l = l - 1
                        results.append(''.join(pal))
                else: # if mid element is 9 this will effect entire left half because of carry
                    pal[mid] = '0' # we need to take care of large inputs so we can not just directly add 1 in left half
                    pl = l
                    while pal[l] == '9':
                        pal[l] = '0'
                        l = l - 1
                    if l >= 0:
                        pal[l] = str(int(pal[l]) + 1)
                    while r < palen:
                        pal[r] = pal[pl]
                        r = r + 1
                        pl = pl - 1
                    if l < 0:
                        pal[0] = '1'
                        pal[palen - 1] = '01'
                    results.append(''.join(pal))
            else:
                while r < palen: # when flag is 'r'
                    pal[r] = pal[l]
                    r = r + 1
                    l = l - 1
                results.append(''.join(pal))
    else: # even length almost similar concept here with flags having similar significance as in case of odd length input
        pal = list(pal)
        pr = r = mid
        pl = l = mid - 1
        flag = 'n'
        while pl >= 0:
            if pal[pl] > pal[pr]:
                flag = 'r'
                break
            elif pal[pl] < pal[pr]:
                flag = 'm'
                break
            else:
                pl = pl -1
                pr = pr + 1
        if flag == 'r':
            while r < palen:
                    pal[r] = pal[l]
                    r = r + 1
                    l = l - 1
            results.append(''.join(pal))
        else:
            if pal[l] != '9':
                pal[l] = str(int(pal[l]) + 1)
                while r < palen:
                    pal[r] = pal[l]
                    r = r + 1
                    l = l - 1
                results.append(''.join(pal))
            else:
                pal[mid] = '0'
                pl = l
                while pal[l] == '9':
                    pal[l] = '0'
                    l = l - 1
                if l >= 0:
                    pal[l] = str(int(pal[l]) + 1)
                while r < palen:
                    pal[r] = pal[pl]
                    r = r + 1
                    pl = pl - 1
                if l < 0:
                    pal[0] = '1'
                    pal[palen - 1] = '01'
                results.append(''.join(pal))

for xx in results:
    print(xx) 

我已在代码中提供了注释,以使事情更清晰。如果有任何特定的投票下降原因或者它在任何测试用例中失败,请发表评论。 - quintin
1
(1) 你的代码比必要的长得多。 (2) 它没有定义一个适当命名的函数来表达抽象。 (3) xx 是一个糟糕的变量名,因为它不向人类读者传递任何信息。 (4) 代码中没有段落,给读者停下来喘口气的机会。 (5) 它使用了魔法值 n、r、m 作为标志;标志通常具有布尔类型。 (6) 它并不清楚 results 包含什么,因为它在循环中打印出来,而 nextPalindrome 应该明确返回单个字符串或数字。 - Roland Illig

-1

嗨,这里有另一个使用Python的简单算法:

  def is_palindrome(n):
      if len(n) <= 1:
          return False
      else:
          m = len(n)/2
          for i in range(m):
              j = i + 1
              if n[i] != n[-j]:
                  return False
          return True

  def next_palindrome(n):
      if not n:
          return False
      else:
          if is_palindrome(n) is True:
              return n
          else:
             return next_palindrome(str(int(n)+1))

  print next_palindrome('1000010')

这不是一个高效的解决方案。另外,为了检查它是否是回文,我们可以使用这个: str(a) == ''.join(reversed(str(a))) - coding_pleasures
当然我们可以做到,但是面试官不允许使用内置函数。 - James Sapam

-1
我们可以轻松地像下面这样找到下一个回文数。
private void findNextPalindrom(int i) {
    i++;
    while (!checkPalindrom(i)) {
        i++;
    }
    Log.e(TAG, "findNextPalindrom:next palindrom is===" + i);
}


private boolean checkPalindrom(int num) {
    int temp = num;
    int rev = 0;
    while (num > 0) {
        int rem = num % 10;
        rev = rev * 10 + rem;
        num = num / 10;
    }
    return temp == rev;
}

这种方法仅适用于非常小的数字。OP正在寻求一个可以处理1000位数的解决方案。 - Roland Illig

-2

简单的代码和测试输出:

class NextPalin
{
public static void main( String[] args )
{
    try {
        int[] a = {2, 23, 88, 234, 432, 464, 7887, 7657, 34567, 99874, 7779222, 2569981, 3346990, 229999, 2299999 };
        for( int i=0; i<a.length; i++)
        {
            int add = findNextPalin(a[i]);
            System.out.println( a[i] + "  +  "  + add +  "  = "  + (a[i]+add)  );
        }
    }
    catch( Exception e ){}
}

static int findNextPalin( int a ) throws Exception
{
    if( a < 0 ) throw new Exception();
    if( a < 10 ) return a;

    int count = 0, reverse = 0, temp = a;
    while( temp > 0 ){
        reverse = reverse*10 + temp%10;
        count++;
        temp /= 10;
    }

    //compare 'half' value
    int halfcount = count/2;
    int base = (int)Math.pow(10, halfcount );
    int reverseHalfValue = reverse % base;
    int currentHalfValue = a % base;

    if( reverseHalfValue == currentHalfValue ) return 0;
    if( reverseHalfValue > currentHalfValue )  return  (reverseHalfValue - currentHalfValue);

    if(  (((a-currentHalfValue)/base)%10) == 9 ){
        //cases like 12945 or 1995
        int newValue = a-currentHalfValue + base*10;
        int diff = findNextPalin(newValue);
        return base*10 - currentHalfValue + diff;
    }
    else{
        return (base - currentHalfValue + reverseHalfValue );
    }
}
}

$ java NextPalin
2  +  2  = 4
23  +  9  = 32
88  +  0  = 88
234  +  8  = 242
432  +  2  = 434
464  +  0  = 464
7887  +  0  = 7887
7657  +  10  = 7667
34567  +  76  = 34643
99874  +  25  = 99899
7779222  +  555  = 7779777
2569981  +  9771  = 2579752
3346990  +  443  = 3347433
229999  +  9933  = 239932
2299999  +  9033  = 2309032

3
(1) 代码转储不是答案。也许可以解释一下你做了什么,它是如何工作的等等。 (2) 你看到那部分提到数字长达一百万位数了吗?整数行不通...远远不够用。 - cHao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接