任务
求出 10000 以内所有数字的因数和。
可能已经想好的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <stdio.h> int sum[10005] = {0};
void init_sum() { for (int i = 1; i <= 10000; i++) { for (int j = 1; j <= i; j++) { if (i % j) continue; sum[i] += j; } } return ; }
int main() { init_sum(); printf("hello world\n"); return 0; }
|
效率较低,所以弃了。
编码
数论积性函数
所谓数论积性函数,首先,是作用在正整数范围的函数,也就是说函数 f(x) = y 中的 x 均是正整数。其次,是数论积性函数的一个最重要的性质,就是如果 n 和 m 互质,那么 f(n*m) = f(n) * f(m) 。
因数个数函数
因数个数:就不难理解了,它指的是一个数字因数的数量。例如,数字 6,有 1、2、3、6 这 4 个因数,因数个数就是 4。
素数筛框架
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #define MAX_N 10000 int prime[MAX_N + 5] = {0}; void init_prime() { for (int i = 2; i * i <= MAX_N; i++) { if (prime[i]) continue; prime[i] = i; for (int j = 2 * i; j <= MAX_N; j += i) { if (prime[j]) continue; prime[j] = i; } } for (int i = 2; i <= MAX_N; i++) { if (prime[i] == 0) prime[i] = i; } return ; }
|
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #define MAX_N 10000 int prime[MAX_N + 5] = {0}; int g_cnt[MAX_N + 5]; void init_g_cnt() { g_cnt[1] = 1; for (int i = 2; i <= MAX_N; i++) { int n = i, cnt = 0, p = prime[i]; while (n % p == 0) { cnt += 1; n /= p; } g_cnt[i] = g_cnt[n] * (cnt + 1); } return ; }
|
小结
- 所谓代码框架,就是要活学活用。
- 在真正的工作中,你所做的事情,大多是在多种代码框架之间做选择及组合拼装,每个算法代码只会解决遇到的一部分问题。而你在使用这些算法代码的时候,往往不能照搬照用,反而要做一些适应性的改变,这些都是“框架思维”中所重视的。