编程随想:论数学的重要性

今天樊皓东问了我一道程序设计的题目:

求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字,最后一项长度为n。

给出的内置代码:

#include <stdio.h>
#include <math.h>

long int process (int a, int n){
    //请你完成这段代码。
}

int main(int argc, const char * argv[]) {
    long int s=0;
    s=process(2, 5);
    printf("%ld\n",s);
    return 0;
}

题目非常简单,相信对程序设计多少有些了解的同学应该可以通过循环写出这个程序,比如下面:

long int process (int a, int n){
    int everyTimeNumber=0;
    long int sum=0;
    for (int i=0; i<n; i++){
        everyTimeNumber+=(int)pow(10,i)*a;
        //printf("第%d次数生成的数字是:%d\n",i,everyTimeNumber);
        sum+=everyTimeNumber;
    }
    return sum;

但是循环程序的效率并不高,特别是如果数量非常庞大的情况下程序的运行需要耗费相对多的时间。这个问题若能直接给出数学解答则是极大地提高了程序的运行效率。

如果对数字敏感,我们可以轻易的写出若干9的表达形式:\(10^{n}-1\)

由若干9转化为若干数字a,只需要等比例缩放即可,我们可以轻易的得到通项公式:

\(a_{n}=\frac{a}{9}\cdot(10^{n}-1)\)

显然通项公式中是一个等比数列和一个等差数列的线性运算,而且等差数列为a/9的常数列,应用等差数列和等比数列的求和公式对通项进行累加,我们很容易得到:

\(S_{n}=a+aa+...+a...a\)
\(=\frac{a}{9}[(10-1)+(10^{2}-1)+(10^{3}-1)+...+(10^{n}-1)]\)
\(=\frac{a}{9}[\frac{10(10^{n}-1)}{10-1}-n]\)

显然,程序可以精简成:

long int process (int a, int n){
    return (long int)(a*((10*(pow(10,n)-1)/9)-n)/9);
}

程序得到极大简化,运行效率得到显著提升。

分享