f(n)=n求法程序的重写

本文介绍了一种计算从1至某个大整数范围内特定数字(如1)出现次数的算法。通过递增数列及减枝优化,提高了算法效率。文中详细解释了算法流程,并附带实现代码。

这个BLOG里有个JAVAEYE的两道题,其中的第二题,提供了一个解法,是减枝的办法。看完这个程序觉得写的比较繁琐一点,且没有任何注释,不容易看懂,所以这里重写程序基本思路一样,不过添加注释 

总的来说就是举例来说,10到19,然后20-29,。。。到了100-199,这样递增数从10,100.。。

有兴趣的可以看看,linkhl好容易原创一个贴呵呵。。。

#define gsize 9
//save f(9),f(99),f(999),f(9999).....
unsigned long gtable[gsize];


unsigned 
long maxn=400000000L;

//initiate the gtable
void initGtable()
{
    
int i=2;
    
int j,n=1;
    
for(i=2;i<gsize;i++){
    
//    n=1;
    
//    for(j=1;j<i;j++)
            n*=10;
        gtable[i]
=gtable[i-1]*10+n;
    }

}

//return count1 ,count how many 1 the n has
unsigned long count1(unsigned long n){
    
int cout=0;
    
while(n){
        
if((n%10)==1){
            cout
++;
        }

        n
=n/10;
    }

    
return cout;
}


//most important, countBefore presents the 1's numbers from 1 to number -1, count1now presents the number of 1 of number parameter,wei presents the valid digit 
//number.
unsigned long cout(unsigned long number, unsigned long countBefore, unsigned long count1now, unsigned long wei){
    unsigned 
long i,n,nwei,maxcount,gcount,nnumber;
    
if(wei==1){
        
if(number==countBefore+count1now){
            printf(
"the fn is number %d ",number);
                    }

        
return countBefore+count1now;
    }

    n
=1;
    gcount
=0;
    nnumber
=number;
    
for(nwei=wei-1;nwei>0;nwei--){n*=10;gcount++;nnumber/=10;}
    maxcount
=countBefore+gtable[gcount]+count1now*n;
    
//here we have cut a lot of branchs.
    if((maxcount<number)||(number+n-1)<countBefore)return maxcount;
    n
/=10;
    
for(i=0;i<10;i++)
        countBefore
=cout(number+i*n,countBefore,((i)==1)?count1now+1:count1now,wei-1);
    
return countBefore;//returning  maxcount  is either ok
}





main()
{
    unsigned 
long  i,wei,temp,n,ret,count1now,countBefore;
    gtable[
0]=0;
    gtable[
1]=1;
    initGtable();
    
for(i=2;i<gsize;i++){
        printf(
"%d ",gtable[i]);
    }

    n
=1;
    wei
=1;
    ret
=0;
    count1now
=1;
    countBefore
=0;
    temp
=1;
    
while(n<maxn){
        countBefore
=cout(n,countBefore,count1now,wei);//n=1,2,3,4,5,6,7,8,9,10,20,...90,100,200,...900,1000,2000,....
        n+=temp;
        
if(!(n%temp)&&(n/temp)==10)
        
{temp*=10;wei++;}//you have add temp 10times.
        count1now=count1(n);
    }

        
        
}
```markdown ### 题目重述 要求求斐波那契数列的第 $n$ 个数,并对给出的 C++ 程序进行修改以正确实现该功能。 --- ### 给出答案(答案为带注释的代码块) ```cpp #include <iostream> using namespace std; // 正确的递归版斐波那契函数 int fib(int n) { if (n == 0) { return 0; // F(0) = 0 } else if (n == 1) { return 1; // F(1) = 1 } else { return fib(n - 1) + fib(n - 2); // F(n) = F(n-1) + F(n-2) } } int main() { int n; cin >> n; // 输入n cout << fib(n); // 输出第n个斐波那契数 return 0; } ``` --- ### 代码解析 1. **原问题分析**: - 原代码存在多处语法错误和逻辑错误: - `usingr namespace std;`:拼写错误,应为 `using namespace std;` - `int m=0:4日5intlhj(int n){`:严重语法混乱,混有乱码 - 函数名 `hj` 不规范,且逻辑中使用全局变量 `m` 计数,导致递归失效 - `else m++;return hj(m-1)+hj(m-2)`:此逻辑破坏了斐波那契递归结构 2. **修改说明**: - 修复所有语法错误 - 重写 `fib` 函数,采用标准递归定义: $$ F(0) = 0,\quad F(1) = 1,\quad F(n) = F(n-1) + F(n-2)\quad (n \geq 2) $$ - 使用 `cin` 输入 $n$,`cout` 输出结果 - 删除无意义的全局变量 `m` 3. **程序行为**: - 输入一个整数 $n$ - 输出斐波那契数列的第 $n$ 项(从第0项开始计数) --- ### 知识点(列出该代码中遇到的知识点) - **递归函数设计**:函数调用自身解决子问题,适用于斐波那契这类具有递推关系的问题。 - **C++基础语法**:包括 `#include`、`using namespace std;`、`cin/cout` 输入输出等基本结构。 - **斐波那契数列定义**:满足 $F(n) = F(n-1) + F(n-2)$ 的整数序列,初始值 $F(0)=0, F(1)=1$。 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值