我试图解决一个函数问题,其中我必须计算数字1在所有小于n(给定)的非负整数中出现的次数。
这是我的代码:
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;
}
但是出现以下编译错误:
第3行:类型'__gnu_cxx :: __ promote_2 :: __ type {aka double}'和'int'到二进制'operator%'的无效操作数
答案 0 :(得分:2)
主要问题是类型转换。 pow
的结果为double
。模运算符不适用于double
。您需要拿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 1个,再加上10个则为10 ... 19。等等。您可以使用以下方法计算给定大小下的数量:
int exp = (int)log10(n);
int ones = exp * (int)pow(10, exp - 1);
其中n
的大小必须为10(例如10、100、1000、10000 ...)。如果您擅长数学,甚至可能会找到一个完整的封闭式。
答案 1 :(得分:2)
函数pow
返回一个double。模运算在整数之间,因此会出现错误-您正在尝试在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);