使用BigInteger检查Palindromes

时间:2015-06-15 09:31:07

标签: java

我目前正在研究/r/dailyprogramming challenge来计算将数字转换为回文数所需的步数。例如24步骤后得到回文:66 - > 24 + 42 = 66。

该程序正在运行,因为其中一个输入非常大,我选择使用BigInteger来解决我使用常规整数的溢出问题。

最初我使用的代码类似于LeetCode上的代码来检查一个值是否为回文,这对于没有导致溢出的输入有效:

原始代码示例用于检查Palindrome:

public int reverse(int x) {

    //flag marks if x is negative
    boolean flag = false;

    if (x < 0) {
        x = 0 - x;
        flag = true;
    }

    int res = 0;
    int p = x;

    while (p > 0) {
        int mod = p % 10;
        p = p / 10;
        res = res * 10 + mod;
    }

    if (flag) {
        res = 0 - res;
    }

    return res;
}

我已更新此代码以说明我对BigInteger的使用。然而更新的代码无限循环,因为从未检测到回文,所以它继续反转并添加 - 我已经通过程序几次现在我无法确定我从我编写的原始代码错误地转换到哪里

Making_Numbers_Palindromic:

public class Making_Numbers_Palindromic {

private BigInteger originalNumber;
private int count = 0;

public void run(BigInteger number) {
    assert (checkPositive(number));

    originalNumber = number;

    boolean flag = false;
    while (!flag) {
        if (checkPalindrome(number)) {
            System.out.printf("%d gets palindromic after" + 
                  "%d steps: %d", originalNumber, count, number);
            System.exit(1);
        }
        number = addReverse(number);
        count++;
    }
}

/**
 * @param number
 * @return BigInteger#signum returns 1 if the value is positive
 */
public boolean checkPositive(BigInteger number) {
    if (number.compareTo(BigInteger.ZERO) == 1) {
        return true;
    }
    return false;
}

public boolean checkPalindrome(BigInteger number) {
    if (number.compareTo(BigInteger.ZERO) < 0) return false;

    BigInteger div = new BigInteger("1");

    while ((number.divide(div)).compareTo(BigInteger.TEN) >= 0) {
        div = div.multiply(BigInteger.TEN);
    }

    while (!number.equals(new BigInteger("0"))) {
        BigInteger len = number.divide(div);
        BigInteger revs = number.mod(BigInteger.TEN);

        if (!len.equals(revs)) return false;

        number = (number.mod(div)).divide(BigInteger.TEN);
        div = div.divide(BigInteger.TEN);
    }
    return true;
}

public BigInteger addReverse(BigInteger number) {
    return number.add(reverse(number));
}

public BigInteger reverse(BigInteger number) {
    boolean flag = false;
    BigInteger reverse = new BigInteger("0");
    BigInteger numCopy = number;

    if (number.compareTo(BigInteger.ZERO) == -1) {
        flag = true;
    }

    while (numCopy.compareTo(BigInteger.ZERO) > 0) {
        BigInteger mod = numCopy.mod(BigInteger.TEN);
        numCopy = numCopy.divide(BigInteger.TEN);
        reverse = (reverse.multiply(BigInteger.TEN)).add(mod);
    }

    if (flag) {
        reverse = BigInteger.ZERO.subtract(reverse);
    }
    return reverse;
  }
}

这是我第一次使用BigInteger而且我已经看过JavaDocs了 - 但是看不出任何明显可能与我使用BigInteger#compare或BigInteger#equals

有关的错误

主要方法:

public class Bootstrap {
    public static void main(String[] args) {

    Making_Numbers_Palindromic mnp = new Making_Numbers_Palindromic();

    if (args.length > 0) {
         mnp.run(BigInteger.valueOf(Integer.parseInt(args[0])));
    } else {
        System.out.printf("Usage: Palindromic Number");
    }
  }
}

我打算让Making_Numbers_Palindromic成为一个私有构造函数,所以我可以像实用工具类一样使用它,我还没有解决它。

感谢您

1 个答案:

答案 0 :(得分:1)

不确定这是唯一的错误,但在checkPalindrome

div = div.divide(BigInteger.TEN);

应该是

div = div.divide(BigInteger.valueOf(100));

因为在比较数字的第一个和最后一个数字后,您将丢弃它们,因此下一次迭代的div应该比当前div小100倍。

也就是说,即使你修复了所有的错误,你也会做你应该做的工作的两倍,因为如果你反转这个数字,你可以用反转的数字来确定原来是否是回文(通过比较原来的反转数字)。