Jump to content
Sign in to follow this  
UPSman2

is this the fastest

Recommended Posts

UPSman2

is this the fastest way to find all the occurrences of a string within another string?

cause if it's not would someone please provide me with an example of a faster way? or if I'm approaching this the wrong way it'd be nice if someone corrected me.

#Include <String.au3>
#Include <Array.au3>
Dim $Found[10001]
$dir = FileOpenDialog ( "Open file", @ScriptDir, "Text files (*.txt)")
$SearchString =InputBox ( "Search", "Search for all occurences of this string:") 
$String = FileRead ( $dir)
$a = TimerInit()
FindAllOccurrences()
MsgBox(0,"","Time tooken: " & TimerDiff($a))
MsgBox(0,"",$Found[0] & " found")

Func FindAllOccurrences()
    $Found_Posistion = StringInStr ( $String,$SearchString,1,1,1)
    $String_Length = StringLen($SearchString)
    If $Found_Posistion = 0 Then
    Else
        $trigger = 1
        Do
            $Found[0] = $trigger
            $Found[$trigger] = $Found_Posistion
            $Found_Posistion = StringInStr ( $String,$SearchString,1,1,$Found_Posistion + $String_Length)
            $trigger = $trigger + 1
        Until $Found_Posistion = 0
    EndIf
EndFunc

Edit: i want to have the string position returned of each substring found in the mainstring

Edited by UPSman2

Share this post


Link to post
Share on other sites
Airwolf

Use StringRegExp(); it returns an array based on a query (so you could find the number of occurences of any pattern in a string).


Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt

Share this post


Link to post
Share on other sites
UPSman2

well ive never used regexp, but i guess ill give it a shot

btw could you give me an example of how to use it?

Share this post


Link to post
Share on other sites
Airwolf

The queries can get extremely complicated; it really depends on what you're searching for. This example would find all occurences of the word "autoit". Check the help file for much more info on the StringRegExp() function.

$result = StringRegExp($string, "(autoit)+", 3)
MsgBox(0,"","Matches Found: " & UBound($result))
Edited by Airwolf

Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt

Share this post


Link to post
Share on other sites
UPSman2

ok i think i might have something with my setup but when i run this script it returns 0

$String = "123hi123hi123hi"
$result = StringRegExp($string, "(hi)+", 1)
MsgBox(0,"","Matches Found: " & (UBound($result) - 1))

Share this post


Link to post
Share on other sites
Airwolf

ok i think i might have something with my setup but when i run this script it returns 0

$String = "123hi123hi123hi"
$result = StringRegExp($string, "(hi)+", 1)
MsgBox(0,"","Matches Found: " & (UBound($result) - 1))
Sorry, I goofed. :) Check the edited version - tested working - in my last post.

Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt

Share this post


Link to post
Share on other sites
UPSman2

ok maybe i'm just having a slow moment but, yes it does return how many occur, but how would i find where in the string they are found

p.s. btw thx for help :)

Edit: ok i guess i didn't make myself fully clear, but i want to have the string position returned of each substring found in the mainstring

Edited by UPSman2

Share this post


Link to post
Share on other sites
Airwolf

$string = "autoit autoit autoit autoit"
$i = 1
While 1
    $search = StringInStr($string, "autoit", 0, $i)
    If $search <> 0 Then
        MsgBox(0,"","Position of match " & $i & " is: " & $search)
        $i += 1
    Else
        $i -= 1
        ExitLoop
    EndIf
WEnd

MsgBox(0,"","Matches Found: " & $i)


Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt

Share this post


Link to post
Share on other sites
UPSman2

i think its more efficient if you just start your search from the last found value instead of changing the occurrence value.

why? because your searching through data you've already searched

proof?: your way (240 KB file): 1st: 3411.49, 2nd: 3237.78

other way (240 KB file): 1st: 260.68, 2nd: 225.62

but i think i can improve my speed with your loop :)

Share this post


Link to post
Share on other sites
Airwolf

i think its more efficient if you just start your search from the last found value instead of changing the occurrence value.

why? because your searching through data you've already searched

proof?: your way (240 KB file): 1st: 3411.49, 2nd: 3237.78

other way (240 KB file): 1st: 260.68, 2nd: 225.62

but i think i can improve my speed with your loop :)

Hmm... I'm not visualizing this. Can you post the faster way? I'm just curious as to what you are referring to. Are you talking about shrinking the string each time?

Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt

Share this post


Link to post
Share on other sites
UPSman2

StringInStr ( "string", "substring" [, casesense [, occurrence [, start [, count]]]] )

basically shrinking it (depends on how autoit built in does it though)

and the other way is my org

Edited by UPSman2

Share this post


Link to post
Share on other sites
Airwolf

StringInStr ( "string", "substring" [, casesense [, occurrence [, start [, count]]]] )

basically shrinking it (depends on how autoit built in does it though)

and the other way is my org

Wow, I just noticed my desktop is running v3.2.8.1... That's why I thought I was going nuts. :) The start and count parameters were recently added! I guess I upgraded my laptop and forgot about my desktop.

Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt

Share this post


Link to post
Share on other sites
UPSman2

Wow, I just noticed my desktop is running v3.2.8.1... That's why I thought I was going nuts. :) The start and count parameters were recently added! I guess I upgraded my laptop and forgot about my desktop.

lol

anyway what I'm wondering is how to edge every little piece of speed out of that function b/c I'll be using it for searching through large chunks of data and it gets kina slow when searching like 1mb files

Share this post


Link to post
Share on other sites
Airwolf

lol

anyway what I'm wondering is how to edge every little piece of speed out of that function b/c I'll be using it for searching through large chunks of data and it gets kina slow when searching like 1mb files

This trims the string each time and still keeps track of the current position in the original string... it should be fairly efficient:

$string = "autoit autoit autoit autoit"
$find = "autoit"
$i = 1
$trimmedtotal = 0
While 1
    $search = StringInStr($string, $find, 0, 1)
    If $search <> 0 Then
        ; calculate position of current find by adding the trimmed total to the found position
        $position = $trimmedtotal + $search
        MsgBox(0,"","Position of match " & $i & " is: " & $position)
        ; trim string to right after string found
        $string = StringTrimLeft($string, ($search + StringLen($find)))
        MsgBox(0,"","String length is now: " & StringLen($string))
        ; add length of $find to found position then add total trimmed so far to get new trimmed total
        $trimmedtotal = $trimmedtotal + $search + StringLen($find)
        ;increase count of found string
        $i += 1
    Else
        $i -= 1
        ExitLoop
    EndIf
WEnd

MsgBox(0,"","Matches Found: " & $i)

Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt

Share this post


Link to post
Share on other sites
SkinnyWhiteGuy

Use StringReplace, just don't assign it's return to a variable, and @extended will be the number of replacements it made (i.e. The number of items it found).

Share this post


Link to post
Share on other sites
Airwolf

Use StringReplace, just don't assign it's return to a variable, and @extended will be the number of replacements it made (i.e. The number of items it found).

He needs the position of each item found.

Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt

Share this post


Link to post
Share on other sites
SkinnyWhiteGuy

Ah, that'll teach me to just post solutions without reading the entire problem. :)

Share this post


Link to post
Share on other sites
Airwolf

I made a UDF out of the last example I posted. This is the most efficient method I can come up with, and it's fairly easy to use. The result returned is 0 if the search string is not found, otherwise an array is returned. The array index of 0 is the total number of items found and each subsequent index is the position in the string of each find.

; EXAMPLE
$result = _StringInStr_Pos("autoit autoit autoit autoit", "autoit")
$message = ""

For $x = 1 To (UBound($result) - 1)
    $message = $message & @CR & $result[$x]
Next

MsgBox(0,"",$result[0] & " results found at positions:" & @CR & $message)

; FUNCTION
Func _StringInStr_Pos($string, $find)
    Dim $array[1]
    $i = 1
    $trimmedtotal = 0
    While 1
        $search = StringInStr($string, $find, 0, 1)
        If $search <> 0 Then
            $position = $trimmedtotal + $search
            $string = StringTrimLeft($string, ($search + StringLen($find)))
            $trimmedtotal = $trimmedtotal + $search + StringLen($find)
            $array[0] = $i
            ReDim $array[$i + 1]
            $array[$i] = $position
            $i += 1
        Else
            If $i = 1 Then
                Return 0
            EndIf
            Return $array
        EndIf
    WEnd
EndFunc
Edited by Airwolf

Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt

Share this post


Link to post
Share on other sites
UPSman2

your way (3.24mb file with 102 matches): 3998.6, 4026.9, 4030.74

original way (3.24mb file with 102 matches): 1657.64, 1697.85, 1558.83

the built in "start" option in stringinstr is faster then trimming it yourself and keeping track of it via variables

but i just learnt about redim :)

Edited by UPSman2

Share this post


Link to post
Share on other sites
Airwolf

but i just learnt about redim :)

Well, then at least it wasn't a complete waste of time. :)

Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt

Share this post


Link to post
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
Sign in to follow this  

×