7

回文数的两种读法都是一样的。由两个 2 位数字的乘积构成的最大回文数是 9009 = 91 × 99。

找出由两个 3 位数字的乘积构成的最大回文数。

我编写了这段代码来找到解决方案,但 Project Euler 网站上的答案仍然不正确:

function Palindromic(x) {
    var pal = parseInt(x.toString().split('').reverse().join(''));

    if (pal === x)
        return true;
    else
        return false;
}

var x = 100,
    y = 100,
    product = x * y;

for (x; x <= 999; x++) {
    for (y = x; y <= 999; y++) {
        product = x * y;
        if (Palindromic(product)) {
            console.log(x + '*' + y + '=' + product);
        }
    }
}

我的代码有问题吗?!无论如何,我得到的答案是 888888 from 924*962

4

6 回答 6

7

我不认为,您的代码存在真正的问题。您只是不过滤最大的产品,这不一定是您的最后一个输出。只需为最大的产品添加额外的检查,例如:

var x, y, product, max = 0;

for (x = 100; x <= 999; x++) {
    for (y = x; y <= 999; y++) {
        product = x * y;
        if (Palindromic(product)) {
          if( max < product ) { // this is new
            max = product;
            console.log(x + '*' + y + '=' + product);
          }
        }
    }
}

这返回

913*993=906609

作为最大的结果。

于 2013-09-17T06:47:22.167 回答
4

很晚的答案,我的方法类似于Sirko。我发现了一种我认为可以显着提升性能的有趣方法,所以我想分享一下:

function isPalindrome(num) {
  return parseInt(String(num).split('').reverse().join('')) === num;
}

function findLargestPalindromeProduct(numberOfDigits) {
  var start = Math.pow(10, numberOfDigits - 1);
  var end = Math.pow(10, numberOfDigits);
  var largestPalindrome = 0;
  var product;
  for (a = start; a < end; a++) {
    for (b = start; b < end; b++) {
      product = a * b;
      if (largestPalindrome < product) {
        if (isPalindrome(product)) {
          largestPalindrome = product;
        }
      }
    }
  }

  return largestPalindrome;
}
console.time('Function #1');
for (var i = 0; i < 100; i++) {
  findLargestPalindromeProduct(3);
};
console.timeEnd('Function #1')

当我在 Chrome 控制台中运行它时,我每次迭代平均得到大约 34 毫秒。

当我首先检查它是否是回文时,我的平均迭代时间约为 500 毫秒。

它这么快的原因是因为检查乘积是否大于最大回文是非常快的检查并快速过滤掉许多对,而不是首先检查它是否是回文(当它甚至可能不大于最大的回文- 即使它实际上是回文)。

于 2018-10-07T21:03:29.123 回答
2
let string = [];
let mul = 0;

let x = 100;
while(x < 1000){
    for(y = 100; y < 1000; y++){
        mul = x * y;
        let n = mul.toString();                   //to convert multiplied value to string 
        let stringSplit = n.split("");            //splits the string in array
        let reverseSplit = stringSplit.reverse(); //reverse the string array
        let joinSplit = reverseSplit.join("");    //join the reversed array into string
        if (joinSplit == n){          //check weather reversed string is equal to multiplied value
            string.push(joinSplit);  //as there are lots of value it puts them in array
        }
    }
  x++;
 }
 string.sort(function(a, b){return b-a}); // sort array in descending order as we want highest value 
 console.log(string[0]); 
于 2019-08-30T02:24:37.073 回答
1

也是一个迟到的答案,但遍历所有选项真的很慢。您可以循环批次,对于 n===2,您可以批次 10,对于 n ===3 批次 100 等等

这是一个 JSPerf https://jsperf.com/largest-palindrome-product/1

export const isPalindrome = (arg: string | number): boolean => {
  const orig = `${arg}`;
  const reverse = orig.split("").reverse().join("");

  return orig === reverse;
};

/**
 * The idea here is to search in batches to avoid looping trough all of the possibilities.
 *
 * For n === 2 you will first search between 90 and 99 if no palindrome found you will move to 80 and 89 etc.
 * If a palindrome is found you will pick the max from the batch
 *
 */
export const largestPalindromeProduct = (num: number): [number, [number, number]] => {
  const min = Number("1".padEnd(num, "0"));
  const max = Number("9".padEnd(num, "9"));

  let stepperMax = max;
  let res: number = 0;

  let position: [number, number] = [min, min];

  while (stepperMax >= min) {
    for (let i = max; i >= stepperMax - min - 1; i--) {
      for (let j = max; j >= stepperMax - min - 1; j--) {
        const temp = i * j;
        if (isPalindrome(temp) && temp > res) {
          position = [i, j];
          res = temp;
        }
      }
    }

    if (res !== 0) {
      return [res, position];
    }

    stepperMax = stepperMax - min - 1;
  }

  return [res, position];
};

于 2018-12-23T12:16:59.967 回答
0

为了更早地找到大回文串,您可以从范围的最后一个数字向下计数,而不是从范围的第一个数字向上计数。

这样你就可以停止检查那些太小而无法改进迄今为止发现的最大回文的因素,尽早打破内循环。

例如:

/**
 * Check if a number is a palindrome.
 * @param {number} num Number to be checked.
 * @returns {boolean} True if the number is a palindrome, false otherwise.
 */
const isPalindrome = (num) => {
  const numStr = String(num)
  const reverseNumStr = [...numStr].reverse().join('')
  return numStr === reverseNumStr
}

/**
 * Find the largest palindrome product of two n-digit numbers.
 * @param {number} digits Number of digits of the multiplied numbers.
 * @returns {number} Largest palindrome product.
 */
const largestPalindromeProduct = (digits) => {
  const start = 10 ** (digits - 1) // first n-digit number
  const end = (10 ** digits) - 1 // last n-digit number
  let max = 0

  for (let factorA = end; factorA >= start; factorA--) {
    for (let factorB = end; factorB >= factorA; factorB--) {
      const product = factorA * factorB
      if (product <= max) break
      if (isPalindrome(product)) max = product
    }
  }

  return max
}

官方的 Project Euler 问题 4 概述涵盖了此优化和其他优化。

于 2022-02-04T08:39:20.657 回答
-2

这是一个很晚的答案,但是我提出了一种不同的方法,它是一个足够的解决方案,而不是完美的解决方案

我只检查了 6 位回文。

1.从最大值只生成6位回文数(前三位,后三位应取反)

2.检查生成的回文数字是否有两个3位数字作为因子,如果是则返回数字,即两个3位数字乘积所能产生的最大回文数。c# 中的代码示例。

    static void Main(string[] args)
    {
        Console.WriteLine(SixDigitPalindromeWithDivisor().ToString());
        Console.ReadLine();
    }

    public static int SixDigitPalindromeWithDivisor()
    {
        for (int i = 999; i > 100; i--)
        {
            //generating palindrome number from max
            var palindromeInt = Int32.Parse(Convert.ToString(i) + ReverseString(Convert.ToString(i)));

            //checking three digit number factor exist
            if (CheckThreeDigitDivisorExists(palindromeInt))
            {
                return palindromeInt;
            }
        }
        return 0;
    }

    public static bool CheckThreeDigitDivisorExists(int number)
    {
        for (int i = 999; i > 100; i--)
        {
            if (number % i == 0)
            {
                if (number / i <= 999)
                {
                    return true;
                }
            }
        }
        return false;
    }

    public static string ReverseString(string s)
    {
        char[] arr = s.ToCharArray();
        Array.Reverse(arr);
        return new string(arr);
    }
于 2017-05-05T10:33:05.590 回答