2016-03-07 5 views
2

Я понимаю, что название предлагает простой ответ. Пожалуйста, прочитайте это, хотя. В моих студенческих исследованиях у меня есть курс, называемый вычислительной математикой и численным анализом, где я изучаю C++. Теперь я начал кодирование в VBA вчера - просто для удовольствия. Я попытался создать программу, которая может вычислять корни многочлена. После некоторых взад и вперед мне удалось написать весь код. Последнее, что я хочу сделать, это распечатать все корни в Excel. Для этого я использую массив под названием «arroot». Суб ниже мой Main:Определить количество элементов в массиве

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 

Вы можете видеть, что я экономлю значение в массиве, всегда обновление «я», чтобы гарантировать, что я получаю все значения. Код отвечает за печать корень ниже:

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. Как я могу решить эту проблему? Я хочу, чтобы мой массив был таким же большим, как количество корней. Если это имеет смысл сделать так: я хочу, чтобы скобки для массива как-то были пустыми, поэтому он автоматически настраивается.

Спасибо заранее!

EDIT:

В соответствии с просьбой, вот полный код:

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 
+1

Вы пробовали ReDim? –

+0

Код для вашего Printroot кажется прекрасным и должен печатать все элементы в вашем массиве, как есть. Единственное, что вы, возможно, захотите рассмотреть, это: «Для i = LBound (arroot) для UBound (arroot)» из-за следующего: https://msdn.microsoft.com/en-us/library/aa266179(v=vs .60) .aspx Итак, если массив не содержит того, что вы ожидаете, возникает проблема с кодом, генерирующим массив (который не указан в вопросе). – Ralph

+0

@Ralph Как говорится в статье: «Поскольку базой по умолчанию является 0, оператор Option Base никогда не требуется». и поскольку i устанавливается в 0 до того, как arroot (i) = root, нижняя граница будет равна нулю. –

ответ

0

Массивы не очень эффективны для того, что вы хотите сделать в VBA. Я хотел бы предложить, чтобы создать коллекцию, как:

Public yourArray As New Collection 

Добавление элемента с тем же типом он будет динамически регулировать его размер. Ниже я покажу, как добавить элементы в коллекцию.

Public yourArray As New Collection 

Sub trieal() 

i = 10 
Do Until i = 1 
    yourArray.Add i 
    i = i - 1 

Loop 

For Each e In yourArray 
    Debug.Print (e) 
Next 
End Sub 

Это решает вашу проблему зацикливания элементов вашего «массива».

+0

Коллекции начинаются с 1, массивы начинаются с нуля. Коллекции предназначены для хранения объектов, массивы предназначены для хранения примитивных типов данных. Коллекции не так эффективны, как массивы. Именование коллекции yourArray сбивает с толку, потому что коллекции и массивы представляют собой два принципиально разных контейнера. –

+0

Я согласен с тем, что вы сказали. У меня была аналогичная проблема с использованием массивов, как это было указано в вопросе, и я подумал, так как это сработало для меня, это могло бы работать и на кого-то другого. – Pydan

+0

Тогда вы просто не зацикливались на массиве и не следили за своим счетчиком точно. Массивы для примитивных данных - всегда. –

Смежные вопросы