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

Java ProjectEuler解决方案返回错误答案,java,math,Java,Math,我试图解决的问题来自ProjectEuler 某些整数具有以下属性: n + reverse(n) = a number consisting entirely of odd digits. 例如: 14: 14 + 41 = 55 不允许以0开头或结尾的数字 下面有多少个“可逆”数字10^9 这个问题也给出了一个提示: 1000以下有120个这样的数字 我对Java非常陌生,我试图通过编写一个程序来解决这个问题,该程序可以检查多达10亿的所有数字,我知道这不是最好的方法,但我同意 问题是

我试图解决的问题来自ProjectEuler

某些整数具有以下属性:

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

14: 14 + 41 = 55
不允许以0开头或结尾的数字

下面有多少个“可逆”数字
10^9

这个问题也给出了一个提示:

1000以下有120个这样的数字

我对Java非常陌生,我试图通过编写一个程序来解决这个问题,该程序可以检查多达10亿的所有数字,我知道这不是最好的方法,但我同意

问题是我的程序给出了错误的数字量,我不知道为什么!(代码很可能包含一些丑陋的东西,请随意以任何方式进行改进)


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

idOdd = idOdd && (x % 2 == 0);

顺便说一句,我推荐的做法是,通过简单的单元测试,您应该能够很容易地跟踪到这样的错误。

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

  • 仅当数字不是10的倍数时才将其发送到
    ReverseEnumber
    。这被称为方法的先决条件,可能是最简单的解决方案
  • 有办法让你的方法不返回结果。这是编程领域中一种流行的技术,称为,通常使用名为的工具来实现。在Java中,这些是通过
    可选的
    类实现的。这些允许您的方法(总是必须返回一些东西)返回一个表示“什么都没有”的对象。这将允许您知道您的方法是否由于某种原因无法或不愿意给您一个结果(在本例中,数字中有一个零)

  • 下面是一个快速工作的片段:

    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);
            }
        }
    }
    

    代码中最重要的问题如下所示:

    总和=反向。反向枚举数(数字)+数字

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

    sum=这个。reverseEnumber(数字)+数字

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


    编辑:尝试解释为什么不需要实例化新对象实例来调用方法-我找到了以下答案,解释了
    函数
    (对象)方法
    之间的区别:。我的解释应该足够了(您不需要新对象,因为成员方法已经可以访问对象中的成员数据)。

    我认为分离函数性将使问题变得更容易。这是解决你问题的办法。也许这不是最好的,但这会带来一个好结果:

    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;
    
    }
    
    publicstaticvoidmain(最终字符串[]args){
    int计数器=0;
    对于(int i=0;i<20;i++){
    最终int reverseNumber=ReverseEnumber(i);
    最终整数和=i+倒数;
    if(无零(i)和isOdd(和)){
    计数器++;
    System.out.println(“i:+i”);
    System.out.println(“r:+反向编号);
    系统输出打印项次(“s:+sum”);
    }
    }
    系统输出打印项次(计数器);
    }
    公共静态布尔hasnozero(final int i){
    最终字符串s=字符串。值(i);
    如果(s.startsWith(“0”)| | s.endsWith(“0”)){
    返回false;
    }
    返回true;
    }
    公共静态整数反向枚举器(最终整数i){
    最终StringBuilder sb=新StringBuilder(String.valueOf(i));
    返回Integer.parseInt(sb.reverse().toString());
    }
    公共静态布尔isOdd(最终整数i){
    for(最终字符:String.valueOf(i).toCharArray()){
    if(Integer.parseInt(String.valueOf))%2==0{
    返回false;
    }
    }
    返回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.
    

    您是否试图找出它不起作用的原因?如何打印?如果您对第一个
    1000
    数字运行该程序,结果会打印
    125
    。@可悲的是,我试图理解错误,但无法找出答案。尽管其他答案提供了简化代码的选项,但这是正确的答案。你能向@feflopizer解释一下为什么他不必实例化一个新对象就可以从同一个对象访问一个方法吗。我认为这是他问题的根本原因。@ViniciusZaramella-我添加了一些文字。@zloster非常感谢,现在一切都清楚多了@如果我的回答对你有帮助,那就接受它吧。
    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);
            }
        }
    }
    
    $javac Prgm.java  
    $java Prgm
    ...//Prgm outputs numbers  1 per line
    $java Prgm | wc --lines
    120
    
    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;
    
    }