我试图解决的问题来自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);
答案 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)method
:https://stackoverflow.com/a/155655/25429。 IMO解释应该足够了(您不需要新对象,因为成员方法已经可以访问对象中的成员数据。)
答案 1 :(得分:0)
当您使用以下代码检查下一个数字时,您会覆盖给定数字的奇数检查:isOdd = false;
。因此,在结果中,您只检查第一个数字是否为奇数。
你应该用
idOdd = idOdd && (x % 2 == 0);
顺便说一句。您应该能够通过简单的单元测试轻松跟踪这样的错误,我建议这样做。
答案 2 :(得分:0)
这里的一个关键问题是你的reverseNumber
方法有两件事:检查数字是否为零,是否反转了数字。我知道如果数字是10的倍数,你想忽略结果(或者实际上,你没有结果)。因此,你有两种方法:
reverseNumber
。这称为方法的前提条件,可能是最简单的解决方案。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个数字(满足条件),wc
是word 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