在 C++ 中使用 pow() 时出错

Error while using pow() in C++

我试图解决一个函数问题,在这个问题中我必须计算数字 1 在所有小于 n(given) 的非负整数中出现的次数。

这是我的代码:

int ones(int n, int d)
{
    int rounddown = n - n % pow(10, d+1);
    int roundup = rounddown + pow(10, d+1);
    int right = n % pow(10, d);
    int dig = (n/pow(10, d)) % 10;
    if(dig<1)
        return rounddown/10;
    else if(dig==1)
        return rounddown/10 + right + 1;
    else
        return roundup/10;
}

int countDigitOne(int n) {

    int count = 0;
    string s = to_string(n);
    for(int i=0;i<s.length();i++)
    count+=ones(n, i);   
    return count;        
}

但是出现以下编译错误:

Line 3: invalid operands of types '__gnu_cxx::__promote_2::__type {aka double}' and 'int' to binary 'operator%'

主要问题是类型转换。 pow is double. The modulo operator does not work for double. You need to take fmod.

的结果

像这样修正第 3 行:

int rounddown = (int)(n - fmod(n, pow(10, d +1));

因为你的值都在integer的域中你也可以使用:

int rounddown = n - n % (int)(pow(10, d + 1));

根据其他人的建议。


只是为了完整性...如果你不是被迫使用算术方法,你可以 char 比较:

#include<iostream>
#include<string>

using namespace std;

int countOnesInNumber(string s)
{
    int res = 0;
    for(int i = 0; i < s.length(); i++)
    {
        if(s[i] == '1')
        {
            res++;
        }
    }
    return res;
}

long countOnes(int upper)
{
    long result = 0;
    for(int i = 0; i < upper; i++)
    {
        result += countOnesInNumber(std::to_string(i));
    }
    return result;
}

int main()
{
    string in;
    cout << "Please enter a number:";
    cin >> in;
    cout << endl;
    cout << "you choose:" << in << endl;
    int n = stoi(in);
    cout << "there are " << countOnes(n) << " ones under " << n << endl;

    cin.ignore();
    cin.get();
}

还有一种更复杂的方法。每个幅度都重复数字。 10 以下有 1 个,100 以下有 1 个 10 的乘积加上另外 10 个 10...19。等等。您可以使用以下方法计算给定幅度以下的数量:

int exp = (int)log10(n);
int ones = exp * (int)pow(10, exp - 1);

其中 n 的大小必须为 10(例如 10、100、1000、10000 ...)。如果你擅长数学,你甚至可能会找到一个完整的封闭公式。

函数powreturns一个双精度。模运算在整数之间进行,因此出现错误 - 您正试图在 int 和 double 之间使用模。解决它的一种方法是使用转换:

int rounddown = n - n % (int)pow(10, d + 1);

正如其他人所说,对整数使用 pow 函数以及从 double 转换为 int 是低效的,并且可能导致错误。我建议(通过同意 Tyler V 的建议)你实现这个简单的递归整数 pow:

int ipow(int a, int b){
    if (b == 0)
        return 1;

    return a * ipow(a,b - 1);
}

这仅适用于正整数 a,b,但我认为就您的目的而言,这已经足够了。现在你可以写

int rounddown = n - n % ipow(10, d + 1);