任何人都可以告诉我代码有什么问题。找到由两个3位数字的乘积制成的最大palindrome
。
function largestPalindrome(){
for(var i =999; i>100; i--){
for(var j = 999; j>100; j--){
var mul = j*i;
if(isPalin(mul)){
return i * j;
}
}
}
}
function isPalin(i){
return i.toString() == i.toString().split("").reverse().join("");
}
console.log(largestPalindrome());
This answer was close to my question 但我仍然觉得我在做循环的方式它应该会给我带来最大的产品。
答案 0 :(得分:23)
你的工作不正常,因为它检查999*999
,然后是999*998
,然后是999*997
,直到它达到999*583
左右。虽然它没有检查997*995
或更接近顶部的东西
这会产生更大的数字
function largestPalindrome(){
var arr = [];
for(var i =999; i>100; i--){
for(var j = 999; j>100; j--){
var mul = j*i;
if(isPalin(mul)){
arr.push(j * i);
}
}
}
return Math.max.apply(Math, arr);
}
function isPalin(i){
return i.toString() == i.toString().split("").reverse().join("");
}
console.log(largestPalindrome());
这是另一种方法,将3个数字生成的所有palindrome
存储在一个数组中,然后使用Math.max on the array
获取最大的palindrome
答案 1 :(得分:18)
我认为如果你将数学应用于问题,你可以真正减少猜测。
我会将三位数字写为1000 - a
和1000 - b
,这意味着回文为1 000 000 - 1000(a+b) + ab
。
首先,让我们找到ab < 1000
的解决方案。然后,最左边的三个数字是1000 - (a+b)
,最右边的三个数字是ab
。
然后我会说这是一个数字为x,y,z
的回文:
100x+10y+z=ab
100z+10y+x=1000-a-b
从而
99x-99z = ab+a+b-1000
x-z = 1/99(ab+a+b-10)-10
那么(ab + a + b-10)可以被99整除,我们也知道x和z是左边的数字在-9和0之间(整个shebang是对称的,所以我们可以假设x&lt; = z)所以1/99(ab+a+b-10)
介于1和9之间。我们可以将ab+a+b-10
重写为ab+a+b+1-11=99p
所以(a+1)(b+1)=99p+11=11*(9p+1)
其中p在1到9之间运行。这真的是真的易:
for ($p = 1; $p <= 9; $p++) {
$n = 9 * $p + 1;
// This could be vastly optimized further.
for ($j = 1; $j <= $n; $j++) {
if ($n % $j === 0) {
$a = 1001 - $n / $j;
$b = 1001 - 11 * $j;
$test = $a * $b;
if (strrev($test) === (string) $test) {
print "$a $b " . $a * $b . "\n";
}
}
}
}
现在只打印一个正确的解决方案。
现在我们知道906609是一个解决方案,因此有一个解决方案,其中ab> 1000和1000(a + b) - ab&lt; 93391?没有:))
答案 2 :(得分:8)
如@ VisioN的评论所述:
995*583 = 580085
是一个回文。
993*913 = 906609
也是(较大的)回文。
您的代码会在995*583
之前检查993*913
并在找到的第一个回文中退出,因此它不会返回最大的回文。
解决方案:从999*999 = 998001
开始向下获取最大的回文并检查它们是否可以写为xyz*abc
。
或者只是使用您链接的问题中的已接受解决方案:)。您的解决方案,但是当您找到第一个回文时,不要返回,检查它是否大于已找到的最大回文,在这种情况下您需要更换它。一旦最大的回文大于i*999
,您就可以停止。
答案 3 :(得分:5)
包含评论的更优化版本。请注意,不需要快速返回,只需存储max
并优化周期,以便在j*i
已经过检查时不重新计算i*j
。
function largestPalindrome() {
var max = 0;
// not using i >= 100 since 100*100 is not palindrome! :)
for (var i = 999; i > 100; i--) {
// because i * j === j * i, no need of both i and j
// to count down from 999
for (var j = i; j > 100; j--) {
var mul = j * i;
if (isPalin(mul) && mul > max) {
max = i * j;
}
}
}
return max;
}
function isPalin(i) {
// adding empty string to i instead using of .toString
// avoids unnecessary wrapping in String object on the left side
i = '' + i;
// don't rely on ==, use === instead
return i === i.split("").reverse().join("");
}
console.log(largestPalindrome());
答案 4 :(得分:4)
使用underscore.js建议解决方案。首先,找到所有的回文,然后从最大的回文中循环,然后返回有两个3位素因子的回文。
function isPalindrome(num) {
var str = num.toString();
return str.split('').reverse().join('') === str;
}
function palindromes() {
var max = 999 * 999;
var min = 100 * 100;
return _.select(_.range(max, min, -1), isPalindrome);
}
palindromes().find(function (x) {
if (_.find(_.range(999, 100, -1), function (y) {
return (x % y === 0 && y != x / y && x / y < 1000) ? true : false;
})) return true;
})
答案 5 :(得分:3)
#define MAX(a, b) ((a) > (b) ? (a) : (b))
int largestPalindrome()
{
int ret = 0;
for (int i = 999; i > 100; --i)
{
int jLimit = MAX(ret / i, 100);
for (int j = i; j > jLimit; --j)
{
int ans = i * j;
if (isPalin(ans))
{
ret = MAX(ans, ret);
}
}
}
return ret;
}
上面解释的原因。
当我们找到回文产品时,我们可以重新计算j的范围。这应该更快。
答案 6 :(得分:3)
上述解决方案将完美无缺,但当我们试图找出这2个数字(i = 913和j = 993)时,我们将会发出 ONLY
我将修改Azder提出的解决方案
int max = 0;
int no1 = 0;
int no2 = 0;
// not using i >= 100 since 100*100 is not palindrome! :)
for (var i = 999; i > 100; i--) {
// because i * j === j * i, no need of both i and j
// to count down from 999
for (var j = i; j > 100; j--) {
var mul = j * i;
if (isPalin(mul)) {
if ((i+j) > max) {
max = i+j;
no1 = i; no2 = j;
}
}
}
}
//Now we can get the 2 numbers (no1=993 and no2=913)
return (no1*no2);
答案 7 :(得分:2)
我认为您可以使用此链接提供的代码 http://www.mathblog.dk/project-euler-problem-4/
因为这样可以节省乘法的CPU周期,这是非常昂贵的操作。
即使在这个你可以做更多的东西使其更像,你可以稍微修改它的while循环
out.write("TstMsg"+ "\n")
因此,我们可以将其写为while (!found) {
firstHalf--;
palin = makePalindrome(firstHalf);
for (int i = 999; i > 99; i--) {
if ((palin / i) > 999 || i*i < palin) {
break;
}
if ((palin % i == 0)) {
found = true;
factors[0] = palin / i;
factors[1] = i;
break;
}
}
}
,而不是从i=999 : 100,
移动,因为您可以在其平方根中找到数字因子。请参阅链接How to find Number is prime number or not!
此外,您可以将i=sqrt(palin):100
更改为if(condition)
,因为与零相比,通常不会将其视为一种好的做法。与简单的否定位相比,需要更多的CPU周期。
答案 8 :(得分:2)
这就是我做的。我用老式的方式来检查回文。它似乎在我的电脑上运行得更快,但我可能错了。像上面的帖子一样推送到一个阵列,在我的电脑上肯定是非常慢的。控制台明显滞后。我建议只检查你的产品是否大于你当前的最大值,如果是,存储它而不是把所有东西都推到一个阵列。如果我错了,请随时纠正我。非常感谢。
//should find the largest palindrome made from the product of two 3 digit numbers
var largestPalindrome = function() {
var max = 0,
product = 0;
for (var num1 = 999; num1 >= 100; num1--) {
for (var num2 = 999; num2 >= 100; num2--) {
product = num1 * num2;
product > max && isPalindrome(product.toString()) ? max = product : 0;
}
}
return max;
};
//check to see if product is a palindrome
var isPalindrome = function(product) {
var palindromeCheck = true;
for (var i = 0; i < product.length / 2; i++) {
if (product[i] != product[product.length - i - 1])
palindromeCheck = false;
}
return palindromeCheck;
//return product === product.split("").reverse().join("");
};
答案 9 :(得分:1)
而不是创建Array
或ArrayList
来存储所有回文,我只创建了另一个变量max
,并在其中存储了最高价值的回文。
我的代码是Java代码,但您可以从中理解逻辑。 这是我的代码,以更好地解释我所说的内容(阅读评论):
package euler;
import java.util.ArrayList; import java.util.Collections;
public class Problem4 {
public static void main (String[] args)
{
int product=0;
int max=0;
for(int i=999;i>100;i--)
{
for (int j=i;j>100;j--)
{
product=i*j;
if(isPalindrome(product))
{
//Just store maximum value of product.
//Following if loop is required in your code,in place of return i*j;
if(product>max)
{ max=product; }
}
}
}
System.out.println(max);
}
//might be inefficient to create StringBuilder and again String to compare.
public static boolean isPalindrome(int product)
{
boolean isPalindrome=false;
StringBuilder temp = new StringBuilder(Integer.toString(product)).reverse();
if(temp.toString().equals(Integer.toString(product)))
{
isPalindrome=true;
}
return isPalindrome;
}
}
当你得到第一个回文时,你正在做的是返回并退出循环。在你的情况下,它不是最大值回文。
而是使用if条件并跟踪最大值并让循环继续直到结束。
我添加了if条件,让循环运行并注册该值。
从此代码中得到了正确的答案。
PS。谢谢你的意见。我想我可以在第一时间更好地解释它。
答案 10 :(得分:1)
我已经看到很多关于这个问题的帖子,这是我提出的解决方案:
我们的回文位于这两个数字之间,写一个程序循环遍历这些数字,每当你得到回文检查它是否可以被3位数字完全整除,商也是3位数。
下面是我在C#中的程序,它打印的最后一个数字是我们要求的答案,享受。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Collections;
namespace E
{
public class Program
{
public static void Main(string[] args)
{
//Your code goes here
for(int i=10000;i<=998001;i++)
{
string s1 = i.ToString();
char[] array = s1.ToCharArray();
Array.Reverse(array);
string s2 = new String(array);
if(s1==s2)
{
for(int j=100;j<=999;j++)
{
if(i%j==0 && i/j <= 999)
{
System.Console.WriteLine(i);
continue;
}
}
}
}
System.Console.WriteLine("done");
}
}
}
答案 11 :(得分:1)
我认为这应该是最佳的
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
template <typename T>
bool IsPalindrome(const T num) {
T reverse = 0;
T n = num;
while (n > 0) {
reverse = (reverse * 10) + n % 10;
n /= 10;
}
return reverse == num;
}
template <typename T = long long int>
T LongestPalindromeFromProductOfNDigitNums(int n) {
T result = 0, val = 0, max_n_digit_num = std::pow(10, n)-1,
least_n_digit_num = std::pow(10, n-1);
int n_checks = 0;
for (T i = max_n_digit_num; i >= least_n_digit_num; --i) {
if ((i*i) < result) {//found the highest palindrome
break;
}
for (T j = i; j >= least_n_digit_num; --j) {
val = i*j;
++n_checks;
if (val < result) // any product i*j for the value of 'j' after this will be less than result
break;
if (IsPalindrome(val)) {
if (val > result)
result = val;
break; // whenever a palindrome is found break since we only need highest one
}
}
}
std::cout << " Total num of checks = " << n_checks << std::endl;
return result;
}
int main() {
int n = 3;
std::cout << " LongestPalindromeFromProductOfNDigitNums for n = "
<< n << " is " << LongestPalindromeFromProductOfNDigitNums(n) << std::endl;
n = 4;
std::cout << " LongestPalindromeFromProductOfNDigitNums for n = "
<< n << " is " << LongestPalindromeFromProductOfNDigitNums(n) << std::endl;
return 0;
}
答案 12 :(得分:1)
斯威夫特3:
// my approach is to make 6-digit palindrome first and then
// check if I can divide it by 3-digit number
// (you can see some visual listing at the end of the code)
// execution time on my laptop is around: 2.75409698486328 sec
import Foundation
func maxPalindrom() -> Int {
var result = 999999
var i = 9
var j = 9
var k = 9
while true {
while true {
while true {
print("in K loop: \(result) k = \(k)")
if isDivisible(number: result) {
return result
}
if k <= 0 {
k = 9
result += 9900
break
}
result -= 1100
k -= 1
}
print("in J loop: \(result)")
if isDivisible(number: result) {
return result
}
if j < 0 {
j = 9
result += 90090
break
}
result -= 10010
j -= 1
}
print("in I loop: \(result)")
if isDivisible(number: result) {
return result
}
if i < 0 {
break
}
result -= 100001
i -= 1
}
if result == 100001 {
return -1
}
return -1
}
func isDivisible(number: Int) -> Bool {
var i = 999
while true {
if number % i == 0 && number / i < 999 {
return true
}
if i < 500 {
return false
}
i -= 1
}
}
let start = NSDate()
print(maxPalindrom()) // 906609
let end = NSDate()
print("executio time: \(end.timeIntervalSince(start as Date)) sec") // ~ execution time: 2.75409698486328 sec
//in K loop: 999999 k = 9
//in K loop: 998899 k = 8
//in K loop: 997799 k = 7
//in K loop: 996699 k = 6
//in K loop: 995599 k = 5
//in K loop: 994499 k = 4
//in K loop: 993399 k = 3
//in K loop: 992299 k = 2
//in K loop: 991199 k = 1
//in K loop: 990099 k = 0
//in J loop: 999999
//in K loop: 989989 k = 9
//in K loop: 988889 k = 8
//in K loop: 987789 k = 7
//in K loop: 986689 k = 6
//in K loop: 985589 k = 5
//in K loop: 984489 k = 4
//in K loop: 983389 k = 3
.....
答案 13 :(得分:1)
这里的大部分答案都是正确的。如果你想保存900 * 900循环,你可以循环遍历10000到998001之间的所有回文,并找出它们是否可被3位数整除。
static void largestpalindromeproduct(){
int a=999,b=999,c=a*b,loopcounter=0;
while(c>10000){
loopcounter++;
c--;
if(isPalindrome(c))
if(isDivisible(c))
break;
}
System.out.println(" largest : " + c+ "\nloops:"+ loopcounter);
}
static boolean isDivisible(int n){
int a=999;
while(a>=100){
if(n%a==0){
if(secondDividerIs3Digit(n,a))
return true;
}
a--;
}
return false;
}
static boolean secondDividerIs3Digit(int n, int a){
Integer b=n/a;
if(b.toString().length()==3)
return true;
return false;
}
static boolean isPalindrome(int n){
Integer i=new Integer(n);
String p=i.toString();
StringBuffer s=new StringBuffer(i.toString());
s.reverse();
if(p.equals(s.toString()))
return true;
return false;
}
答案 14 :(得分:0)
作为一个非常简单的解决方案,这个解决方案
public class LargestPallendrome {
public static void main(String[] args) {
int a = 999;
int b = 999;
long max = 0;
while (a > 100) {
long num = a * b;
if (checkPallendrome(num)) {
if (num > max)
max = num;
}
if (b >= 100)
b--;
else {
a--;
b = 999;
}
}
System.out.println(max);
}
public static boolean checkPallendrome(long num) {
String a = num + "";
String b = new StringBuffer(num + "").reverse().toString();
if (a.equals(b))
return true;
return false;
}
}
答案 15 :(得分:0)
JavaScript中的另一个简单解决方案
function reverseNumber(n)
{
n = n + "";
return n.split("").reverse().join("");
}
function palindrom(){
var r= 1 , y =1;
var largest = 0;
while(r <= 1000){
var num1 = r;
var num2 = 0;
while(num1 <= 1000 && num2 <= num1){
product = num1 * num2;
if (product == reverseNumber(product)){
console.log(`${num1} x ${num2} = ${product}`);
if(product > largest){
largest = product;
}
}
num1 = num1 + 1;
num2= num2 + 1;
}
r++;
}
console.log(``)
console.log(`The largest is ${largest}`);
}
console.log(palindrom());
答案 16 :(得分:0)
public static void main(String[] args) {
int tempAns = 0;
int max = 999;
for (int i = 100; i <= max; i++) {
for (int j = max; j >= i; j--) {
if (findPalindrome(i * j) && (i * j) > tempAns) {
System.out.println("Palindrome: " + j + " * " + i + " = " + j * i);
tempAns = i * j;
}
}
}
}
private static boolean findPalindrome(int n) {
String nString = String.valueOf(n);
int j = 0;
int stringLength = nString.length() - 1;
for (int i = stringLength; i >= 0; i--) {
if (nString.charAt(j) == nString.charAt(i)) {
if (i == 0) {
return true;
}
j++;
} else if (nString.charAt(j) != nString.charAt(i)) {
return false;
}
}
return false;
}
答案 17 :(得分:0)
这更好,因为它使用O(N)时间复杂度来查找所有回文(计算六位数no的回文是常数),而O(N 2 )几乎可以找到实际的回文回文中最糟糕的情况是,在找到第一个否定的那一刻,我们不必再进行任何计算,而实际上,我们正在对可能的回文号使用最坏的情况。所以我认为更好
package ProjectEuler;
import java.util.ArrayList;
import java.util.Arrays;
public class Largest_Palindrome_Product {
public static void main(String[] args) {
int count=0;
for(int i=10000;i<998002;i++) {
int x=i,c=0;
while(x!=0) {
c=c*10+x%10;
x/=10;
}
if(c==i) {
count++;
}
}
int a[]=new int[count],count1=0;
for(int i=10000;i<998002;i++) {
int x=i,c=0;
while(x!=0) {
c=c*10+x%10;
x/=10;
}
if(c==i) {
a[count1]=i;
count1++;
}
}
Arrays.sort(a);
tp:for(int i=count-1;i>=0;i--)
{
for(int j=999;j>100;j--)
if(a[i]%j==0&&a[i]/j<=999) {
System.out.println(a[i]+" "+j+" "+a[i]/j);
break tp;
}
}
}
}
答案 18 :(得分:0)
这就是我用Java语言编写的方式。简单容易!
let num1 = 999;
let num2 = 999;
let arr = [];
function check(x, y)
{
if(String(x*y) == String(x*y).split("").reverse().join(""))
{
return true;
}
return false;
}
for(let i=0; i<999999; i++)
{
if(check(num1, num2))
{
arr.push(num1*num2);
num1--;
num2 = num1+1;
}
num2--;
}
console.log(arr.sort((x, y) => y-x)[0]);
答案 19 :(得分:0)
我用random.randint
检查过几次。在python 3.7.1中,应使用CMD运行它,并在20秒后会得到正确的答案。
import random
x,y,z,a,b=100,100,' ','',0
while 100<=x<=999 and 100<=y<=999:
a=x*y
x=random.randint(900,999)
y=random.randint(900,999)
print(x,' x ',y,'=')
z=len(str(a))
if z==6:
if str(a)[0] == str(a)[5]:
if str(a)[1] == str(a)[4]:
if str(a)[2] == str(a)[3]:
print(a,'yes')
exit(a)
else:
pass
#906609
答案 20 :(得分:0)
可读选项:
function maxPalindrome(num) {
let maxPalindrome = 1;
for (let i = num; i > 0; i--) {
for (let j = num; j > 0; j--) {
const product = i * j;
if (
product.toString() === product.toString().split("").reverse().join("")
&& product > maxPalindrome
) {
maxPalindrome = product;
}
}
}
return maxPalindrome;
}
console.log(maxPalindrome(999));