项目欧拉#8,我不明白我哪里出错了

时间:2014-05-23 08:38:17

标签: c++

我正在研究八号项目的问题,其中我提供了这个非常大的数字:

73167176531330624919225119674426574742355349194934 96983520312774506326239578318016984801869478851843 85861560789112949495459501737958331952853208805511 12540698747158523863050715693290963295227443043557 66896648950445244523161731856403098711121722383113 62229893423380308135336276614282806444486645238749 30358907296290491560440772390713810515859307960866 70172427121883998797908792274921901699720888093776 65727333001053367881220235421809751254540594752243 52584907711670556013604839586446706324415722155397 53697817977846174064955149290862569321978468622482 83972241375657056057490261407972968652414535100474 82166370484403199890008895243450658541227588666881 16427171479924442928230863465674813919123162824586 17866458359124566529476545682848912883142607690042 24219022671055626321111109370544217506941658960408 07198403850962455444362981230987879927244284909188 84580156166097919133875499200524063689912560717606 05886116467109405077541002256983155200055935729725 71636269561882670428252483600823257530420752963450

我应该“找到1000位数字中具有最大产品的13个相邻数字。” 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;
}

我一直得到2091059712作为解决方案,因为欧拉告诉我的项目是错误的,我怀疑它太大了。任何帮助将不胜感激。

编辑:更改为unsigned long int并且它有效。谢谢大家!

20 个答案:

答案 0 :(得分:21)

事实上,您的解决方案太小而不是太大。答案是注释中指出的,存在整数溢出,并且线索是您的解决方案接近签名int的最大可能值:2147483647.您需要使用不同的类型来存储产品。

请注意,以下答案仍然是正确的&#39;因为你的代码确实做错了,但它不是造成错误值的原因。如果您希望那里的人告诉您可以改进的方法和编码风格,请尝试将您的(工作)代码发送到http://codereview.stackexchange.com

以前的回答

您正在检查内部循环内部而非外部的新产品。这意味着您的最大值包括所有小于或等于13位数的字符串,而不仅仅是13。

如果您找到的字符串少于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;
    }
}

答案 1 :(得分:5)

9 ^13≈2.54e12(最大可能值,需要42位完全表示),它不适合signed int。你应该使用int64。

答案 2 :(得分:2)

如果你不想弄乱BigNum库,你可以只取数字的对数(拒绝0)并加起来。它相当于同样的比较。

答案 3 :(得分:1)

我有同样的问题。 int product和int greatproduct具有“ int”类型,因此可以存储的最大值。他们最多只能存储2147483647的值。

使用“ long long”类型代替“ int”。

答案 4 :(得分:0)

我用这种方法解决了问题

1.首先运行两个循环,循环遍历字符串中的数字。

2.内循环之后到达接下来的13个数字并将其乘积存储在变量中

3.当内循环结束时,我们只使用最大值。(这是我们需要的):>

看看我的 C++ 代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s="//thestring is there";
    long long unsigned mainans=1,ans=1;           //initialize the value of mainans and ans to 1 (not 0 as product also become 0)
    for(int i=0;i<s.length()-13;i++)             //run the loop from 0 upto 13 minus string length
    {
        ans=1;
        for(int j=i;j<i+13;j++)                //now from that particular digit we check 13 digits afterwards it
        {
            int m=s[j]-'0';                   //convert the number from string to integer
            ans*=m;                           //taking product in every interation for 13 digits 
        }
        mainans=max(mainans,ans);            //now taking only max value because that what we need
    }
    cout<<mainans;
    return 0;
}

答案 5 :(得分:0)

我用红宝石解决了它。如果

x = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"

然后使用下面的逻辑来解决问题

def print_lps(x)
    p = 1
    0.upto(x.length-13) do |i|
      j = i
      xy = 1
      while j < i+13 do
        xy *= x[j].to_i 
        j += 1 
      end
      p = xy if xy > p
    end
    puts p
end

print_lps(x) # 23514624000

答案 6 :(得分:0)

我的2美分... Javascript

Largest_product_in_series_13 = g => {
                 return [...g.matchAll(/(?=([1-9]{13}))/g)]
                        .reduce((a,c)=>(p=eval(c[1].split``.join`*`),p>a?p:a),0)
}

首先,它与所有13位数字系列匹配,然后降为最大乘积。

console.log(Largest_product_in_series_13(`7316717653133062491922....

> 23514624000 开始:14.292ms

答案 7 :(得分:0)

这是我的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);

答案 8 :(得分:0)

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

答案 9 :(得分:0)

您应在'int'位置使用'int64_t'

答案 10 :(得分:0)

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 );

}

答案 11 :(得分:0)

我的函数式编程解决方案

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

答案 12 :(得分:0)

static long q8(){
        long max_product = 1;
        long product = 1;
        String n = "LONG_INPUT";
        for(int i=0;i<13;i++){
            max_product *= Integer.parseInt(n.charAt(i)+"");
        }
        product = max_product;
        for(int i=1;i<n.length()-13;i++){
            int denom = Integer.parseInt(n.charAt(i-1)+"");
            if(denom!=0)
                product = product/denom * Integer.parseInt(n.charAt(i+12)+"");
            else
                product = product(i,n);
            max_product = (max_product>product)?max_product:product;
        }

        return max_product;
    }
    static long product(int index,String n){
        long pro = 1;
        for(int i=index;i<index+13;i++){
            pro *= Integer.parseInt(n.charAt(i)+"");
        }
        return pro;
    }

答案 13 :(得分:0)

没有内部循环的更快捷方式,但仅适用于输入中没有0的情况:

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;
}

为了使用包含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;
}

答案 14 :(得分:-1)

如果有人在2018年仍在观看此问题,我对上述问题的解决方案尽管这里有很多解决方案,但我的解决方案会预先检查其中包含0的单个13位数字,因为总是乘以0 0,因此我们可以删除这种无用的计算

import uuid4

consent_id = str(uuid.uuid4())
with requests.Session() as session:
    session.cookies = {'euConsentId': consent_id}

    response = session.get(...)

答案 15 :(得分:-1)

这将在O(n)时间内找到答案并处理零。写在Dart。

/**
 * Main function
 *
 * Find the thirteen adjacent digits in the 1000-digit number that have the greatest product.
 * What is the value of this product?
 *
 */
const String DIGITS = "73167176531330624919225119674426574742355349194934"
                      "96983520312774506326239578318016984801869478851843"
                      "85861560789112949495459501737958331952853208805511"
                      "12540698747158523863050715693290963295227443043557"
                      "66896648950445244523161731856403098711121722383113"
                      "62229893423380308135336276614282806444486645238749"
                      "30358907296290491560440772390713810515859307960866"
                      "70172427121883998797908792274921901699720888093776"
                      "65727333001053367881220235421809751254540594752243"
                      "52584907711670556013604839586446706324415722155397"
                      "53697817977846174064955149290862569321978468622482"
                      "83972241375657056057490261407972968652414535100474"
                      "82166370484403199890008895243450658541227588666881"
                      "16427171479924442928230863465674813919123162824586"
                      "17866458359124566529476545682848912883142607690042"
                      "24219022671055626321111109370544217506941658960408"
                      "07198403850962455444362981230987879927244284909188"
                      "84580156166097919133875499200524063689912560717606"
                      "05886116467109405077541002256983155200055935729725"
                      "71636269561882670428252483600823257530420752963450";

main(List<String> args) {

  const int MAX_DIGITS = 13;
  int len = DIGITS.length;

  int digits = 0;
  int largest = 0;
  int current = 0;

  int index = 0;
  while (index < len) {

    int value = int.parse(DIGITS[index]);

    // if we get a zero then rebuild the MAX_DIGITS consecutive digits
    if (value == 0) {
      current = 0;
      digits = 0;
    } else {
      // Multiply consecutive digits up to target set
      if (digits < MAX_DIGITS) {
        if (current == 0) {
          current = value;
        } else
          current *= value;
        digits++;
      } else {
        int divisor = int.parse(DIGITS[index - MAX_DIGITS]);

        if (current == 0) {
          current = value;
        } else {
          current = (current ~/ divisor);
          current *= value;
        }
      }

      if (current > largest) {
        largest = current;
      }
    }

    index++;
  }

  print('Num  $largest');
}

答案 16 :(得分:-1)

我已经使用python're'模块解决了这个问题

查找所有可能的13位数字而没有零(总数988为零和283没有零),然后找到每个数字的乘积并检查最大值

在这里我使用了正则表达式正则表达式

注意:字符串不能包含任何换行符

  

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)

答案 17 :(得分:-1)

**This is JavaScript solution.**


greatestProductOfAdjacentDigit = (givenNumber, noOfDigit) => {
stringNumberToNumbers = givenNumber => givenNumber.split('').map(each => parseInt(each, 10))

            let numbers = mathematicalProblems.stringNumberToNumbers(givenNumber);
            return numbers.map(function (each, ind, arr) {
                return mathematicalProblems.productOfAll(arr.slice(ind, ind + noOfDigit));
            }).reduce(function (accumulator, currentValue) {
                return accumulator > currentValue ? accumulator : currentValue;
            });
        };

测试

const givenNumber = '73167176531330624919225119674426574742355349' +
                '194934969835203127745063262395783180169848018694788518438586' +
                '156078911294949545950173795833195285320880551112540698747158' +
                '523863050715693290963295227443043557668966489504452445231617' +
                '318564030987111217223831136222989342338030813533627661428280' +
                '644448664523874930358907296290491560440772390713810515859307' +
                '960866701724271218839987979087922749219016997208880937766572' +
                '733300105336788122023542180975125454059475224352584907711670' +
                '556013604839586446706324415722155397536978179778461740649551' +
                '492908625693219784686224828397224137565705605749026140797296' +
                '865241453510047482166370484403199890008895243450658541227588' +
                '666881164271714799244429282308634656748139191231628245861786' +
                '645835912456652947654568284891288314260769004224219022671055' +
                '626321111109370544217506941658960408071984038509624554443629' +
                '812309878799272442849091888458015616609791913387549920052406' +
                '368991256071760605886116467109405077541002256983155200055935' +
                '72972571636269561882670428252483600823257530420752963450';

console.log(greatestProductOfAdjacentDigit(givenNumber, 4)); //5832
console.log(greatestProductOfAdjacentDigit(givenNumber, 13)); //23514624000

答案 18 :(得分:-1)

试试这个:

    {
        DateTime BeganAt = new DateTime();

        BeganAt = DateTime.Now;

        Int64 result = 0;

        string testNumber = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";

        StringBuilder StringBuilder = new StringBuilder(13);

        Int64 maxNumber = 0;

        try
        {
            char[] numbers = testNumber.ToCharArray();

            int tempCounter = 13;

            for (int i = 0;i < numbers.Length;i++)
            {
                if(i < tempCounter)
                {
                    StringBuilder.Append(numbers[i]);
                }
                else if (i == tempCounter)
                {
                    if (maxNumber < Convert.ToInt64(StringBuilder.ToString()))
                    {
                        maxNumber = Convert.ToInt64(StringBuilder.ToString());
                    }

                    StringBuilder.Clear();
                    StringBuilder.Append(numbers[i]);
                    tempCounter = tempCounter + n;
                }
            }

            result = maxNumber;
        }
        catch
        {
            throw;
        }

        DateTime EndedAt = new DateTime();

        EndedAt = DateTime.Now;

        TimeSpan TimeItTook = (EndedAt - BeganAt);

        return Convert.ToString(result) + " - Time took to execute: " + Convert.ToString(TimeItTook.TotalMilliseconds);
    }

答案 19 :(得分:-1)

虽然上面的解决方案很好,但这里有一个完美的python实现:

def main():
      num=7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
      prod,maxprod=1,0
      numtostr=str(num)
      length=len(numtostr)
      for i in range(1,length-13+1):
          prod=1
          for z in range(i,i+13):
              prod=prod*int(numtostr[z-1:z])
              if prod>maxprod:
                  maxprod=prod
      print "Largest 13 digit product is %d" %(maxprod)

 if __name__ == '__main__':
       main()