统计数字问题

 

在王晓东编著的《算法设计与实验题解》中看到的这个问题,问题描述如下:
一本书的页码从自然数1开始顺序编码直到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。例如第6页用6表示而不是06或006。数字统计问题要求对给定书的总页码,计算出书的全部页码中分别用到多少次数字0,1,2,3,.....9。
这个题目有个最容易想到的n*log10(n)的算法。这是自己写的复杂度为O(n*log10(n))的代码:

 

int n;
int c[10];//计数
void calc()
{
    for(int i=1;i<=n;i++)
    {
        int j=i;
        do
        {
            c[j%10]++;
            j/=10;
        }while(j!=0);
    }

    for(int i=0;i<10;i++)
        cout<<c[i]<<endl;
}


int main()
{
    while(cin>>n)
    {
        calc();
    }

    return 0;
}

 

写了个脚本来处理测试数据:

 

t=`find  test -type f`
mkdir answer1
for i in $t; do
    echo $i
    pos=${#i}-4
    echo ${i:$pos:1}
    k=${i:$pos:1}
    ./count < $i > answer1/count${k}.out
done

formdos answer/* 转换编码

diff -ru answer answer1

 

 

更优算法;

http://blog.csdn.net/jcwkyl/article/details/3009244

考察由0,1,2...9组成的所有n位数。从n个0到n个9共有10^n个n位数。在这10^n个n位数中,0,1,2.....9每个数字使用次数相同,设为f(n)。f(n)满足如下递推式:

n=1情况: f(n) =1

n>1情况: f(n) = 10f(n-1)+10^(n-1)

最前面可添加0-9 这十个数字,所以后面所有数字出现次数为 10f(n-1)  ,加上最前面这个数字自己出现的次数10^(n-1)

f(2)=10*1+10^1=20

据此,可从高位向低位进行统计,再减去多余的0的个数即可。

 

10(10f(n-2)+10^(n-2))+10^(n-1) = 10^2*f(n-2)+2*10^(n-1) = 10^(n-1)*f(1) +(n-1)*10^(n-1) =n*10^(n-1)

 

bash 固定位置截取

${varible:start:len}:截取变量varible从位置start开始长度为len的子串。第一个字符的位置为0。

posted @ 2015-04-02 11:15  katago  阅读(2405)  评论(0)    收藏  举报