C++ Project Euler #8,我不明白我哪里出错了
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23824570/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Project Euler #8, I don't understand where I'm going wrong
提问by psBDS
I'm working on project euler problem number eight, in which ive been supplied this ridiculously large number:
我正在处理项目euler 问题 8,其中提供了这个大得离谱的数字:
7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
and am supposed to "Find the thirteen adjacent digits in the 1000-digit number that have the greatest product." EG the product of the first four adjacent digits is 7 * 3 * 1 * 6. My code is the following:
并且应该“在 1000 位数字中找到具有最大乘积的十三个相邻数字。” EG 前四位相邻数字的乘积为 7 * 3 * 1 * 6。我的代码如下:
int main()
{
string num = /* ridiculously large number omitted */;
int greatestProduct = 0;
int product;
for (int i=0; i < num.length() -12; i++)
{
product = ((int) num[i] - 48);
for (int j=i+1; j<i+13; j++)
{
product = product * ((int) num[j] - 48);
if (greatestProduct <= product)
{
greatestProduct = product;
}
}
}
cout << greatestProduct << endl;
}
I keep getting 2091059712 as the answer which project euler informs me is wrong and I suspect its too large anyway. Any help would be appreciated.
我一直收到 2091059712 作为项目 euler 通知我的答案是错误的,我怀疑它太大了。任何帮助,将不胜感激。
EDIT: changed to unsigned long int and it worked. Thanks everyone!
编辑:更改为 unsigned long int 并且它起作用了。谢谢大家!
采纳答案by jwg
In fact your solution is too small rather than too big. The answer is what was pointed out in the comments, that there is integer overflow, and the clue is in the fact that your solution is close to the largest possible value for an signed int: 2147483647. You need to use a different type to store the product.
事实上,您的解决方案太小而不是太大。答案是评论中指出的,存在整数溢出,线索在于您的解决方案接近有符号整数的最大可能值:2147483647。您需要使用不同的类型来存储产品。
Note that the answer below is still 'correct' in that your code does do this wrong, but it's not what is causing the wrong value. Try taking your (working) code to http://codereview.stackexchange.comif you would like the folks there to tell you what you could improve in your approach and your coding style.
请注意,下面的答案仍然是“正确的”,因为您的代码确实做错了,但这不是导致错误值的原因。如果您希望那里的人告诉您您可以改进您的方法和编码风格,请尝试将您的(工作)代码带到http://codereview.stackexchange.com。
Previous answer
上一个答案
You are checking for a new greatest product inside the inner loop instead of outside. This means that your maximum includes all strings of less or equal ton 13 digits, rather than only exactly 13.
您正在内部循环内而不是外部检查新的最伟大的产品。这意味着您的最大值包括小于或等于 13 位数字的所有字符串,而不仅仅是 13 位数字。
This could make a difference if you are finding a string which has fewer than 13 digits which have a large product, but a 0 at either end. You shouldn't count this as the largest, but your code does. (I haven't checked if this does actually happen.)
如果您找到的字符串少于 13 位且产品很大,但两端都是 0,这可能会有所不同。您不应该将此视为最大的,但您的代码确实如此。(我还没有检查这是否真的发生了。)
for (int i=0; i < num.length() -12; i++)
{
product = ((int) num[i] - 48);
for (int j=i+1; j<i+13; j++)
{
product = product * ((int) num[j] - 48);
}
if (greatestProduct <= product)
{
greatestProduct = product;
}
}
回答by Artem Sobolev
9^13 ≈ 2.54e12 (maximal possible value, needs 42 bit to be represented exactly), which doesn't fit into signed int
. You should use int64.
9^13 ≈ 2.54e12(最大可能值,需要精确表示 42 位),不适合signed int
. 您应该使用 int64。
回答by Alex Gian
If you don't want to mess with BigNum libraries, you could just take logarithms of your digits (rejecting 0) and add them up. It amounts to the same comparison.
如果您不想弄乱 BigNum 库,您可以只取数字的对数(拒绝 0)并将它们相加。它相当于相同的比较。
回答by Andrey
A faster way without internal loop, but works only where there isn't a 0
in the input:
一种没有内部循环的更快方法,但仅适用0
于输入中没有 a的情况:
long long greatest(string num)
{
if (num.length() < 13)
return 0;
// Find a product of first 13 numbers.
long long product = 1;
unsigned int i;
for (i=0; i<13; ++i) {
product *= (num[i]-'0');
}
long long greatest_product = product;
// move through the large number
for (i=0; i+13<num.length(); ++i) {
product = product/(num[i]-'0')*(num[i+13]-'0');
if (greatest_product < product)
greatest_product = product;
}
return greatest_product;
}
In order to make this work with inputs containing 0
, split the input string into substrings:
为了使其与包含0
的输入一起使用,请将输入字符串拆分为子字符串:
int main()
{
string num = /* input value*/;
long long greatest_product = 0;
size_t start = -1;
// Iterate over substrings without zero
do {
++start;
size_t end = num.find('0', start);
long long product = greatest(num.substr(start, end-start));
if (greatest_product < product)
greatest_product = product;
start = end;
} while (start != string::npos);
cout << greatest_product << endl;
}
回答by Muhammed Afsal
public static void main(String[] args) {
String val = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
int Sum = 0;
String adjacent = null;
for (int i = 0; i < val.length()-13; i++) {
int total = 1;
for (int j = 0; j < 13; j++) {
total = total * Character.getNumericValue(val.charAt(i+j));
}
if(total > Sum){
Sum = total;
adjacent = val.substring(i, i+13);
}
}
System.out.println("Sum = " + Sum);
System.out.println("Adjsc = " + adjacent );
}
回答by Vu Anh
My functional programming solution
我的函数式编程解决方案
def product(number):
product_result = 1
for n in number:
product_result *= int(n)
return product_result
length = 13
indices = range(0, len(number) - 13 + 1)
values = indices
values = map(lambda index: {"index": index, "number": number}, values)
values = map(lambda value: value["number"][value["index"]:value["index"] + length], values)
values = map(product, values)
values = max(values)
print values
回答by Jimmy Suh
I had the same problem. int product and int greatestproduct have maximum value it can store since they are 'int' type. They can only store values up to 2147483647.
我有同样的问题。int product 和 int bestproduct 具有可以存储的最大值,因为它们是“int”类型。它们最多只能存储 2147483647 的值。
Use 'long long' type instead of 'int'.
使用“long long”类型而不是“int”。
回答by sai krishna
const thousandDigit =
`73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450`;
const productsOfAdjacentNths = num =>
[...thousandDigit].reduce((acc, _, idx) => {
const nthDigitAdjX = [...thousandDigit.substr(idx, num)].reduce(
(inAcc, inCur) => inCur * inAcc,
1
);
return acc.concat(nthDigitAdjX);
}, []);
console.log(Math.max(...productsOfAdjacentNths(13))); //5377010688
回答by tan pham
This is my O(n) approach
这是我的 O(n) 方法
function findLargest(digits, n){
let largest = 0;
let j = 0;
let res = 1;
for(let i = 0; i< digits.length; i ++){
res = res * parseInt(digits[i]);
if(res == 0){
res = 1;
j = 0;
continue;
}
if(j === n-1){
if(res > largest)
largest = res;
res = res/parseInt(digits[i - j]);
j = j - 1;
}
j = j + 1;
}
return largest;
}
let val = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
findLargest(val, 13);
回答by Rocky Jain
I have solve this problem using python 're' module
我已经使用 python 're' 模块解决了这个问题
Finding all possible 13 digits number without having zeros (total 988 with zero and 283 without zero) then find the product of each of these digits and check for max
找到所有可能的 13 位没有零的数字(总共 988 个有零,283 个没有零)然后找到这些数字中的每一个的乘积并检查最大值
here i have used look ahead regex
在这里我使用了前瞻正则表达式
Note: string must not contain any newline char
注意:字符串不能包含任何换行符
s = '731671765...'
s = '731671765 ...'
import re
def product_13(d):
pro = 1
while d:
pro *= d % 10
d //= 10
return pro
pat = re.compile(r'(?=([1-9]{13}))')
all = map(int, re.findall(pat, s))
pro = -1
for i in all:
v = product_13(i)
if pro < v:
pro = v
print(pro)