`
ihuashao
  • 浏览: 4720495 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

最接近π值的5位分数的算法

阅读更多

题目:

求一个分数,分子5位数(第1位不是0),分母也是5位数(第1位不是0),分子和分母这10个数正好由0到9这10个数字组成(不缺也不重复)。求最接近π值的那个分数

解法1(穷举法)

Sub getit()
Const num As Long = 3628800 ' 10!
Dim tt As Single, i As Long, j As Long, k As Long, temp1 As Long, temp2 As Long, pi As Single, diff As Single, out As String, temp As String
pi = 4 * Atn(1)
diff = 1
tt = Timer '开始计时
For i = 0 To num - 1
temp = 0
temp1 = i
For j = 2 To 10
temp2 = temp1 Mod j + 1
temp1 = temp1 \ j
temp = Left(temp, temp2 - 1) & j - 1 & Mid(temp, temp2)
Next
If temp Like "[3-9]####[1-3]####" Then
temp1 = Val(Left(temp, 5))
temp2 = Val(Right(temp, 5))
If Abs(temp1 / temp2 - pi) < diff Then diff = Abs(temp1 / temp2 - pi): out = temp1 & "/" & temp2
End If
Next
MsgBox out & "用时 " & Timer - tt & " 秒!"
End Sub

最后结果:=85910/27346

上述代码效率太低.

解法2(穷举法)

Sub Getit()
Dim pi As Single, diff As Single, i As Long, j As Long, temp As Long, s() As Byte, n As Byte, result As String, tt As Single
tt = Timer
pi = 4 * Atn(1)
diff = 1
For i = 31425 To 98765
ReDim s(9)
For j = 1 To 5
s(Mid(i, j, 1)) = 1
Next
If WorksheetFunction.Sum(s) = 5 Then
temp = Fix(i / pi)
For j = 1 To 5
s(Mid(temp, j, 1)) = 1
Next
If WorksheetFunction.Sum(s) = 10 Then
If Abs(i / temp - pi) < diff Then
diff = Abs(i / temp - pi)
result = i & "/" & temp
End If
End If
End If
Next
MsgBox result, vbInformation, "总计用时" & Timer - tt & "秒!"
End Sub

解法3(递归法)(yier_fang提供,http://club.excelhome.net/dispbbs.asp?boardid=2&replyid=978209&id=262029&page=1&skin=0&Star=1)

Dim lngFM As Long
Dim lngFZ As Long
Const PI = 3.1415926535
Dim dbl As Double
Dim kkk As Long
Dim intCK As Integer
Dim showW As Boolean
Dim Unums As String
Dim Lnums As String


Sub cnft()
Dim tm
tm = Timer
Application.ScreenUpdating = False
kkk = 0: lngFM = 0: lngFZ = 0
Unums = Cells(3, "H")
Lnums = Cells(3, "I")
dbl = 3.1415926535
intCK = Cells(3, "F").Value
showW = Cells(3, "E").Value
If showW Then UserForm1.Show
Call fs("", "")
Cells(1, 2).Value = lngFZ
Cells(2, 2).Value = lngFM
If lngFM = 0 Then
Cells(3, 2).Value = "无解"
Else
Cells(3, 2).Value = (lngFZ / lngFM)
End If
Cells(4, 2).Value = kkk
UserForm1.Hide
Application.ScreenUpdating = True
Cells(5, 2) = Format((Timer - tm), "0.0000") & "秒"
End Sub
Sub fs(ByRef FM As String, ByRef FZ As String)
kkk = kkk + 1
If showW Then
UserForm1.TextBox1.Text = "递归第..." & kkk & "...次"
DoEvents
End If
Dim i, j As Long
If Len(FM) = 0 Then
For i = 1 To 9
For j = 1 To 9
If i <> j Then
Call fs(CStr(i), CStr(j))
End If
Next j
Next i
ElseIf Len(FM) < 5 Then
If intCK = 1 Then
If ((FZ - 1) / (FM + 1)) > PI Then Exit Sub
If FM = 1 Then
If ((FZ + 1) / (FM)) < PI Then Exit Sub
Else
If ((FZ + 1) / (FM - 1)) < PI Then Exit Sub
End If
ElseIf intCK = 2 Then
'=======下面是手工的出口设置=========
If FZ / FM < Lnums Then Exit Sub
If FZ / FM > Unums Then Exit Sub
End If
For i = 0 To 9
If InStr(FM & FZ, i) = 0 Then
For j = 0 To 9
If InStr(FM & FZ & i, j) = 0 Then
Call fs(FM & i, FZ & j)
End If
Next j
End If
Next i

Else

If Abs((FZ / FM) - PI) < dbl Then
lngFM = FM
lngFZ = FZ
dbl = Abs((FZ / FM) - PI)

End If
End If
End Sub

解法4(递归法)(彭希仁提供:http://club.excelhome.net/dispbbs.asp?boardid=2&replyid=977506&id=262029&page=1&skin=0&Star=2)

Public pi
Public x
Public y
Public z
Public k As Long
Public st
Sub peng()
t = Timer
pi = 4 * Atn(1)
x = 10
st = 0
Call caii("", 0)
MsgBox (y & "/" & z & "=" & y / z & "递归" & st & "次,耗时" & Timer - t & "秒")
End Sub
Sub caii(a, i)
st = st + 1
m = 0
If i = 1 Then m = 3
For j = m To 9
If Not (a Like "*" & j & "*") Then
If i + 1 = 5 Then
k = a & j
If k > 31415 Then
kp = Round(k / pi)
If Abs(k / kp - pi) < x Then
h = k & kp
For n = 0 To 9
If Not (h Like "*" & n & "*") Then Exit For
Next n
If n = 10 Then
x = Abs(k / kp - pi)
y = k
z = kp
End If
End If
End If
Else
Call caii(a & j, i + 1)
End If
End If
Next j
End Sub

解法5(回溯法)

Sub getit(ByVal target As Single) 'target is a single number between 1~98765\10234
Dim n As Byte, m As Byte
Dim i As Integer, j As Integer, t As Integer, a(), fenmu As Long, fenzi As Long, max As Long, temp As String, result As Long
m = 4: n = 9
diff = 1
tt = Timer
max = int(98765/target)
ReDim a(m)
For i = 1 To m
a(i) = -1
Next
Do
a(t) = a(t) + 1
If a(t) > n Then
t = t - 1
Else
For i = 0 To t - 1
If a(t) = a(i) Then Exit For
Next
If i = t Then
If t = m Then
fenmu = Join(a, "")
fenzi = Round(fenmu * target)
temp = fenzi & "/" & fenmu
If Abs(fenzi / fenmu - target) < diff Then
For j = 0 To 9
If InStr(temp, j) = 0 Then Exit For
Next
If j = 10 Then diff = Abs(fenzi / fenmu - target): result = fenmu
End If
End If
If t < m Then t = t + 1: a(t) = -1
End If
End If
If fenmu > max Then Exit Do
Loop Until t = -1
Debug.Print "Target: " & target & vbCrLf & "Result: " & Round(result * target) & "/" & result & vbCrLf & "Error: " & diff & vbCrLf & "Lapsetime: " & Format(Timer - tt, "0.00000") & " seconds" & vbCrLf
End Sub

Sub macro1()
getit Sqr(2)
getit Sqr(3)
getit Exp(1)
getit 4 * Atn(1)
getit 5.6789
End Sub

返回:

Target: 1.414214
Result: 95103/67248
Error: 4.76071359769127E-07
Lapsetime: 0.20313 seconds

Target: 1.732051
Result: 93820/54167
Error: 1.03205265816492E-07
Lapsetime: 0.13867 seconds

Target: 2.718282
Result: 87159/32064
Error: 4.39718097983719E-07
Lapsetime: 0.06445 seconds

Target: 3.141593
Result: 85910/27346
Error: 1.79341409058684E-07
Lapsetime: 0.04492 seconds

Target: 5.6789
Result: 95082/16743
Error: 1.08244854411521E-05
Lapsetime: 0.01563 seconds

分享到:
评论

相关推荐

    圆周率的连分数逼近等算法和程序

    夏道行用连分数的方法证明,在所有分母不超过 8000 的分数当中,和 π 最接近的仍然是密率。如果有分数 q/p 比 355/113 更接近 π,则一定会有,p,q 为正整数,求解可得 p&gt;16586。可见密率的分母不大而精确度很高。 ...

    级数求PI的快速算法

    随着迭代次数的增加,计算结果会越来越接近真实的π值。 在实际编程中,我们还可以优化这个过程,比如使用并行计算加速级数求和,或者采用更高效的级数公式。例如,Bailey-Borwein-Plouffe(BBP)公式允许直接计算...

    2008FrFT.rar_2008frft_fractional_fractional fourier_分数阶_土耳其算法

    当α趋于π/2时,FrFT接近于传统的傅立叶变换,揭示信号的频率成分。 土耳其算法的基本步骤包括以下几个部分: 1. **分解**: 将分数阶傅立叶变换矩阵分解为一系列基本矩阵的乘积。 2. **快速算法**: 利用这些基本...

    matlab开发-使用侧面数字pi值的扩展方法

    5. **π值估算**:根据比例乘以4即可得到π的近似值,因为球面积占正方体面积的比例是π/4。 `license.txt`文件则包含了脚本的许可信息,可能涉及代码的使用、修改和分发的条款。 在实际应用中,为了提高精度,...

    test_C++_C++_数学_π_

    这种方法是通过将一个正方形内接于一个圆,然后不断分割成更小的正多边形,当边数趋于无穷大时,多边形的周长接近圆的周长,从而逼近π的值。具体来说,可以使用著名的马赫林级数或者莱布尼茨公式等无限级数来计算π...

    一种新的LFM信号参数估计算法

    算法的核心概念首先从LFM信号的数学模型开始,通常表示为s(t) = exp{j(2πf0t + πk0t^2)},其中f0为初始频率,k0是调制斜率,也就是调频率。该算法的独特之处在于引入了二次相位函数(QP function)的概念,通过这...

    遗传算法的C 代码实现教程.doc

    在本教程中,遗传算法被应用于求解函数 `y=x*sin(10*π*x)+2.0` 的最大值。这个函数是一个非线性函数,其最大值可能不那么容易通过传统数学方法找到。 遗传算法的基本步骤如下: 1. **初始化种群**:首先,随机...

    2020年高中数学 1.3《中国古代数学中的算法案例》教案 新人教B版必修3.doc

    2. 探索“割圆术”的算法,这是一种无限逼近圆周率的方法,通过不断倍增圆内接正多边形的边数来逐步接近圆的周长与直径的比例,即圆周率π。 过程与方法目标强调: 1. 将抽象的数学问题转化为具体步骤化的过程,...

    c代码-c语言计算π

    程序会累加这些项,随着项数增加,结果会越来越接近π/4,乘以4即可得到π的近似值。 `README.txt`文件通常包含项目的说明、使用指南或作者的注释。在这个上下文中,它可能解释了所用算法的原理,如何编译和运行...

    C 代码 近似伽马函数的对数.rar

    这些测试可能会覆盖各种输入值,包括小数、大数以及接近整数的值,确保算法在各种边界条件和极端情况下的表现。 总的来说,这个C代码库提供了一个实用工具,可以用于在C程序中高效地计算伽马函数的对数,这对于需要...

    河南省唐河县第一高级中学2012-2013学年高一数学下学期第一次月考试题

    6. **算法与程序**:根据算法框图,执行流程是将t初始化为1,然后从2到5循环,每次乘以i的值,最后输出t的值。执行完后,t的值为1*2*3*4*5=120,对应选项D。 7. **频率分布直方图**:中间小长方形面积占其他10个的1...

    mypiplottergregory.​m:为 pi 绘制经典 Gregory-Leibnitz 级数的任何 n 项的 pi 值。-matlab开发

    这个级数随着项数的增加逐渐接近π的真实值,但永远不会完全等于π,因为π是无理数。MATLAB脚本“mypiplottergregory.m”将帮助我们可视化这一过程,展示随着项数增加,级数和π之间的差距是如何减小的。 在MATLAB...

    matlab 常用函数--

    7. **`round(x)`**:四舍五入到最接近的整数。 8. **`fix(x)`**:将`x`四舍五入到零的方向,即负数朝正方向,正数不变。 9. **`floor(x)`**:向下取整,即向负无穷方向取整数。 10. **`ceil(x)`**:向上取整,即...

    c代码-圆周率计算代码

    这个公式表明,你可以无限地加减分数序列,每两个项的绝对值都会逐渐减小,从而逐渐接近π/4。因此,程序可能会包含一个循环,不断地累加或累减这些分数,然后乘以4来得到π的近似值。 在`README.txt`文件中,可能...

    课程Matlab函数整理.pdf

    - `round(x)`:四舍五入`x`到最接近的整数。 - `fix(x)`:舍去小数部分,返回最接近的整数。 - `floor(x)`:向下取整,返回小于等于`x`的最大整数。 - `ceil(x)`:向上取整,返回大于等于`x`的最小整数。 - `...

    六年级上册期末试题数学题【新课标人教版】精选.doc

    - 抛硬币正反面出现次数比最可能接近1:1,因为硬币正反面出现的概率应该是相等的。 - 正方形内最大圆的面积是正方形面积的π/4,约等于78.5%。 6. **分数、百分比及运算**: - 质量、时间和比率的转换。 - 黄豆...

    estimating-pi:通过计算估算Pi

    每增加一项,级数的和会更接近π/4。因此,我们可以编写一个循环,不断累加这些项,然后乘以4来得到π的近似值。Python代码示例如下: ```python def gregory_leibniz(n_terms): pi_approx = 0 for i in range(1,...

    计算机二级C上机题库.pdf

    1. 在计算公式 `(1 + 1/t)^t` 直到 `t` 接近无穷大时,形参 `e` 的值通常为一个很小的正数,例如 `1e-3`,这时可以利用泰勒级数或者牛顿迭代法求解,函数返回值为 `0.551690`,表示在 `t` 趋向于无穷大时,该公式的...

    2021—2022年人教版六年级数学上册期中考试题及答案(1).pdf

    3. 通过扇形占比计算,360° - 45° * 2 = 270°,占了3/4,所以30天中有3/4 * 30 = 22.5天是雨天,选择最接近的选项,即21天。 4. 服装店的盈亏计算,100元赚20%是120元,亏本20%是80元,所以总亏损10元,是亏本。 ...

Global site tag (gtag.js) - Google Analytics