问题概述
题目:算法-数位递增的数-
问题描述:
一个正整数如果任何一个数位不大于右边相邻的数位,则称为一个数位递增的数,
例如1135是一个数位递增的数,而1024不是一个数位递增的数.
给定正整数 n,请问在整数 1 至 n 中有多少个数位递增的数?
输入:
输入的第一行包含一个整数 n。
输出:
输出一行包含一个整数,表示答案。
样例输入:
30
样例输出:
26
1. 问题分析
1.1 算法核心
这是一道初级算法题,较为容易,算法核心点在于对于整形数的认识,快速解出题目是我们的终极目标;
1.2 算法分析
虽然这是一道初级算法题,但是有很多进阶的算法题类似整形数问题都是由此演变而来的,注重底层细节是我们写算法的程序猿必不可少的素质;
而本题最重要的底层细节就是整形数的处理,一般我们会想到利用C++的STL容器string字符串类对象去解决,即下面解决方案的第一个声明函数checkIncreaseByString,从字符串尾开始向前比较,只要有一个不符合递增规律就说明不满足题意直接返回false即可,表示这个整形数不是数位递增的数,如果正常退出比较循环说明这是一个数位递增的数,返回true表示,然后相应的让我们预先定义的计数器+1就行,最后按照题目要求输出即可;
需要注意的点就是这类整形数题目有多种解决方法,可以利用字符串string类对象的函数,也可以利用数学计算的特点,比如求余运算等对整形数做处理。针对这两种方法呢,我进行了性能测试,最后发现利用string类对象的方法性能较差,性能上两者至少差了10倍,这也启示我们类虽然解决了代码复用的问题,封装了很多函数属性等,给我们程序猿带来很大便利,但很多优秀的算法的核心其实是依靠的程序猿的思维过程,一个程序猿很熟悉底层细节,那么他就能设计出一个针对某个问题效率很高的算法,这一点是母庸质疑的!
2. 解决方案
#include <iostream>
#include <string>
using namespace std;
bool checkIncreaseByString(int t);
bool checkIncreaseByInteger(int t);
int main()
{
int ans = 0, n;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
//if(checkIncreaseByString(i)) ans++;
if(checkIncreaseByInteger(i)) ans++;
printf("%d\n", ans);
return 0;
}
bool checkIncreaseByString(int t)
{
char temp[8];
sprintf(temp, "%d", t);
string s(temp);
for(int i = 1; i < s.size(); i++)
if(s[i - 1] > s[i]) return false;
return true;
}
bool checkIncreaseByInteger(int t)
{
int t1 = t % 10;
int t2;
t /= 10;
while(t)
{
t2 = t % 10;
if(t1 < t2)
return false;
t1 = t2;
t /= 10;
}
return true;
}
3. 资源分享
旗木白哉のGitHub:
https://github.com/YangMengHeng
C++ / C源代码下载地址:
https://github.com/YangMengHeng/myCode/tree/master/VSCode
Java源代码下载地址:
https://github.com/YangMengHeng/myCode/tree/master/Java
旗木白哉のblog源代码下载地址:
https://github.com/YangMengHeng/myCode/tree/master/%E6%97%97%E6%9C%A8%E7%99%BD%E5%93%89%E3%81%AEblog