google面试题之一,(不为蹭分只求探讨者进)
前日,从网上看到一个google面试题之一,即做之,因而带出些问题望各位大侠不吝赐教。
题目如下:
有这样一个函数,对于任意整数n,都能返回写出0到n之间出现“1”的个数。例如,f(13)=6。请注意f(1)=1,那么下一个能实现f(n)=n的最大数字是什么?
本人写了两个程序求解,-用递归、一用非递归程序,
解法1 递归程序:
它包含1公共模块(模块内容如下)。
**************************************************************
Public Const BitNum = 8
Public Function OneOfNum(ByVal Number As Long, ByVal BitNum As Long) As Long
Dim i As Integer
If Number < (10 ^ BitNum) Then
For i = BitNum To 0 Step -1
Dim j As Integer
j = Number \ (10 ^ i)
If 1 = j Then
OneOfNum = OneOfNum + 1
End If
Number = Number - j * (10 ^ i)
Next
End If
End Function
Public Function FindOne(ByVal num As Long) As Long
If num = 1 Then
FindOne = 1
Else
FindOne = OneOfNum(num, BitNum) + FindOne(num - 1)
End If
End Function
**********************************************************
窗体程序如下(窗体上有两文本框text1和text2)
**********************************************************
Dim sumofone As Long
Private Sub Command1_Click()
Dim k As Long
For k = Val(Text1.Text) To 1
Dim L As Long
L = FindOne(Val(Text1.Text))
If k = L Then
Text2.Text = Str(k)
Exit For
End If
Next
End Sub
*********************************************
当text1中输入超过某个值(不大,如5000)时,它会报溢出,故求解不能进行下去。
因而带出问题是:
vb的递归最大支持多少层?如何做一个满足自己的堆栈?(足够大,能满足本题)
_____________________________________________________________________________
解法2 非递归程序 窗体程序如下(窗体上有两文本框text1和text2,text1输入最大范围,text2输出结果):
*****************************************************************************************
Dim MaxVal As Long
Dim BitLong As Integer
Dim a() As Integer
Dim Find As Boolean
Private Sub Command1_Click()
Find = False
Dim Maxlong As Integer
Maxlong = 10
Dim Count As Long
MaxVal = Val(Text1.Text)
For Count = 2 To MaxVal
Dim i As Integer
BitLong = 0
For i = Maxlong To 1 Step -1
If Not ((Count \ 10 ^ (i - 1)) = 0) Then
BitLong = i '找出数的位数长度。
Exit For
End If
Next i
ReDim a(1 To BitLong) As Integer
Dim Temp As Long
Temp = Count
For i = BitLong To 1 Step -1 '从高位到低位分离出该数中的各个位上的数字至a()数组中
Dim bit As Integer
bit = Temp \ 10 ^ (i - 1)
a(BitLong - i + 1) = bit
Temp = Temp - bit * 10 ^ (i - 1)
Next
Dim SumofOne As Long
Dim Num As Long
Num = Count
SumofOne = 0
SumofOne = SumofOne + Num \ 10 '找出个位上1的个数
If (Num Mod 10) >= 1 Then
SumofOne = SumofOne + 1
End If
Dim BitNo As Integer 'BitNo 指明是第几位
For BitNo = 2 To BitLong - 1
Dim k As Long
k = Num \ 10 ^ BitNo
Dim preNum As Long
preNum = k * 10 ^ (BitNo - 1)
If a(BitNo) = 0 Then
SumofOne = SumofOne + preNum
ElseIf a(BitNo) = 1 Then
SumofOne = SumofOne + Val(Right(Num, BitNo)) + 1 '当有一位数字为1时,它后面的几位数字组成的数要加1
ElseIf a(BitNo) > 1 Then
SumofOne = SumofOne + (k + 1) * 10 ^ (BitNo - 1)
End If
Next
If BitLong = 1 Then '1位数时不加1
SumofOne = SumofOne + Val(Right(Num, BitLong - 1))
ElseIf a(1) = 1 Then '最高位的数为1时它后面的几位数字组成的数要加1
SumofOne = SumofOne + Val(Right(Num, BitLong - 1)) + 1
Else
SumofOne = SumofOne + 10 ^ (BitLong - 1)
End If
'MsgBox (Str(SumofOne))
If Num = SumofOne Then
Text2.Text = Str(Num)
Find = True
Exit For
End If
Next Count
If Find = False Then Text2.Text = "NO Find"
End Sub
******************************************************************************************
解出google问题结果为199981,这两种解法对吗?如若不对请指出。
如果正确,还有更简单的算法吗?(从时间复杂度及空间复杂度考虑)
在此谢谢各位高手、大侠了!!!!