【发布时间】:2016-06-21 07:59:05
【问题描述】:
我知道,标题暗示了一个简单的答案。不过,请仔细阅读。在我的本科学习中,我有一门名为计算数学和数值分析的课程,在那里我学习了 C++。现在我昨天开始用 VBA 编码 - 只是为了好玩。我试图制作一个程序,可以计算多项式的根。经过一番来回,我设法写下了所有代码。我要做的最后一件事是在 Excel 中打印所有根。为此,我使用了一个名为“arroot”的数组。下面的子是我的主要:
Sub Main()
Dim fx As Double, Dim dffx As Double, Dim n As Integer
Dim x As Double, Dim root As Double, Dim arroot()
Dim a(15) As Long, Dim i As Integer
Sheet1.Cells.ClearContents
Call PolyCoef(n, a)
i = 0
Do
Call Table(n, a, x, fx, dffx)
Call NewRapHorner(n, a, fx, dffx, root)
Call HornerDivPol(n, a, root)
arroot(i) = root
i = i + 1
Loop While (Not n = 0)
Call Printroot(arroot)
End Sub
您可以看到,我将值保存在数组中,始终更新“i”以确保获得每个值。负责打印根的代码如下:
Private Sub Printroot(arroot())
Sheet1.Range("G3").Value = "Root"
Sheet1.Range("H3").Value = "x-value"
For i = 0 To UBound(arroot()) Step 1
Sheet1.Range("G" & 4 + i).Value = i + 1 & ". root"
Sheet1.Range("H" & 4 + i).Value = arroot(i)
Next
End Sub
我的问题: 执行此操作时,我遇到了问题 - 代码无法运行。当我将数组定义为 Dim arroot (15) 时,代码有效。唯一的问题是,我打印了太多的 'i + 1 & ".root"'s。我该如何解决这个问题?我希望我的数组与根数一样大。如果这样说有意义的话:我希望数组的括号以某种方式为空,因此它会自动调整。
提前谢谢你!
编辑:
根据要求,这是完整的代码:
Sub Main()
Dim fx As Double, Dim dffx As Double, Dim n As Integer
Dim x As Double, Dim root As Double, Dim arroot(15)
Dim a(15) As Long, Dim i As Integer
Sheet1.Cells.ClearContents
Call PolyCoef(n, a)
i = 0
Do
Call Table(n, a, x, fx, dffx)
Call NewRapHorner(n, a, fx, dffx, root)
Call HornerDivPol(n, a, root)
arroot(i) = root
i = i + 1
Loop While (Not n = 0)
Call Printroot(arroot)
End Sub
'Main Ends. Subs used in main are defined:
Private Sub PolyCoef(n As Integer, a() As Long)
Dim e As Integer
Sheet1.Range("A1").Value = "Enter n for polynomial"
Sheet1.Range("B1").Value = InputBox("Enter n", "Degree of the polynomial")
n = Sheet1.Range("B1").Value
e = n
Sheet1.Range("A3").Value = "Coefficients:"
Sheet1.Range("B3").Value = "Values:"
For i = 0 To n Step 1
Sheet1.Range("A" & i + 4).Value = i + 1 & ". coefficient, a" & e
Sheet1.Range("B" & i + 4).Value = InputBox("Enter coefficient", i + 1 & ". coefficient")
a(i) = Sheet1.Range("B" & i + 4).Value
e = e - 1
Next
End Sub
Private Sub Horner(n As Integer, a() As Long, x As Double, fx As Double, dffx As Double)
Dim e As Integer, Dim b(15), Dim c(15)
b(0) = a(0)
For i = 1 To n Step 1
b(i) = a(i) + x * b(i - 1)
Next
c(0) = b(0)
For i = 1 To n Step 1
c(i) = b(i) + x * c(i - 1)
Next
fx = b(n)
dffx = c(n - 1)
End Sub
Private Sub Table(n As Integer, a() As Long, x As Double, fx As Double, dffx As Double)
Dim xmax As Double, Dim dx As Double
x = InputBox("Enter first x-value", "Enter xmin")
xmax = InputBox("Enter last x-value", "Enter xmax")
dx = (xmax - x) / 19
Sheet1.Range("D3").Value = "x-value"
Sheet1.Range("E3").Value = "f(x)"
For i = 0 To 19 Step 1
Call Horner(n, a, x, fx, dffx)
Sheet1.Range("D" & 4 + i).Value = x
Sheet1.Range("E" & 4 + i).Value = fx
x = x + dx
Next
End Sub
Private Sub NewRapHorner(n As Integer, a() As Long, fx As Double, dffx As Double, root As Double)
Dim xnew As Double, Dim xold As Double, Dim eps As Double
Dim ite As Integer, Dim x0 As Double, Dim i As Integer
x0 = InputBox("Enter x-value close to root", "x-value")
eps = InputBox("Enter tolerance", "Tolerance")
ite = InputBox("Enter number of max iterations", "Max iterations")
i = 0
xnew = x0
root = 0
Do
xold = xnew
Call Horner(n, a, xnew, fx, dffx)
xnew = xnew - (fx / dffx)
i = i + 1
Loop While (Abs(xnew - xold) > eps And i < ite)
If i >= ite Then
MsgBox "Number of max iterations has been exeeded"
Else
root = xnew
End If
End Sub
Private Sub HornerDivPol(n As Integer, a() As Long, root As Double)
Dim b(15) As Long
b(0) = a(0)
For i = 1 To n Step 1
b(i) = a(i) + root * b(i - 1)
Next
For i = 1 To n Step 1
a(i) = b(i)
Next
n = n - 1
End Sub
Private Sub Printroot(arroot())
Sheet1.Range("G3").Value = "Root"
Sheet1.Range("H3").Value = "x-value"
For i = 0 To UBound(arroot()) Step 1
Sheet1.Range("G" & 4 + i).Value = i + 1 & ". root"
Sheet1.Range("H" & 4 + i).Value = arroot(i)
Next
End Sub
【问题讨论】:
-
你试过 ReDim 吗?
-
Printroot 的代码看起来不错,应该按原样打印数组中的所有元素。您唯一可能要考虑更改的是
For i = LBound(arroot) To UBound(arroot),原因如下:msdn.microsoft.com/en-us/library/aa266179(v=vs.60).aspx 因此,如果数组不包含您期望的内容,那么生成数组的代码就会出现问题(未显示在问题)。 -
@Ralph 正如文章所述,“因为默认基数是 0,所以永远不需要 Option Base 语句。”并且因为在调用 arroot(i) = root 之前 i 被设置为 0,所以下限将为零。
-
在 VB6/VBA 中,arr(15) 的数组定义是一个长度为 16 的数组,从 0 到 15,而不是像大多数语言那样创建一个长度为 15 的数组从 0 到 14。
-
添加...如果您声明一个带有空括号的数组,您需要在循环中的每次迭代中使用 ReDim Preserve 语句,以便分配您正在使用的数组。带空括号的数组不能包含任何内容。尝试将您的声明更改为 Dim arroot (14),这将为您提供 15 个编号为 0 到 14 的元素。