最大的回文产品 - 欧拉项目

时间:2014-07-16 04:22:30

标签: java palindrome

我试图解决项目Euler problem 4,即:

回文数字两种方式相同。由两个2位数字的乘积制成的最大回文是9009 = 91×99。 找到由两个3位数字的乘积制成的最大回文。

这是我的解决方案,它的输出是997799,但这不是正确的答案,我想知道问题出在哪里:

package projecteuler;

public class Pro4 {

    public static void main(String[] args) {

        for(int i=999*999;i>=100*100;i--){
            if(isPalindrome(i)==true){
                System.out.println(i);
                break;
            }
        }
    }

    static boolean isPalindrome(int x){
        int[] bits = new int[7];
        int index=1;
        while(x>0){
            bits[index]=x%10;
            index++;
            x/=10;
        }
        for(int i=1;i<=index/2;i++){
            if(bits[i]!=bits[index-i]){
                return false;
            }
        }
        return true;
    }

}

17 个答案:

答案 0 :(得分:6)

这是一个不会遍历所有6位数字的解决方案:

public static boolean isPalindrome(int nr) {
    int rev = 0;                    // the reversed number
    int x = nr;                     // store the default value (it will be changed)
    while (x > 0) {
        rev = 10 * rev + x % 10;
        x /= 10;
    }
    return nr == rev;               // returns true if the number is palindrome
}

public static void main(String[] args) {

    int max = -1;

    for ( int i = 999 ; i >= 100 ; i--) {
        for (int j = 999 ; j >= 100 ; j-- ) {
            int p = i * j;
            if ( max < p && isPalindrome(p) ) {
                max = p;
            }
        }
    }
    System.out.println(max > -1? max : "No palindrome found");
}

修改

main方法的改进解决方案(根据Peter Schuetze所说)可能是:

public static void main(String[] args) {

    int max = -1;

    for ( int i = 999 ; i >= 100 ; i--) {
        if ( max >= i*999 ) { 
            break;
        }
        for (int j = 999 ; j >= i ; j-- ) {             
            int p = i * j;
            if ( max < p && isPalindrome(p) ) {
                max = p;
            }
        }
    }       
    System.out.println(max > -1? max : "No palindrome found");
}

对于这个特殊的例子,时间大约是2倍,但如果你的数字更大,那么改进将会更加显着。

<强>输出

906609

答案 1 :(得分:3)

您正在按顺序从999 * 999递减到100 * 100。这并不一定意味着您找到的第一个回文是两个3位数字的乘积。

回文997799有11和90709作为主要因素,不是两个3位数的乘积。

答案 2 :(得分:1)

for i的for循环从998001下降到100000.你的程序中没有任何地方检查i实际上是两个3位数字的乘积。

答案 3 :(得分:0)

JAVASCRIPT
嘿,我查看了一些答案,这很令人困惑,这就是我得到的:首先,我从一个按钮调用函数 getPalindrome(),我只给它数字的数量。然后在第一个 for 循环中,我通过添加 9 * 10^0 (9)、9 * 10^1 (90) 等将 max 设置为提供的数字的最大数字。然后我有两个嵌套循环,它们来自最后两个数字向下(例如 99 和 98)。第一个循环的条件大多无关紧要,因为最大的回文总是在最后一个数字中(例如 90 和 99、990 和 999 等)。在循环内部,我检查两个数字是否都不能被 11 整除,这意味着我们不能有回文,所以我只是跳过它并降低第二个数字。 如果其中之一可以被 11 整除,则调用回文函数检查。 尽管我不认为这个解决方案比其他解决方案更好/更快,但它更简单、更容易理解。

const getPalindrome = () => {
let max = 0;
for (let i = 0; i < digit; i++) {
  max += 9 * Math.pow(10, i);
}
let min = (max + 1)/10;
let first = max;
let second = max - 1;

for (let i = first; i > min; i--) {
  for (let j = second; j > min * 9; j--) {
    if(i % 11 !== 0 && j % 11 !== 0) {
      continue;
    } else {
      if(checkForPalindrome(i*j)) {
        return setResult(i*j);
      }
    }
  }
} 


}

  const checkForPalindrome = (num) => {
    let digits = `${num}`;
    for (let i = 0; i < Math.floor(digits.length / 2); i++) {
      if(digits[i] !== digits[digits.length-1-i]) {
        return false;
      } 
    }
    return true;
  }

答案 4 :(得分:0)

这是Project_Euler-4问题的Python代码。

我们必须找到最大的回文数,它是两个三位数的乘积

import math
def isPal(x):
    x=str(x)
    t=x[::-1]
    if(x==t):
        return True
    else:
        return False
max=0
for i in range(999,99,-1):
    for j in range(999,99,-1):
        if(isPal(i*j)):
            if((i*j)>max):
                max=(i*j)
print(max)

答案将是906609

答案 5 :(得分:0)

这是c ++中的代码

#include <iostream>
using namespace std;
int reverse(int a){
int reverse=0;
for(int i=0;i<6;i++){
    reverse = reverse*10+a%10;
    a/=10;
}
return reverse;
}
int main(){
int a=999,max=1,rev;;
int b=999;
for(a=999;a>100;a--){
    for(b=999;b>100;b--){
        int p = a*b;
         rev = reverse(p);
        if (p==rev) {
            if(max<rev){
                max = rev;
            }
        }
    }
}
cout<<"\n"<<max<<"\n";
return 0;
  }

答案 6 :(得分:0)

此方法比以前的方法快得多。 它首先评估999 * 999.它是Puzzled over palindromic product problem

中提出的方法的实现

我们想在较小的产品之前尝试更大的产品,所以接下来尝试998 * 998,外循环每次减少一个。在内循环中, 取外部限制数来创建(n + y)(n-y)(总是小于n ^ 2),迭代y直到其中一个因子太大或太小。

来自https://pthree.org/2007/09/15/largest-palindromic-number-in-python/, 其中一个因素必须是11的倍数。 检查其中一个因子是11的倍数,并且该产品是否大于之前找到的(或初始)回文数。

一旦满足这些测试,看看产品是否是回文。

一旦发现回文,我们可以将外环的限制提高到回文的平方根,因为这是可能是答案的最小值。

该算法仅在475次比较中找到了答案。这远远优于简单方法提出的810,000,甚至405450。

有人可以提出更快的方法吗?

Longest palindromes:
Max factor   Max Palindrome
9999         99000099
99999        9966006699
999999       999000000999
9999999      99956644665999
99999999     9999000000009999
999999999    999900665566009999

public class LargestPalindromicNumberInRange {
    private final long lowerLimit;
    private final long upperLimit;
    private long largestPalindrome;
    private long largestFirstFactor;
    private long largestSecondFactor;
    private long loopCount;
    private long answerCount;

public static void main(String[] args) {
    long lowerLimit = 1000;
    long upperLimit = 9999;
    LargestPalindromicNumberInRange palindromicNumbers = 
            new LargestPalindromicNumberInRange(lowerLimit, upperLimit);
    palindromicNumbers.TopDown();
}

private LargestPalindromicNumberInRange(long lowerLimit, long upperLimit){
    this.lowerLimit = lowerLimit;
    this.upperLimit = upperLimit;
}
private void TopDown() {
    loopCount = 0;
    answerCount = 0;
    largestPalindrome = lowerLimit * lowerLimit;
    long initialLargestPalindrome = largestPalindrome;
    long lowerFactorLimit = lowerLimit;
    for (long limit = upperLimit; limit > lowerFactorLimit; limit--){
        for (long firstFactorValue = limit; firstFactorValue >= limit - 1; firstFactorValue--) {
            long firstFactor = firstFactorValue;
            long secondFactor = limit;
            while(secondFactor <= upperLimit && firstFactor >= lowerLimit){
                if (firstFactor % 11 == 0 || secondFactor % 11 == 0) {
                    long product = firstFactor * secondFactor;
                    if (product < largestPalindrome) { break; }
                    loopCount++;
                    if (IsPalindromic(product)) {
//                    System.out.print("Answer: " + product + "\n");
                        answerCount++;
                        largestPalindrome = product;
                        largestFirstFactor = firstFactor;
                        largestSecondFactor = secondFactor;
                        lowerFactorLimit = (long) Math.sqrt(largestPalindrome);
                        break;
                    }
                }
                firstFactor--;
                secondFactor++;
            }
        }
        System.out.print("Answer: " + largestPalindrome + "\n");
        System.out.print("Factor1: " + largestFirstFactor + "\n");
        System.out.print("Factor2: " + largestSecondFactor + "\n");
        System.out.print("Loop count: " + loopCount + "\n");
        System.out.print("Answer count: " + answerCount + "\n");
    }
private boolean IsPalindromic(Long x) {
    String forwardString = x.toString();

    StringBuilder builder = new StringBuilder();
    builder.append(forwardString);
    builder = builder.reverse();
    String reverseString = builder.toString();

    return forwardString.equals(reverseString);
}

}

答案 7 :(得分:0)

另一个用C#编写的简单解决方案

private static void Main(string[] args)
        {
            var maxi = 0;
            var maxj = 0;
            var maxProd = 0;
            for (var i = 999; i > 100; i--)
            for (var j = 999; j > 100; j--)
            {
                var product = i * j;
                if (IsPalindrome(product))
                    if (product > maxProd)
                    {
                        maxi = i;
                        maxj = j;
                        maxProd = product;
                    }
            }
            Console.WriteLine(
                "The highest Palindrome number made from the product of two 3-digit numbers is {0}*{1}={2}", maxi, maxj,
                maxProd);
            Console.ReadKey();
        }

        public static bool IsPalindrome(int number)
        {
            var numberString = number.ToString();
            var reverseString = string.Empty;
            for (var i = numberString.Length - 1; i >= 0; --i)
                reverseString += numberString[i];
            return numberString == reverseString;
        }

答案 8 :(得分:0)

因为在R中没有人这样做。这个解决方案可以解决问题。

项目欧拉问题4

回文数字读取两种方式相同。由两个2位数字的乘积制成的最大回文是9009 = 91×99。

找到由两个3位数字的乘积制成的最大回文。         R没有内置功能来检查回文,所以我创建了         一个虽然'rev'可以使用:)。此外,代码未针对进行优化         速度主要是为了提高可读性。

@Override
public boolean equals(Object obj) {
    if (obj == this) {
        return true;
    }
    if (obj == null || obj.getClass()!=getClass()) {
        return false;
    }
    return Object.equals(this.getAlias(),((User) obj).getAlias())
        && Object.equals(this.getEmailAddress(),((User) obj).getEmailAddress())
        && Object.equals(this.getCellNumber(),((User) obj).getCellNumber()));
} 

享受!

答案 9 :(得分:0)

/ * 找到由两个n位数字的乘积制成的最大回文。 由于结果可能非常大,您应该返回最大的回文模型1337。 例: 输入:2 输出:987 说明:99 x 91 = 9009,9009%1337 = 987 注意: n的范围是[1,8]。  * /

    public class LargestPalindromeProduct {
    public int largestPalindrome(int n) {
        if(n<1 || n>8)
            throw new IllegalArgumentException("n should be in the range [1,8]");

        int start = (int)Math.pow(10, n-1); // n = 1, start 1, end = 10 -1.   n = 2, start = 10, end = 99; 
        if(start == 1) start = 0 ; // n = 3, start = 100, end == 999
        int end = (int)Math.pow(10, n) - 1;

        long product = 0;
        long maxPalindrome = 0;

        for(int i = end ; i >= start ; i--)
        {
            for(int j = i ; j >= start ; j--)
            {
                product = i * j ;
                 // if one of the number is modulo 10, product can never be palindrome, e.g 100 * 200 = 200000, or 240*123 = 29520. this is because the product will always end with zero but it can never begin with zero except one/both of them numbers is zero. 
                if(product % 10 == 0)
                    continue; 
                if(isPalindrome(product) && product > maxPalindrome)
                    maxPalindrome = product;                    
            }
        }
        return (int)(maxPalindrome % 1337);
    }
    public static boolean isPalindrome(long n){
        StringBuffer sb = new StringBuffer().append(Long.toString(n)).reverse();
        if(sb.toString().equals(Long.toString(n)))
            return true;
        return false;
    }
    public static void main(String[] args){
         System.out.println(new LargestPalindromeProduct().largestPalindrome(2));
    }

}

答案 10 :(得分:0)

在C中完成 这可能会对你有所帮助。

#include<stdio.h>
int calculate(int n)
{
    int temp = 0,m = 0;
    m = n;
    while(n != 0)
    {
        temp = temp * 10;
        temp = temp + n % 10;
        n = n / 10;
    }
    if(m == temp)
    {
        printf(" %d \n",temp);
        return temp;
    }
    else
    {
        return 0;
    }
}
int main()
{
    int i,j,temp = 0,count=0,temp1 = 0;
    for(i = 100;i < 1000;i++)
    {
        for(j = 100;j < 1000;j++)
        {
            temp1 = i * j;
            temp = calculate(temp1);

            if(temp > count)
            {
                count = temp;
            }
        }   
    }
    printf(" The Largest Palindrome number is : %d \n",count);
}

答案 11 :(得分:0)

我在这里看到很多错误。

  • 首先,您使用2个最高3位数的乘法,然后递减它以找到回文。根据问题,您需要做的是使用具有最高3位数no.s的变量,然后递减它们以检查最终产品。
  • 第二,检查是否。是palindrome你使用一个数组来存储它然后用一个循环来检查它,我发现它不正确,因为你可以简单地存储结果否。在另一个整数变量中使用简单的方法。(reverseNum * 10 +(num%10))

我看到用户已经发布了正确的代码(ROMANIA)

答案 12 :(得分:0)

public class LargestPalindromProduct {

   public static void main(String args[]) {
      LargestPalindromProduct obj = new LargestPalindromProduct();
      System.out.println("The largest palindrome for product of two 3-digit numbers is " + obj.getLargestPalindromeProduct(3));
   }

/*
 * @param digits
 * @return
 */
private int getLargestPalindromeProduct(int digits) {
   int largestPalindromeProduct = -1;
   int startNum = (int)Math.pow(10, digits) - 1;
   int endNum = (int)Math.pow(10, digits-1) - 1;

   for (int i = startNum; i > endNum; i--) {
       for (int j = startNum; j > endNum; j--) {
           if (isPalindrome(i * j)) {
               largestPalindromeProduct =  Math.max(largestPalindromeProduct, i * j);
           }
       }
   }
   return largestPalindromeProduct;
}

private boolean isPalindrome(int number) {
    String s = String.valueOf(number);
    for (int i = 0, j = s.length() -1; i < j;i++, j--) {
        if (s.charAt(i) != s.charAt(j)) {
            return false;
        }
    }
    return true;
}

答案 13 :(得分:0)

以上都没有给出正确的答案。 (我认为逻辑可能是正确的,但正确的答案是906609)。由于您不知道该数字是6位数还是5位数,因此您需要检查两者。下面是一个简单的代码来做同样的事情。

经常调用乘法,我知道......

i = 999
for u in range (100,1000):
    for y in range (100,1000):
        if len(str(u*y)) == 5 and str(u*y)[0]==str(u*y)[4]and str(u*y)[1]==str(u*y)[3] and u*y>i:
        i=u*y
        print ('the product of ', u, ' and ',y,' is: ',u*y)
    elif len(str(u*y)) == 6 and str(u*y)[0]==str(u*y)[5]and str(u*y)[1]==str(u*y)[4]and str(u*y)[2]==str(u*y)[3]and u*y>i:
        i=u*y
        print ('the product of ', u, ' and ',y,' is: ',u*y)

答案 14 :(得分:0)

您还假设您找到的第一个回文最大。您找到的第一个回文是580085,这不是正确答案。

您还假设您找到的第一个回文是两个3位数字的乘积。您还应该使用两个不同的数字,而不是将999与999相乘,并向下迭代到100 * 100.

答案 15 :(得分:0)

您正在迭代循环,其编号从998001到10000,因为某些数字可能不是产品两个3位数字。
您应该乘以两个3位数字,然后比较它,如果该数字是回文与否。

你的for循环代码应该是:

  for(int i=999;i>=100;i--)  
  {
        int k = i-1;
        int product = i * k;
        System.out.println(i+" * "+k+"  = "+product);

        if(isPalindrome(product)==true){
            System.out.println("palindrum number "+product);
            System.out.println("Product of : "+i+" * "+k);
            break;
        }
  }  

这将为您提供最大的回文数,它是两位3位数的乘积 输出是:

palindrum number 289982
Product of : 539 * 538  

如果你乘以两个数字不同,这都是正确的 如果您想要包含相同数量的产品以检查是否为回文,则上述代码可能几乎没有变化 该代码应该是:

for(int i=999;i>=100;i--){
        int k = i;
        int product = i * k;
        System.out.println(i+" * "+k+"  = "+product);

        if(isPalindrome(product)==true){
            System.out.println("palindrum number "+product);
            System.out.println("Product of : "+i+" * "+k);
            break;
        }
        else{
            k = i - 1;
            product = i * k;
            System.out.println(i+" * "+k+"  = "+product);
            if(isPalindrome(product)==true){
                System.out.println("palindrum number "+product);
                System.out.println("Product of : "+i+" * "+k);
                break;
            }
        }
    }

为您提供如下输出:

palindrum number 698896
Product of : 836 * 836

我认为这是你需要做的。

答案 16 :(得分:-1)

#include <bits/stdc++.h>
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int sm=100,lr=999,ans=0;
    for(int i=sm;i<=lr;i++)       //for every number we traverse and find its 
                                   // product with other number
    {
        for(int j=sm;j<=lr;j++)
        {
            int pro=i*j;                    //find product of number 
            string str=to_string(pro);      //  convert to string 
        string rev = string(str.rbegin(),str.rend());  //reverse it 
            if(str==rev)                              //check it with 
          {                                           //string it is equal or 
                                                     //  with reverse
            ans=max(ans,pro);} //storing only max value if it satisfy the  
                               //condition
        }
    }
    cout<<ans; // ans is 906609 
    return 0;
}