输入m∈[1,9],输入任意正整数n,求n里出现了多少次数字m
第一种是线性实现,轮询每个数字,到百万量级时就不行了
//
//
//
//
int count_nums(int m, int n)
{
int count = 0;
char n_str = m + '0';
// n里多少个数字有m
for(int i=1; i<n; ++i){
for(const char &ch : to_string(i))
if(ch == n_str){
count += 1;
break;
}
}
return count;
}第二种是先构造一个每位有多少相同数字的表,然后查表实现,由牛客网@言1997 同学提供
帖子地址:https://www.nowcoder.com/discuss/630291?source_id=profile_create_nctrack&channel=-1
//
// 输入m∈[1,9],输入任意正整数n,求n里出现了多少次数字m
//
// 第一种是线性实现,鄙视
int count_nums2(int m, int n)
{
int n1 = n / 10, k = 10, idx;
vector<int> count = { 0,1 }, nums = { n % 10 };
while (n1 > 0) {
count.push_back(count.back() * 9 + k);
nums.push_back(n1 % 10);
k *= 10;
n1 /= 10;
}
// for(int i:count) cout<<i<<' ';
// cout<<endl;
// for(int i:nums) cout<<i<<' ';
// cout<<endl;
int ans = 0;
for (int i = nums.size() - 1; i > -1; --i) {
k /= 10;
//cout<<k<<endl;
if (nums[i] <= m) {
ans += count[i] * nums[i];
if (nums[i] == m) {
ans += n % k;
break;
}
}
else {
ans += count[i] * (nums[i] - 1) + k;
}
}
return ans;
}第三种是我自己实现的查表法,毕竟懂原理是一方面,会敲出来是另一方面
vector<int> create_table(int number, bool print=false)
{
// 构造表
vector<int> unit_count = {0, 1};
for(int unit=100; unit < number; unit*=10) {
int count = 9 * unit_count[unit_count.size()-1] + unit / 10;
unit_count.push_back(count);
}
// 输出构造后的表结构
cout << "{ ";
if(print)
for(const int& val : unit_count)
cout << val << ' ';
cout << " }" << endl;
//
return unit_count;
}
int count_nums3(int m, int n, const vector<int>& table = vector<int>())
{
int ret = 0;
vector<int> tb = table.empty() ? create_table(n) : table;
// 将目标拆分为两部分
int tail = 0;
auto str = to_string(n);
auto idx = str.find(m+'0');
if(idx != string::npos && idx != str.size()-1) {
n = stoi(str.substr(0, idx+1));
auto tmp = str.substr(idx+1, str.size()-idx);
tail = stoi(tmp);
n *= pow(10, tmp.size());
str = to_string(n);
}
//
int unit = 1;
for(int i=0, len=str.size();
i < len;
++i, unit*=10)
{
int bit = str[len - i - 1] - '0'; // 获取该十进制bit上的元素
auto tmp = (bit - (bit > m)) * tb[i] + (bit > m) * unit;
ret += tmp;
}
//
cout << ret << " " << tail << " " << n << endl;
ret += tail;
return ret;
}
这里是测试用的主函数
int main() {
// 输入m∈[1,9],输入任意正整数n,求n里出现了多少次数字m
int m, n;
m = 2;
n = 316541656;
//
auto table = create_table(n, true);
auto res = count_nums3(m, n, table);
cout << "count_nums3:\t" << res << endl;
cout << "count_nums2:\t" << count_nums2(m, n) << endl;
cout << "count_nums:\t" << count_nums(m, n) << endl;
}



京公网安备 11010502036488号