【问题标题】:int64_t doesn't hold 13 digit integerint64_t 不包含 13 位整数
【发布时间】:2018-12-19 21:45:59
【问题描述】:

我的程序可以正常处理最多 10 位的数字,但是当我使用hackerrank 编译器时,任何数字都会导致它输出错误的数字。但是,当我使用 Visual Studio 时,它没有输出任何内容,但我听到某些东西一直在旋转,直到我关闭 cmd 窗口(可能是 CPU)。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    // This program counts the "a" letters in a string (s) depending on how 
    // many iterations(numOfRepetitions) through the string
    string s;
    getline(cin, s);

    int64_t numOfRepetitions;
    cin >> numOfRepetitions;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    int64_t i=0;
    int64_t  countA=0;    // Counting occurances of letter "a"
    for (int64_t x=0; x<numOfRepetitions; x++)
    {


        if (s[i]=='a') countA++;
        if (i==s.length()-1) i=-1;
        i++;

    }

    cout << countA << endl;
    }
    // Input that works:   s = 'a'   numOfRepetitions=1000       Output:1000
    // Input doesn't work: s = 'a'   numOfRepetitions=1000000000000 
    // Output:1410065408 ( it should be: 1000000000000 )

注意:我在其他线程中尝试了使用 long long、int32_t、casting as double ... 等的建议。没有任何效果

【问题讨论】:

  • for (int x=0; x&lt;numOfRepetitions; x++) 如果你打算在一个地方使用 int64_t,你需要在所有地方都使用它。读完后把号码打印出来。如果它就在那里,但您的程序不起作用,那么问题出在其他地方。
  • “我听到一些东西一直在快速旋转,直到我关闭 cmd 窗口(可能是 CPU)” 那是风扇。不过,这表明 CPU 正在努力工作
  • signed 整数溢出是未定义的行为。您的程序很可能正在旋转您的 CPU。
  • 你有没有想过你做错了。计算字符串中a的数量一次,然后相乘。 a 的数量不会改变。
  • 也许 OP 在 c++11 之前的平台上,std::cin 不需要有 operator&gt;&gt;(long long&amp;) 并且使用的是窄类型?

标签: c++ visual-studio c++11 visual-c++ c++14


【解决方案1】:

试试这个选项:

int main()
{
    string s;
    getline(cin, s);
    int64_t numOfRepetitions = 0;
    cin >> numOfRepetitions;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    int64_t countA = 0;
    size_t i = 0;
    for (; i < s.size(); ++i)
        if (s.at(i) == 'a')
            ++countA;
    if (i)
        numOfRepetitions = (numOfRepetitions / i) * countA;
    std::cout << numOfRepetitions << "\n";
    std::cin.get();
    return 0;
}

x

【讨论】:

  • 这是给定代码的替代解决方案,但没有解决为什么结果不正确的问题。其次,at() 是比operator[] 更昂贵的操作,因为它执行边界检查。在不知道索引是否在容器范围内时首选at(),在已知索引时首选operator[]
  • 关于 at 和 operator[]。 Operator[] 用于调试开发。查看 stl 中的某个容器,您会看到 operator[] 旨在更有效地搜索错误。
  • 但这是用于调试版本。 at 需要在运行时进行边界检查,但 operator[] 不是。现在,这两个都允许执行超出要求的任何其他检查。这对于开发人员及早发出问题信号很有用。但是在发布版本中,合理的标准库实现会将这些检查限制在最低限度。调试构建插入的边界检查与选择其中一种方法而不是另一种方法完全无关。请参阅here 进行演示。
  • 其实在 release operator[] 中比 at 方法更有优势。您如何看待 v._Get_data()._Myfirst[index]?如果我们确定索引正确,使用此选项来提高速度是否有意义?
  • 不,因为标准没有定义这些方法。而且它可能根本不会提高速度。您的平台是否公开公开实施细节?
【解决方案2】:

您解决问题的方式比实际需要的要困难得多。您可以通过计算完整字符串的“a”字符数以及剩余和相乘的字符数来得到答案。

在这些编程挑战中,蛮力解决方案很少是正确的。您的庞大循环将需要很长时间才能运行。

long repeatedString(string s, long n)
{
    long full = n / s.size();
    long rem = n % s.size();
    long count = 0;
    long rem_count = 0;
    for (long i = 0; i < s.size(); ++i)
    {
        if (s[i] == 'a')
        {
            ++count;
            if (i < rem)
            {
                ++rem_count;
            }
        }
    }
    return count * full + rem_count;
}

值得注意的是long不足以在Visual Studio中解决这个问题,您需要更改为long longint64_t。它适用于 Hackerrank,因为它们在 Linux 上编译,其中 long 是 64 位。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多