ProjectEuler解决方案返回错误的答案

时间:2016-02-14 19:10:18

标签: java math

我试图解决的问题来自ProjectEuler。

有些整数具有以下属性:

n + reverse(n) = a number consisting entirely of odd digits. 

例如:

14: 14 + 41 = 55

不允许以0开头或结尾的数字。

10^9以下有多少“可逆”数字?

问题也给出了提示:

  

在1000以下有120个这样的数字。

我对Java很陌生,我试图通过编写一个检查所有数字达到十亿的程序来解决这个问题,这不是最好的方法,我知道,但我很好。

问题是我的程序发出了错误的数字,我无法弄清楚原因! (代码很可能包含一些丑陋的东西,随时以任何方式改进它)

int result = 0;
boolean isOdd = true;
boolean hasNo0 = true;

public int reverseNumber(int r)    //this method should be working 
{                          //guess the main problem is in the second method
    int n = 0;
    String m = "";
    if (r % 10 == 0) { hasNo0 = false; }
    while (r > 0){
    n = r % 10;
    m = String.valueOf(m+n);    
    r /= 10;                       
    }
    result = Integer.parseInt(m);  
    return result;
}

public void isSumOdd(int max)
{
    int number = 1;
    int sum = 0;
    Sums reverseIt = new Sums();
    int amount = 0;

    while (number <= max)
    {
        sum = reverseIt.reverseNumber(number) + number;
        while (sum > 0)
        {
            int x = sum % 10;
            if (x % 2 == 0) { isOdd = false; }
            sum /= 10;
        }
        if (isOdd && hasNo0) { amount++; }
        number++;
        isOdd = true;
        hasNo0 = true;
    }
    System.out.println(amount);
}

调用
Sums first = new Sums();
first.reversibleNumbers(1000000000);

5 个答案:

答案 0 :(得分:1)

代码中最重要的问题是以下行:

  

sum = reverseIt.reverseNumber(number)+ number;

isSumOdd(int max)函数中的

。这里reverseIt对象是Sums类的新实例。由于在使用新实例时使用Sums成员数据(boolean变量)来表示某些条件,因此这些成员变量的值不会复制到当前调用者对象。您必须将该行更改为:

  

sum = this.reverseNumber(number)+ number;

并删除Sums reverseIt = new Sums();声明和初始化。

编辑:尝试解释为什么不需要实例化新对象实例来调用方法 - 我发现以下答案解释了function(object)methodhttps://stackoverflow.com/a/155655/25429。 IMO解释应该足够了(您不需要新对象,因为成员方法已经可以访问对象中的成员数据。)

答案 1 :(得分:0)

当您使用以下代码检查下一个数字时,您会覆盖给定数字的奇数检查:isOdd = false;。因此,在结果中,您只检查第一个数字是否为奇数。 你应该用

替换这一行
idOdd = idOdd && (x % 2 == 0);

顺便说一句。您应该能够通过简单的单元测试轻松跟踪这样的错误,我建议这样做。

答案 2 :(得分:0)

这里的一个关键问题是你的reverseNumber方法有两件事:检查数字是否为零,是否反转了数字。我知道如果数字是10的倍数,你想忽略结果(或者实际上,你没有结果)。因此,你有两种方法:

  1. 如果数字不是10的倍数,则仅将数字发送到reverseNumber。这称为方法的前提条件,可能是最简单的解决方案。
  2. 让您的方法无法回馈结果。这是一种名为"Functional Programming"的编程领域的流行技术,通常使用名为Monad的工具实现。在Java中,这些是使用Optional<>类实现的。这些允许你的方法(总是必须返回某些东西)来返回一个对象,这意味着什么都没有&#34;。这些将允许您知道您的方法是否由于某种原因无法或不愿意给您一个结果(在这种情况下,数字中的数字为零)。

答案 3 :(得分:0)

这是一个快速工作的代码段:

class Prgm
{
    public static void main(String args[])
    {
        int max=(int)Math.pow(10, 3);    //change it to (10, 9) for 10^9
        for(int i=1;i<=max;i++)
        {
            if(i%10==0)
                continue;
            String num=Integer.toString(i);
            String reverseNum=new StringBuffer(num).reverse().toString();
            String sum=(new Long(i+Long.parseLong(reverseNum))).toString();
            if(sum.matches("^[13579]+$"))
                System.out.println(i);
        }
    }
}

每行打印1个数字(满足条件),wcword count这里用来计算行数的linux程序

$javac Prgm.java  
$java Prgm
...//Prgm outputs numbers  1 per line
$java Prgm | wc --lines
120

答案 4 :(得分:0)

我认为分离功能会使问题变得更容易。这是您的问题的解决方案。也许它不是最好的,但却给出了一个好结果:

public static void main(final String [] args)    {
    int counter = 0;
    for (int i = 0; i < 20; i++) {
        final int reversNumber = reverseNumber(i);
        final int sum = i + reversNumber;
        if (hasNoZeros(i) && isOdd(sum)) {
            counter++;
            System.out.println("i: " + i);
            System.out.println("r: " + reversNumber);
            System.out.println("s: " + sum);


        }
    }
    System.out.println(counter);

}

public static boolean hasNoZeros(final int i){
    final String s = String.valueOf(i);
    if (s.startsWith("0") || s.endsWith("0")) {
        return false;
    }
    return true;
}

public static int reverseNumber(final int i){
    final StringBuilder sb = new StringBuilder(String.valueOf(i));
    return Integer.parseInt(sb.reverse().toString());
}


public static boolean isOdd(final int i){
    for (final char s : String.valueOf(i).toCharArray()) {
        if (Integer.parseInt(String.valueOf(s))%2 == 0) {
            return false;
        }

    }
    return true;

}

输出是:

i: 12 r: 21 s: 33 i: 14 r: 41 s: 55 i: 16 r: 61 s: 77 i: 18 r: 81 s: 99 4