Jump to content

How to access a global array of unknown size


Angel
 Share

Recommended Posts

Hi,

I am making a small AutoIt example program which calculates the Fibonnacci numbers. To make it faster I am using 2 global arrays to keep track of the numbers that have already been calculated.

My problem comes when I use Global to declare these arrats within the fibonacci function. When I do so, if I check the size (Ubound) of the array, I get a size of 0, even if the arrays have been initialized to a size of 2:

MsgBox(0,"Debug", Fibonacci(10))

Global $vFiboValues[2] = [1, 1]
Global $vFiboIndexes[2] = [0, 1]

; Function to calculate the $n-th Fibonacci number
; First check if the number has been calculated before. Otherwise use a recursion to calculate it,
; then add it to the global list of fibonacci numbers which is used to avoid recalculation. This "list"
; is made out of 2 global arrays, one holding the numbers that have been calculated, the other 
; holding the indexes of those numbers
Func Fibonacci($n)
  Local $newFibo = FindInFibonacciArray($n)
  If $newFibo = False Then
    ; The fibonacci number is unknown, calculate it!
    $newFibo = Fibonacci($n-2) + Fibonacci($n-1)
    ; Add the $newFibo to the fibonacci memory
    ReDim $vFiboValues[UBound($vFiboValues)+1]
    ReDim $vFiboIndexes[UBound($vFiboIndexes)+1]
    $vFiboValues[UBound($vFiboValues)] = $newFibo
    $vFiboIndexes[UBound($vFiboIndexes)] = $n
  EndIf
  Return $newFibo
EndFunc


; This function checks if the $index-th fibonacci number has been previously calculated
; If it has, it simply returns its value. If not, it returns False
Func FindInFibonacciArray($index)
  Global $vFiboIndexes, $vFiboValues
  For $n = 0 To UBound($vFiboIndexes)-1
    MsgBox(0,"Debug",$n & " " & $vFiboIndexes[$n])
    If $index = $vFiboIndexes[$n] Then
      Return $vFiboValues[$n]
    EndIf
  Next
  ; If we get this far, return False to indicate that the $index was not found
  ; Note how we can return a bool or an integer, as the basic AutoIt variable is a VARIANT
  Return False
EndFunc

I know that I can calculate the fibonacci numbers with a For loop. That is not the point. I just want to show that autoIt can use recursion and just show some other features of the language (such as working with arrays, If/Else constructs, function declarations, etc).

So, is there a way to declare a function as global to access it from within a function? I had never tried to do this before (which may say something about how useful my example will be! ;-))

Thanks,

Angel

Link to comment
Share on other sites

  • Moderators

I didn't really run it... The below stood out though:

Func Fibonacci($n)
  Local $newFibo = FindInFibonacciArray($n)
  If $newFibo = False Then
    ; The fibonacci number is unknown, calculate it!
    $newFibo = Fibonacci($n-2) + Fibonacci($n-1)
    ; Add the $newFibo to the fibonacci memory
    ReDim $vFiboValues[UBound($vFiboValues)+1]
    ReDim $vFiboIndexes[UBound($vFiboIndexes)+1]
    $vFiboValues[UBound($vFiboValues)] = $newFibo;You just Redimmed it... and your making the ubound value the $newFibo... you never get to that value... maybe try $vFiboValues[UBound($vFiboValues) - 1] , same for the one below this example
    $vFiboIndexes[UBound($vFiboIndexes)] = $n
  EndIf
  Return $newFibo
EndFunc

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I didn't really run it... The below stood out though:

Func Fibonacci($n)
  Local $newFibo = FindInFibonacciArray($n)
  If $newFibo = False Then
    ; The fibonacci number is unknown, calculate it!
    $newFibo = Fibonacci($n-2) + Fibonacci($n-1)
    ; Add the $newFibo to the fibonacci memory
    ReDim $vFiboValues[UBound($vFiboValues)+1]
    ReDim $vFiboIndexes[UBound($vFiboIndexes)+1]
    $vFiboValues[UBound($vFiboValues)] = $newFibo;You just Redimmed it... and your making the ubound value the $newFibo... you never get to that value... maybe try $vFiboValues[UBound($vFiboValues) - 1] , same for the one below this example
    $vFiboIndexes[UBound($vFiboIndexes)] = $n
  EndIf
  Return $newFibo
EndFunc
Nice catch. Actually I didn't see that because there is a problem even before that. When FindInFibonacciArray is called, when the Global arrays are declared, their sizes are 0!

So how can I make reference to a global array without knowing its size?

Angel

Link to comment
Share on other sites

You are calling the function before the globals are even declared. :P

Global $vFiboValues[2] = [1, 1]
Global $vFiboIndexes[2] = [0, 1]

MsgBox(0,"Debug", Fibonacci(10)) ;; moved after globals


; Function to calculate the $n-th Fibonacci number
; First check if the number has been calculated before. Otherwise use a recursion to calculate it,
; then add it to the global list of fibonacci numbers which is used to avoid recalculation. This "list"
; is made out of 2 global arrays, one holding the numbers that have been calculated, the other
; holding the indexes of those numbers
Func Fibonacci($n)
  Local $newFibo = FindInFibonacciArray($n)
  If $newFibo = False Then
    ; The fibonacci number is unknown, calculate it!
    $newFibo = Fibonacci($n-2) + Fibonacci($n-1)
    ; Add the $newFibo to the fibonacci memory
    ReDim $vFiboValues[UBound($vFiboValues)+1]
    ReDim $vFiboIndexes[UBound($vFiboIndexes)+1]
    $vFiboValues[UBound($vFiboValues)-1] = $newFibo 
    $vFiboIndexes[UBound($vFiboIndexes)-1] = $n
  EndIf
  Return $newFibo
EndFunc


; This function checks if the $index-th fibonacci number has been previously calculated
; If it has, it simply returns its value. If not, it returns False
Func FindInFibonacciArray($index)
  For $n = 0 To UBound($vFiboIndexes)-1
    MsgBox(0,"Debug",$n & " " & $vFiboIndexes[$n])
    If $index = $vFiboIndexes[$n] Then
      Return $vFiboValues[$n]
    EndIf
  Next
  ; If we get this far, return False to indicate that the $index was not found
  ; Note how we can return a bool or an integer, as the basic AutoIt variable is a VARIANT
  Return False
EndFunc

Changes:

1. MsgBox() moved

2. Ubound() to Ubound()-1 (as smoke said)

3. Removed Globals in FindInFibonacciArray()

Edited by Grineyfase
Link to comment
Share on other sites

You are calling the function before the globals are even declared. :P

Wow! That is a silly mistake! I was getting an error saying that the globals where being used before being declared and instead of looking at the obvious thing, I thought that I had to declare the globals inside the function as well, and then I did not understand what syntax should I use for that (which should have made me think back and realize my original mistake)...

Thanks a lot for your help! :-)

Angel

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...