为什么这个java字符串例程不打印答案?

时间:2013-09-24 10:20:12

标签: java string

我一直在研究Project Euler问题4.我是java的新手,相信我找到了答案(906609 = 993 * 913,使用Excel!)。

当我打印出注释掉的那一行时,我可以说我的字符串操作有效。我已经研究了一些比较字符串的方法,以防我没有多少东西,但是这个程序没有给我一个结果。

请帮我确定一下为什么不打印答案?

詹姆斯

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

    int i;
    int j;
    long k;
    String stringProd;

    for(i=994;i>992; i--){
        for (j=914;j>912; j--){
            k=(i*j);
            stringProd=String.valueOf(k);
            int len=stringProd.length();

            char[] forwards=new char[len];
            char[] back = new char[len];

            for(int l=0; l<len; l++){
                forwards[l]=stringProd.charAt(l);
            }

            for(int m=0; m<len;m++){
                back[m]=forwards[len-1-m];

            } 

            //System.out.println(forwards);
            //System.out.println(back);

            if(forwards.toString().equals(back.toString())){
                System.out.println(k);}
            }
        }
    }
}

2 个答案:

答案 0 :(得分:8)

您正在比较数组的字符串表示形式。 toString()没有给你你的想法。例如,下面的代码清楚地表明了这一点:

char[] arr1 = {'a', 'b'};
char[] arr2 = {'a', 'b'};

System.out.println(arr1.toString() + " : " + arr2.toString());

此代码打印:

[C@16f0472 : [C@18d107f

因此,即使内容相等,两个数组的字符串表示也是不同的。这是因为数组不会覆盖toString()方法。它继承了Object#toString()方法。

  

toString的{​​{1}}方法返回包含的字符串   对象是实例的类的名称,at-sign   字符Object,以及散列的无符号十六进制表示   对象的代码。换句话说,此方法返回一个相等的字符串   价值:

@

因此,在上面的输出中,getClass().getName() + '@' + Integer.toHexString(hashCode()) [C的输出,而char[].class.getName()是哈希码。

您不能使用18d107f比较数组,因为Java中的数组也不会覆盖forward.equals(back)equals()。任何选择?是的,为了比较数组,您可以使用Arrays#equals(char[], char[])方法:

hashCode()

此外,要获取if (Arrays.equals(forward, back)) { System.out.println(k); } 数组,您不需要这些循环。您可以使用String#toCharArray()方法。而且为了获得String的反转,您可以将字符串包装在StringBuilder实例中,并使用它的reverse()方法:

char

现在您已经找到了一种简单的方法来反转字符串,那么如何直接使用String#equals()方法,并阻止创建这些字符数组呢?

char[] forwards = stringProd.toCharArray();
char[] back = new StringBuilder(stringPod).reverse().toString().toCharArray();

最后,因为它是关于项目的euler,这是关于速度和主要是数学。您应该考虑避免使用String stringPod = String.valueOf(k); String reverseStringPod = new StringBuilder(stringPod).reverse().toString() if (stringPod.equals(reverseStringPod)) { System.out.println(k); } 实用程序,并使用常规除法和模数运算,从开头和结尾获取每个数字,并进行比较。

答案 1 :(得分:2)

将字符串转换为char[]使用

char[] forward = stringProd.toCharArray();

要将char[]转换为String,请使用String(char[])构造函数:

String backStr = new String(back); // Not the same as back.toString()

然而,由于以下几个原因,这不是最高效的解决方案:

  • 您无需构建back数组来检查字符串是否为回文 - 您可以从两端走过字符串,比较字符,直到您要么找到差异,要么你的索引在中间相遇。
  • 不是在循环中构建新数组,而是可以重用相同的数组 - 如果您想继续使用数组,可以为产品的最大长度分配一次k,并在循环的所有迭代中使用它。
  • 您不需要将数字转换为字符串以检查它是否是回文 - 您可以通过重复取除除以10的余数,然后除以10来得到数字转到下一个数字。

以下是最后一点的说明:

boolean isPalindrome(int n) {
    int[] digits = new int[10];
    if (n < 0) n = -n;
    int len = 0;
    while (n != 0) {
        digits[len++] = n % 10;
        n /= 10;
    }
    // Start two indexes from the opposite sides
    int left = 0, right = len-1;
    // Loop until they meet in the middle
    while (left < right) {
        if (digits[left++] != digits[right--]) {
            return false;
        }
    }
    return true;
}