elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Guía rápida para descarga de herramientas gratuitas de seguridad y desinfección


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP)
| | | |-+  Programación Visual Basic (Moderadores: LeandroA, seba123neo)
| | | | |-+  [Src] IsInArray
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: [Src] IsInArray  (Leído 4,057 veces)
Psyke1
Wiki

Desconectado Desconectado

Mensajes: 1.089



Ver Perfil WWW
[Src] IsInArray
« en: 9 Mayo 2011, 14:24 pm »

Bueno, aquí os dejo esta sencilla función. :)
Su finalidad es devolver el Index de un Item que se encuentre en un array (acepta todo tipo de Arrays : String, Double, Long...), con la opción de devolver el primero que se encuentre en el array y con los parámetros lngStart y lngEnd podemos establecer límites en nuestra búsqueda.  :D
Para ordenarlo aconsejo usar esta maravillosa función que hizo mi amigo BlackZer0x :
http://goo.gl/RG4Bx

Código
  1. Option Explicit
  2. '======================================================================
  3. ' º Function  : IsInArray
  4. ' º Author    : Psyke1
  5. ' º Country   : Spain
  6. ' º Mail      : vbpsyke1@mixmail.com
  7. ' º Date      : 09/05/2011
  8. ' º Twitter   : http://twitter.com/#!/PsYkE1
  9. ' º Dedicated : BlackZer0x
  10. ' º Reference : http://goo.gl/RDQhK
  11. ' º Recommended Websites :
  12. '       http://foro.h-sec.org
  13. '       http://www.frogcheat.com.ar
  14. '       http://InfrAngeluX.Sytes.Net
  15. '======================================================================
  16. Public Static Function IsInArray&(varArr, _
  17.                                  varValue, _
  18.                                  Optional lngStart&, _
  19.                                  Optional lngEnd&, _
  20.                                  Optional bolFindFirst As Boolean, _
  21.                                  Optional bolIsSorted As Boolean)
  22. Dim lngLB&, lngUB&, Q&, C&
  23.    If (IsArray(varArr) = True) And (IsArray(varValue) = False) Then
  24.        lngLB = LBound(varArr)
  25.        lngUB = UBound(varArr)
  26.  
  27.        If Not IsMissing(lngStart) Then
  28.           If (lngStart > lngLB) And (lngStart < lngUB) Then lngLB = lngStart
  29.        End If
  30.        If Not IsMissing(lngEnd) Then
  31.           If (lngEnd > lngLB) And (lngEnd < lngUB) Then lngUB = lngEnd
  32.        End If
  33.  
  34.        If bolIsSorted Then
  35.            If varArr(lngLB) = varValue Then
  36.                IsInArray = lngLB
  37.                Exit Function
  38.            ElseIf varArr(lngUB) = varValue Then
  39.                If bolFindFirst Then
  40.                    Do While (varArr(lngUB) = varArr(lngUB - 1)) And (Q > lngLB)
  41.                        lngUB = lngUB - 1
  42.                    Loop
  43.                End If
  44.  
  45.                IsInArray = lngUB
  46.                Exit Function
  47.            End If
  48.  
  49.            If lngUB - lngLB < 2 Then GoTo NotFound
  50.            If (varArr(lngLB) > varValue) Or (varArr(lngUB) < varValue) Then GoTo NotFound
  51.  
  52.            C = 0
  53.            Do
  54.                Q = (lngUB + lngLB) \ 2
  55.                If C = Q Then GoTo NotFound
  56.  
  57.                If varArr(Q) > varValue Then
  58.                    lngUB = Q
  59.                ElseIf varArr(Q) < varValue Then
  60.                    lngLB = Q
  61.                    C = lngLB
  62.                Else
  63.                    If bolFindFirst Then
  64.                        Do While (varArr(Q) = varArr(Q - 1)) And (Q > lngLB)
  65.                            Q = Q - 1
  66.                        Loop
  67.                    End If
  68.  
  69.                    IsInArray = Q
  70.                    Exit Function
  71.                End If
  72.            Loop
  73.        Else
  74.            For Q = lngLB To lngUB
  75.                If varArr(Q) = varValue Then
  76.                    IsInArray = Q
  77.                    Exit Function
  78.                End If
  79.            Next Q
  80.  
  81.            GoTo NotFound
  82.        End If
  83.    End If
  84. Exit Function
  85.  
  86. NotFound:
  87.    IsInArray = -1
  88. End Function

Un ejemplo:
Código
  1. Option Explicit
  2.  
  3. Private Const strLine$ = "------------------------------"
  4.  
  5. Private Sub Form_Load()
  6. Dim L&(60), S(), Q&
  7.  
  8.    For Q = 0 To 60
  9.        L(Q) = Q * 2
  10.    Next Q
  11.  
  12.    Debug.Print strLine$, Time$, strLine$
  13.    Debug.Print IsInArray(L, 15)                '---> -1
  14.    Debug.Print IsInArray(L, 40)                '--->  20
  15.    Debug.Print IsInArray(L, 85)                '---> -1
  16.    Debug.Print IsInArray(L, 100)               '--->  50
  17.  
  18.    S = Array("abba", "acero", "karcrack", "sereno", "silencio", "tonto", "tonto", "tonto", "tonto", "zalme")
  19.  
  20.    Debug.Print strLine$
  21.    Debug.Print IsInArray(S, "zalme")           '--->  9
  22.    Debug.Print IsInArray(S, "zalme", , 4)      '---> -1
  23.    Debug.Print IsInArray(S, "mesa")            '---> -1
  24.    Debug.Print IsInArray(S, "besos")           '---> -1
  25.    Debug.Print IsInArray(S, "karcrack")        '--->  2
  26.    Debug.Print IsInArray(S, "karcrack", 3)     '---> -1
  27.    Debug.Print IsInArray(S, "tonto")           '--->  6
  28.    Debug.Print IsInArray(S, "tonto", , , True) '--->  5
  29. End Sub

Retorna:
Código:
------------------------------            18:59:54      ------------------------------
-1
 20
-1
 50
------------------------------
 9
-1
-1
-1
 2
-1
 6
 5



Si necesitamos especial velocidad y lo queremos para un tipo de variable en concreto, sólo hay que modificar un par de cosas. ;)
Aquí un ejemplo para buscar en un array Long, comparado con el código de BlackZer0x ( http://goo.gl/RDQhK ) :
Código:
Option Explicit
'// Compilado sin la comprobación de límites en los arrays xP

Private Sub Form_Load()
Dim L&(6000), Q&, t As New CTiming, y&
    
    If App.LogMode = 0 Then End
    
    For Q = 0 To 6000
        L(Q) = Q * 2
    Next Q
    
    Me.AutoRedraw = True
    
    t.Reset
    For Q = 1 To 1000
        IsInArray L, 15
        IsInArray L, 40
        IsInArray L, 2001
        IsInArray L, 5020
        IsInArray L, 12000
    Next Q
    Me.Print "IsInArray", , t.sElapsed
    
    t.Reset
    For Q = 1 To 1000
        ExitsInArrayNR 15, L, y
        ExitsInArrayNR 40, L, y
        ExitsInArrayNR 2001, L, y
        ExitsInArrayNR 5020, L, y
        ExitsInArrayNR 12000, L, y
    Next Q
    Me.Print "ExitsInArrayNR", t.sElapsed
End Sub

'// by Psyke1
Public Static Function IsInArray&(lngArr&(), lngValue&, Optional lngStart&, Optional lngEnd&, Optional bolFindFirst As Boolean)
Dim lngLB&, lngUB&, lngItem&, Q&, C&
    lngLB = LBound(lngArr)
    lngUB = UBound(lngArr)
    
    If Not IsMissing(lngStart) Then
       If (lngStart > lngLB) And (lngStart < lngUB) Then lngLB = lngStart
    End If
    If Not IsMissing(lngEnd) Then
       If (lngEnd > lngLB) And (lngEnd < lngUB) Then lngUB = lngEnd
    End If
    
    If lngArr(lngLB) = lngValue Then
        IsInArray = lngLB
        Exit Function
    ElseIf lngArr(lngUB) = lngValue Then
        If bolFindFirst Then
            Do While (lngArr(lngUB) = lngArr(lngUB - 1)) And (Q > lngLB)
                lngUB = lngUB - 1
            Loop
        End If
        IsInArray = lngUB
        Exit Function
    End If
    
    If lngUB - lngLB < 2 Then GoTo NotFound
    If (lngArr(lngLB) > lngValue) Or (lngArr(lngUB) < lngValue) Then GoTo NotFound
    
    C = 0
    Do
        Q = (lngUB + lngLB) \ 2
        If C = Q Then GoTo NotFound

        If lngArr(Q) > lngValue Then
            lngUB = Q
        ElseIf lngArr(Q) < lngValue Then
            lngLB = Q
            C = lngLB
        Else
            If bolFindFirst Then
                Do While (lngArr(Q) = lngArr(Q - 1)) And (Q > lngLB)
                    Q = Q - 1
                Loop
            End If
            IsInArray = Q
            Exit Function
        End If
    Loop
Exit Function

NotFound:
    IsInArray = -1
End Function

'// by BlackZer0x
Public Function ExitsInArrayNR(ByRef vValue As Long, ByRef vBuff() As Long, ByRef p As Long) As Boolean
Dim lng_lb                      As Long
Dim lng_Ub                      As Long
    lng_lb = LBound(vBuff&())
    lng_Ub = UBound(vBuff&())
    If Not vBuff&(lng_Ub) > vBuff&(lng_lb) Then
        Dim t                           As Long
        t = lng_Ub
        lng_Ub = lng_lb
        lng_lb = t
    End If
    Do Until ExitsInArrayNR
        Select Case vValue
            Case vBuff&(lng_lb&)
                p& = lng_lb&
                ExitsInArrayNR = True
            Case vBuff&(lng_Ub&)
                p& = lng_Ub&
                ExitsInArrayNR = True
            Case Else
                p = (lng_lb& + lng_Ub&) / 2
                If p <> lng_lb& And p& <> lng_Ub& Then
                    If vBuff&(p&) < vValue& Then
                        lng_lb = p
                    ElseIf vBuff&(p&) > vValue& Then
                        lng_Ub = p
                    ElseIf vBuff&(p&) = vValue& Then
                        ExitsInArrayNR = True
                    End If
                Else
                    Exit Do
                End If
        End Select
    Loop
End Function

Resultado:


DoEvents! :P


« Última modificación: 27 Mayo 2011, 20:27 pm por Psyke1 » En línea

BlackZeroX
Wiki

Desconectado Desconectado

Mensajes: 3.158


I'Love...!¡.


Ver Perfil WWW
Re: [Src] IsInArray
« Respuesta #1 en: 9 Mayo 2011, 19:18 pm »

.
grandiosa, aun que ¿Con listas enormes es igual de rápida?.

P.D.: Te tardaste siglos xP.

Dulces Lunas!¡.


En línea

The Dark Shadow is my passion.
Psyke1
Wiki

Desconectado Desconectado

Mensajes: 1.089



Ver Perfil WWW
Re: [Src] IsInArray
« Respuesta #2 en: 9 Mayo 2011, 19:31 pm »

.
grandiosa, aun que ¿Con listas enormes es igual de rápida?.

P.D.: Te tardaste siglos xP.

Dulces Lunas!¡.
Gracias :)
Sí, la velocidad es rápida incluso con arrays graandes.
Cambié el tamaño del Array referente al test de 6000 a 99999999 y me devuelve esto:


Ya sé que tardé un poco :silbar:, pero yo no rompo una promesa. :D

DoEvents! :P
« Última modificación: 9 Mayo 2011, 19:40 pm por Psyke1 » En línea

BlackZeroX
Wiki

Desconectado Desconectado

Mensajes: 3.158


I'Love...!¡.


Ver Perfil WWW
Re: [Src] IsInArray
« Respuesta #3 en: 9 Mayo 2011, 20:27 pm »

.
Gran trabajo xD, ahora a estudiar tu código por que es alucinante.

Dulces Lunas!¡.
En línea

The Dark Shadow is my passion.
Psyke1
Wiki

Desconectado Desconectado

Mensajes: 1.089



Ver Perfil WWW
Re: [Src] IsInArray
« Respuesta #4 en: 27 Mayo 2011, 20:35 pm »

.
Código mejorado y ahora con la posibilidad de escanear arrays desordenados.

DoEvents! :P
En línea

BlackZeroX
Wiki

Desconectado Desconectado

Mensajes: 3.158


I'Love...!¡.


Ver Perfil WWW
Re: [Src] IsInArray
« Respuesta #5 en: 2 Junio 2011, 01:25 am »

acabo de hacer el test de otra manera y resulta que ahora la mia es mas rapida que la tuya...

Código:

Private Sub Form_Load()
Dim L&(6000), Q&, t As New CTiming, y&
   
    If App.LogMode = 0 Then End
   
    For Q = 0 To 6000
        L(Q) = Q * 2
    Next Q
   
    Me.AutoRedraw = True
   
        t.Reset
    For Q = 1 To 1000
        ExitsInArrayNR 15, L, y
        ExitsInArrayNR 40, L, y
        ExitsInArrayNR 2001, L, y
        ExitsInArrayNR 5020, L, y
        ExitsInArrayNR 12000, L, y
    Next Q
    Me.Print "ExitsInArrayNR", t.sElapsed
   
    t.Reset
    For Q = 1 To 1000
        IsInArray L, 15
        IsInArray L, 40
        IsInArray L, 2001
        IsInArray L, 5020
        IsInArray L, 12000
    Next Q
    Me.Print "IsInArray", , t.sElapsed
   

End Sub


Dulces Lunas!¡.

« Última modificación: 2 Junio 2011, 01:31 am por BlackZeroX▓▓▒▒░░ » En línea

The Dark Shadow is my passion.
Psyke1
Wiki

Desconectado Desconectado

Mensajes: 1.089



Ver Perfil WWW
Re: [Src] IsInArray
« Respuesta #6 en: 2 Junio 2011, 01:44 am »

Supongo que me has dejado la función como Variant y las variables como Variant. :-\
Ya dije en el test que cambié un par de cosas en mi función.
¿Se puede saber que cambiaste en tu test? :huh:

DoEvents! :P
« Última modificación: 2 Junio 2011, 01:49 am por Psyke1 » En línea

BlackZeroX
Wiki

Desconectado Desconectado

Mensajes: 3.158


I'Love...!¡.


Ver Perfil WWW
Re: [Src] IsInArray
« Respuesta #7 en: 2 Junio 2011, 02:22 am »

.
Así queda mejor (Todo lo demás es solo una expansion...):

Revise nuevamente mi código y vi que no eran necesarias las comparaciones dentro del do-loop de los indices lbound y ubound o las sustituciones, ya que el que importa es el elemento medio.

Código Fuente de prueba (Test Aleatorio)



Código
  1.  
  2. Private Sub SwapVals(ByRef lVal1 As Long, ByRef lval2 As Long)
  3.    lval2 = lval2 Xor lVal1
  4.    lVal1 = lVal1 Xor lval2
  5.    lval2 = lval2 Xor lVal1
  6. End Sub
  7.  
  8. 'Return (Devuelve True si existe en el array)
  9. Public Function ExitsInArray(ByRef lFind As Long, ByRef avBuff() As Long, ByRef lpos As Long) As Boolean
  10. Dim llb             As Long
  11. Dim lub             As Long
  12. Dim lposa           As Long
  13.    'If Itsarrayini(VarPtrA(avBuff())) Then
  14.        llb = LBound(avBuff)
  15.        lub = UBound(avBuff)
  16.        If (avBuff(lub) < avBuff(llb)) Then
  17.            SwapVals lub, llb
  18.        End If
  19.        If ((avBuff(llb) <= lFind) And (lFind <= avBuff(lub))) Then
  20.            Select Case lFind
  21.                Case avBuff(lub)
  22.                    lpos = lub
  23.                    ExitsInArray = True
  24.                Case avBuff(llb)
  25.                    lpos = llb
  26.                    ExitsInArray = True
  27.                Case Else
  28.                    lposa = llb
  29.                    Do
  30.                        lpos = (llb + lub) \ 2
  31.                        If (lposa = lpos) Then
  32.                            Exit Do
  33.                        ElseIf (avBuff(lpos) > lFind) Then
  34.                            lub = lpos
  35.                        ElseIf (lFind > avBuff(lpos)) Then
  36.                            lposa = lpos
  37.                            llb = lpos
  38.                        ElseIf (avBuff(lpos) = lFind) Then
  39.                            ExitsInArray = True
  40.                            Exit Do
  41.                        End If
  42.                    Loop
  43.            End Select
  44.        End If
  45.    'End If
  46. End Function
  47.  
  48.  

Dulces Lunas!¡.
« Última modificación: 2 Junio 2011, 04:48 am por BlackZeroX▓▓▒▒░░ » En línea

The Dark Shadow is my passion.
raul338


Desconectado Desconectado

Mensajes: 2.633


La sonrisa es la mejor forma de afrontar las cosas


Ver Perfil WWW
Re: [Src] IsInArray
« Respuesta #8 en: 2 Junio 2011, 04:20 am »

Wow, impresionante. Muy buen trabajo los 2. Mirare los codigos y los usare en mis proyectos :) Sigan asi
En línea

BlackZeroX
Wiki

Desconectado Desconectado

Mensajes: 3.158


I'Love...!¡.


Ver Perfil WWW
Re: [Src] IsInArray
« Respuesta #9 en: 2 Junio 2011, 04:47 am »

.
Actualice el código de mi función.

Temibles Lunas!¡.
En línea

The Dark Shadow is my passion.
Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines