1 算法描述
给定两个整数 l 和 r ,对于所有满足1 ≤ l ≤ x ≤ r ≤ 10^9 的 x ,把 x 的所有约数全部写下来。对于每个写下来的数,只保留最高位的那个数码。求1~9每个数码出现的次数。
2 算法分析
本章节的算法分析包括两个步骤:用例分析与逻辑分析。
2.1 用例分析
用例名称 | 输入 | 分析步骤 | 输出 |
<10约数用例 | I=1 r=6 | 代入条件可得: 1=<x<=6,x的列表={1,2,3,4,5,6}, 6的约数集={1,2,3,6}, 5的约数集={1,5}, 4的约数集={1,2,4}, 3的约数集={1,3}, 2的约数集={1,2}, 1的约数集={1} | 6出现1次, 5出现1次, 4出现1次, 3出现2次, 2出现3次, 1出现6次数 |
>=10约数用例 | I=9 r=13 | 代入条件可得: 9=<x<=13,x的列表={9,10,11,12,13}, 9的约数集={1,3,9}, 10的约数集={1,2,5,10}, 11的约数集={1,11}, 12的约数集={1,2,3,4,6,12}, 13的约数集={1,13} (其中,大于9的约数取最大的数值,例如约数13,取最高数码值3) | 9出现1次 6出现1次 5出现1次 4出现1次 3出现3次 2出现3次 1出现7次 |
2.2 逻辑分析
算法主流程分析:
由以上的分析可知,算法的主要逻辑分为三个步骤:
-
从输入参数中获取上下界限的值
-
遍历上下界限的值中的每个数N,计算数值N的约数集合Y
-
合并每个数的约数集合Y,统计集合Y中数码次数的映射集合T
-
输出集合T
其中Y中无重复数字出现。
约数算法流程分析:
每个数值是偶数或者奇数,也就是2n或者2n+1,其约数小于或者等于n,等于1、2n或者2n+1
取约数中最高数码值流程分析:
遍历数字序列中每位数码值,取最大值
统计约数数码次数流程分析:
从约数合并集合中获取每个数值,统计其出现的次数,大于或等于10的数值,从数字序列中取最大数码值作为统计项
3 算法目标
算法运行的目标是最小化系统资源开销(包括处理器资源开销与内存资源开销)以及最小耗时(算法运行时长)。
4 算法设计
4.1 数据结构设计
名称 | 类型 | 长度 | 描述 |
输入整数数列范围 | 最小值I,最大值r,其中I>=1,r<=10的9次方 | r-I+1 | 待处理整数数列的列表 |
约数集合 | 一维整型数组 | 长度等于元素的大小 | 索引位值标识为1的,索引位等于约数的值 |
统计约数个数集合 | 一维整型数组 | 10 | 数组索引位标识1到9的数码,每个索引位的值表示该索引位对应数码的统计值 |
4.2 算法逻辑设计
算法主流程设计:
-
从输入参数确定数值x的范围
-
迭代数值x范围内的数值,获得每个元素N,调用约数算法对数值N生成约数数组Y
-
调用统计约数算法对数组Y统计数码出现次数,生成数组C
-
返回数组C
-
迭代数组C,输出每个索引位对应的统计值
约数算法流程设计:
-
假设数值N是偶数,形式为2n,其约数是偶数数列中的某元素E,则E*S=2n,其中S是另一个约数,并且约数E、S小于等于n,保存E与S的值到约数集合中,并且约数集合中不能出现重复元素
-
假设数值N是奇数,形式是2n+1,其约数是奇数数列中的某元素E,则E*S=2n+1,其中S是另一个约数,并且约数E、S小于等于n,保存E与S值到约数集合中,并且约数集合中不能出现重复元素
约数最大数码位流程设计:
迭代并从约数的数码位序列中,取最大的数码值
约数集合统计数码次数流程设计:
迭代约数集合,从约数元素数值序列中获取最大数码值,统计所有数码值出现的次数,其中数码值大小范围是1到9
5 算法实现
5.1 程序语言
本程序设计使用Java语言。
5.2 程序示例
算法主流程代码示例:
约数算法流程代码示例:
约数最大数码位流程代码示例:
约数集合统计数码次数流程代码示例:
6 算法验证
本算法验证测试使用代码覆盖率测试方法。
6.1 测试用例
用例描述 | 输入数列 | 输入数列长度 | 输出数列 | 输出数列长度 | 覆盖函数 |
小于10范围的用例 | 随机生成上下界限 | 由随机数决定 | 由随机数决定 | 10 | 所有函数 |
大于或等于10范围的用例 | 随机生成上下界限 | 由随机数决定 | 由随机数决定 | 10 | 所有函数 |
6.2 执行用例
测试用例通过率100%,代码覆盖率100%。
7 算法效率
7.1 时间复杂度
由代码可知该算法的时间复杂度等于O(N的多次方)。
7.2 空间复杂度
该算法使用一维数组,其空间复杂度是常数。
7.3 性能测试
输入数列长度 | 输出数列长度 | 耗时 |
100范围 | 10 | 1毫秒 |
1000范围 | 10 | 23毫秒 |
10000范围 | 10 | 423毫秒 |
100000范围 | 10 | 30431毫秒 |
由以上的性能测试可知,每增加一个数量级范围,耗时增长很快,在这种的情况下需要进行算法优化。
7.4 算法优化
多线程的方式启动多个worker工作线程处理计算约数函数。