问题来源:http://topic.csdn.net/u/20080908/20/1b484308-778a-4a22-9586-acabafce8413.html?seed=1357783278原提问者问:一个论坛做一个等级. 
要求是每升级一要增加120%才能升级. 
我统计的是积分,每级要增加120%才能升级 
,假如积分最小分100为1级,那么 
第二级就要求积分为(100*1.2)+100=220 
第三级就是(220*1.2)+100=364 
第四级就是(364*1.2)+100=536.8 
第五级就是(536.8*1.2+100)=744 
依此类推........ 
假如我现在积分为400分那么就是第三级. 
这个公试怎么来实现? 
用for我又不知道循环到哪里为止. 
请教大家一下 
==============================================================={由于问题是在CSDN的ASP版块,所要语言多是VBS或javascript,我不熟悉
所以没有回答
但觉得这个问题有意思,就用Delphi写了一下。}//-----------------------------------------------{首先,循环最简单:}procedure TForm1.Button1Click(Sender: TObject);
var
  F: Extended;
  I, J: integer;
begin
  F := 0.0;
  J := 3;
  for I := 0 to J-1 do
    F := F * 1.2 + 100;
  Showmessage(FloattoStr(F)); {三级的分数}
end;//-----------------------------------------------{然后,感觉可以换用递归算法,于是写了:}procedure Test(J: integer; var F: Extended);
begin
  if J <= 1 then Exit;
  F := (F*1.2) + 100;
  Dec(J);
  Test(J, F);
end;procedure TForm1.Button1Click(Sender: TObject);
var
  F: Extended;
begin
  F := 100;
  Test(3, F);
  Showmessage(FloattoStr(F)); {三级的分数}
end;//-----------------------------------------------{毕意是用递归实现了。但是,感觉写得有些臃肿!
于是又改写了:}procedure Test(J: integer; var F: Extended);
begin
  if J <= 1 then Exit;
  F := (F*1.2) + 100;
  Test(J-1, F); {因为形参J-1到下一级递归,其值就已经是J:=J-1了}
end;procedure TForm1.Button1Click(Sender: TObject);
var
  F: Extended;
begin
  F := 100;
  Test(3, F);
  Showmessage(FloattoStr(F)); {三级的分数}
end;//-----------------------------------------------{但还是不满意!再改写:}function Test(J: integer): Extended;
begin
  Result := 100;
  if J <= 1 then Exit;
  Result := Test(J-1) * 1.2 + 100;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
  Showmessage(FloattoStr(Test(3))); {三级的分数}
end;//-----------------------------------------------{哈哈再简一下:}function Test(J: integer): Extended;
begin
  Result := 100;
  if J > 1 then Result := Test(J-1) * 1.2 + 100;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
  Showmessage(FloattoStr(Test(3))); {三级的分数}
end;//------------------------------------------------------
{终于算是满意了。过路朋友看一下,还能再写得简练一些不?}零分。呵呵莫骂。

解决方案 »

  1.   


    ^_^  问题来了
    网友 zl_c 给把前面最终的Delphi算法翻译为VBScript,如下:
    <%
    Function g(j)
        If j > 0 Then g = g(j - 1) * 1.2 + 100
    End FunctionResponse.Write(g(2))
    %>
    直观可以看到,这个VBScript函数比前面我最终的Delphi函数更简练!
    将Delphi函数这样改写可以吗?
    function Test(J: integer): Extended;
    begin
      {Result := 0;}{注释掉这句试一试}
      if J > 0 then Test := Test(J-1) * 1.2 + 100;
    end;
    这样写不可以!为什么呢?我想了一下,Delphi首先给函数Result赋值是可以理解的,因为,在Test(J-1)值不确定的情况下,又谈何Test := Test(J-1)呢?
    而恰恰VBScript函数就可以。
    (在这里,还不应忽略一个语法规则:VBScript函数X赋值:
         X=值
             之后,函数就返回了)我想:或许这就是“编译”执行与“解释”执行的根本区别莫非,VBScript首先分析J的取值范围(假设实参J的值为4),得知 J的取值范围为 1 - 4
    然后,再从J = 1 to 4 这样把函数解释为一个循环?
    并且当g(0)时,函数为一个空的函数体,没有返回值赋值语句,默认返回值为 0 或 空字符串?
    想到这里,立即测试!这个猜想得到了证实:
    <%
    Function g(j)
        '
    End FunctionResponse.Write(Cstr(CInt(g(2))))   '返回值是0
    %>
    于是,自己有点认同自己前面的分析了。(关于VBScript解释程序的原理,有待有力的确切的证据和论证)接下来,Delphi是如何做的呢?直觉地去想象,很容易。但是为了证明,应该从分析反汇编码入手:再贴一下Delphi函数,免得翻页看起来烦恼:
    function Test(J: integer): Extended;
    begin
      Result := 0;
      if J > 0 then Test := Test(J-1) * 1.2 + 100;
    end;
    反汇编码是:0045217A 33C0    xor eax,eax
    0045217C 890424  mov [esp],eax
    0045217F 89442404    mov [esp+$04],eax
    00452183 6689442408   mov [esp+$08],ax
    00452188 85DB      test ebx,ebx
    0045218A 7E1A      jle +$1a
    0045218C 8BC3      mov eax,ebx
    0045218E 48        dec eax
    0045218F E8E0FFFFFF    call Test
    00452194 DB2DB0214500     fld tbyte ptr [$004521b0]
    0045219A DEC9             fmulp st(1)
    0045219C D805BC214500     fadd dword ptr [$004521bc]
    004521A2 DB3C24           fstp tbyte ptr [esp]
    004521A5 9B               wait 
    004521A6 DB2C24           fld tbyte ptr [esp]上面这段反汇编码,我有好几处助记词不理解。
    因此,今晚就到这里,希望能有感兴趣的朋友参与进来!
    另外,打算邀Web版的zl_c朋友和大牛Zswang前来助阵解惹!
      

  2.   

        函数必须有个返回值,如果没有Test:= 100这句,那么Test的返回值是不确定的。    记得以前看数据结构和算法的时候,书上似乎说过:对于递归函数来说,有两个重要条件,一个是初始值,一个是中止条件,这两个是不可缺少的。   在这个递归中: Test:= 100是初始值,J > 0是中止条件,如果没有了初始值,肯定是有问题的了。   这样写似乎更好理解一点:
    function Test(J: integer): Extended;
    begin
      if J > 0 then
        Test:= Test(J-1) * 1.2 + 100
      else
        Test:= 100;
    end;个人的一点看法。
      

  3.   

    "函数必须有个返回值,如果没有Test:= 100这句,那么Test的返回值是不确定的。"这句有点问题,是有些情况下不确定。
      

  4.   

    感谢楼上参与!问题的侧重点,在于:Delphi写的递归函数 与 VBScript写的递归函数 恰恰就是“函数值不确定”这个认识有不同之处
    请再理解一下3楼我的本意(3楼是一边想一边写的,可能表达得不好)想知道:为什么这样不同?
      

  5.   

    x *1.2 + IniTial = Y0i  = 1
    x = IniTialY1 =  Y0 + IniTial = IniTial * 2.2 = IniTial * (1.2^(1-1) + 1)i = 2Y2 = IniTial *2.2 * 1.2 + IniTial = IniTial * (1.2 +1) * 1.2 + IniTial  = (1.2^2 + 1.2^1 + 1.2 ^(1-1)) * IniTiali = 3 Y3 = (1.2 * 1.2 + 1.2 + 1) * IniTial * 1.2 + IniTial = (1.2^3 + 1.2^2 + 1.2^1 + 1.2^(1-1)) * IniTial按照上面的公司 就可以求出了
    并不需要递归吧TN = (E1.2^N) * IniTial (E表示求和)所以N的话就是
    TN/IniTial 加一个求和公式
      

  6.   

    求和公式有一个专门的方法求N值的整数 就是你的等级
    上面的推导好像有点错误
    就是N值的多了一位 LZ注意一下
      

  7.   

    谢谢楼上 huzhangyou问题已经与“用循环?”“用递归?”无关....
      

  8.   

    是与用循环还是递归无关的
    我的理解:在VBA中定义函数,默认的返回值是0,就相当于delphi中的reslut:=0这句,而且在VBA中的
    函数名就是result所以就省略了,你在上面的分析我觉得应该是正确的,如果能把VB中的函数反汇编一下比较就好了
    等其他人来看看吧,说的不对别笑:)
      

  9.   

    Partial Class _Default
        Inherits System.Web.UI.Page
        Function g(ByVal j)
            If j > 0 Then g = g(j - 1) * 1.2 + 100
        End Function    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Label1.Text = CStr(CInt(g(-1)))
        End Sub
    End Class返回值为0.
      

  10.   

    连日回复不多。已结贴。日后再说。追加100分。zxf_feng说得贴合问题,很到位;zl_c帮写的VBScript函数。所以这两位分高一点。其他参与都有分。