dany Posted December 8, 2012 Posted December 8, 2012 Only $ and arn't 'allowed': #include <Array.au3> $sString = 'why hello there' $sDelim = '^.*+|/?-[]{}()' $sReplaced = StringRegExpReplace($sString, ' ', $sDelim) MsgBox(0, '...', $sReplaced) _ArrayDisplay(StringSplit($sReplaced, $sDelim, 1), ':)') [center]Spiderskank Spiderskank[/center]GetOpt Parse command line options UDF | AU3Text Program internationalization UDF | Identicon visual hash UDF
AZJIO Posted December 8, 2012 Posted December 8, 2012 dany $sDelim &= Chr(Random(1, 31, 1)) & Chr(Random(93, 255, 1)) My other projects or all
czardas Posted December 8, 2012 Posted December 8, 2012 (edited) After the above discussion, I decided to combine my approach with some of AZIJO's ideas. This is an improvement on my previous code. A very nearly universal delimiter testing function: expandcollapse popup#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w- 7 #include <Array.au3> #include <String.au3> Example() Func Example() Local $sStr = "" ; Monster string for testing For $i = 1 To 10000000 $sStr &= Chr(Random(1, 255, 1)) Next MsgBox(0, "First 300 out of 10000000 Chracters", StringLeft($sStr, 300)) Local $sDelim = _GetDelim($sStr) If Not @error Then ConsoleWrite("<---| " & $sDelim & " |--->" & @LF) Else ConsoleWrite("<---| FAILED |--->" & @LF) EndIf EndFunc Func _GetDelim($sTest) If Not IsString($sTest) Then Return SetError(1, 0, "") ; Invalid Input String. Local $aAscII[31], $sDelim ; Using Control Characters only. ; First try one character For $i = 1 To 31 $sDelim = Chr($i) If Not StringInStr($sTest, $sDelim, 1) Then Return $sDelim Else $aAscII[$i - 1] = $sDelim ; Needed for the next stage. EndIf Next ; That failed - so we try two characters. Local $aDoubleChar = _ArrayCombinations($aAscII, 2, "") For $i = 1 To $aDoubleChar[0] $sDelim = $aDoubleChar[$i] If Not StringInStr($sTest, $sDelim, 1) Then Return $sDelim Next ; That failed - so we try the reverse patterns. ReDim $aDoubleChar[931] $aDoubleChar[0] = 930 For $i = 466 To $aDoubleChar[0] $sDelim = _StringReverse($aDoubleChar[$i -465]) If Not StringInStr($sTest, $sDelim, 1) Then Return $sDelim Else $aDoubleChar[$i] = $sDelim ; Needed for the next stage. EndIf Next ; That failed - so we try three characters. For $i = 1 To $aDoubleChar[0] For $j = 0 To 30 $sDelim = $aDoubleChar[$i] & $aAscII[$j] If Not StringInStr($sTest, $sDelim, 1) Then Return $sDelim Next Next ; That failed - so we try four characters. For $i = 1 To $aDoubleChar[0] For $j = 1 To $aDoubleChar[0] $sDelim = $aDoubleChar[$i] & $aDoubleChar[$j] If Not StringInStr($sTest, $sDelim, 1) Then Return $sDelim Next Next ; That failed - so we try five characters. For $i = 1 To $aDoubleChar[0] For $j = 1 To $aDoubleChar[0] For $k = 0 To 30 $sDelim = $aDoubleChar[$i] & $aDoubleChar[$j] & $aAscII[$k] If Not StringInStr($sTest, $sDelim, 1) Then Return $sDelim Next Next Next ; Here we could also try six characters followed by seven etc. Return SetError (2, 0, "") ; No suitable delimiter found. EndFunc Edited December 8, 2012 by czardas operator64 ArrayWorkshop
dany Posted December 8, 2012 Posted December 8, 2012 Thanks for the sample code czardas I ran these tests: Global $sStr = '' For $i = 1 To 10000000 $sStr &= Chr(Random(1, 255, 1)) ; Monster string for testing. Next MsgBox(0, 'Info', 'Test String Created') Global $sDelim = _GetDelim($sStr) MsgBox(0, 'Delim', Binary($sDelim)) ; Show control characters. MsgBox(0, 'StringInStr?', StringInStr($sStr, $sDelim)) Func _GetDelim($sTest) Local $sDelim = Chr(1) While StringInStr($sTest, $sDelim) $sDelim &= Chr(Random(1, 31, 1)) If 32 = StringLen($sDelim) Then Return SetError(3, 0, 0) WEnd Return $sDelim EndFunc Response time is relatively slow due to the monster test string. _GetDelim itself takes 1-3 iterations to find a unique delimiter. I'm happy with that, the delimiter is 2-3 characters on average. A lookup on a 10 million character string takes some time, I didn't measure exactly but roughly 1-2 seconds before the delimiter pops up. I reduced that by checking only the first 100000 characters of the string, but that's too small a sample, I got collisions outside the test range. Same for a 1 million test sample, it performs better but only marginally, you get collisions now and then. I took out the Random and took your sequential approach: Func _GetDelim($sTest) Local $sDelim ;$sTest = StringLeft($sTest, 1000000) ; Reduced test sample. For $i = 1 To 31 $sDelim &= Chr($i) If Not StringInStr($sTest, $sDelim) Then ExitLoop If 32 = StringLen($sDelim) Then Return SetError(3, 0, 0) Next Return $sDelim EndFunc I haven't kept exact stats but on gut feeling I'd say it performs only marginally better because there's one less function call. When testing a smaller sample range (1 million) it gives less collisions, but it still isn't foolproof. So as far as methods go, I'd say the sequential approach is marginally faster but not much. I simplified the function because I feel matters shouldn't be made overly complicated. Any unique sequence of characters will do, it's just a throw-away value anyway so the simplest approach will suffice. I don't see a way to reduce overall speed for very large monster strings though. So this would be my proposed version, corrections and all: ; #FUNCTION# =================================================================== ; Name...........: _StringRegExpSplit ; Description ...: Split a string according to a regular exp[b][/b]ression. ; Syntax.........: _StringRegExpSplit($sString, $sPattern) ; Parameters ....: $sString - String: String to split. ; $sPattern - String: Regular exp[b][/b]ression to split on. ; Return values .: Success - Array: Array of substrings, the total is in $array[0]. ; Failure - Array: The count is 1 ($array[0]) and the full string is returned ($array[1]) and sets @error: ; |1 Delimiter not found. ; |2 Bad RegExp pattern, @extended contains the offset of the error in the pattern. ; |3 No suitable placeholder delimiter could be constructed. ; Author ........: dany ; Modified ......: czardas, AZJIO ; Remarks .......: ; Related .......: ; ============================================================================== Func _StringRegExpSplit($sString, $sPattern) Local $sSplit, $sDelim, $aError[2] = [1, $sString] For $i = 1 To 31 $sDelim &= Chr($i) If Not StringInStr($sString, $sDelim) Then ExitLoop If 32 = StringLen($sDelim) Then Return SetError(3, 0, $aError) WEnd $sSplit = StringRegExpReplace($sString, $sPattern, $sDelim) If @error Then Return SetError(2, @extended, $aError) If @extended = 0 Then Return SetError(1, 0, $aError) If Not IsBinary($sString) Then Return StringSplit($sSplit, $sDelim, 1) $sSplit = StringSplit($sSplit, $sDelim, 1) For $i = 2 To $sSplit[0] $sSplit[$i] = '0x' & $sSplit[$i] Next Return $sSplit EndFunc [center]Spiderskank Spiderskank[/center]GetOpt Parse command line options UDF | AU3Text Program internationalization UDF | Identicon visual hash UDF
tcurran Posted January 2, 2013 Posted January 2, 2013 ... For $i = 1 To 31 $sDelim &= Chr($i) If Not StringInStr($sString, $sDelim) Then ExitLoop If 32 = StringLen($sDelim) Then Return SetError(3, 0, $aError) WEnd ... @dany You made a small typo converting the _StringRegExpSplit delimiter-finder from random to sequential: That should be a For...Next loop, not a For...WEnd loop. I discovered the glitch because I used your snippet while writing my own improving on StringRegExp. When I'm finished (shortly) it will return the position of a match instead of just True or False (in other words, it will make StringRegExp behave more-or-less like StringInStr).
tcurran Posted January 3, 2013 Posted January 3, 2013 (edited) Here, as promised, is my snippet that makes StringRegExp (mode 0) behave like StringInStr, in the sense that the return value is the position of the regular expression pattern within the test string, rather than just 1 (match) or 0 (no match). @Extended returns the number of matches within the test string.Like StringInStr, you can optionally pass which occurrence or which character to start at within the test string. I didn't include a 'case' option since that's built in to regular expressions, and I didn't include a count option because I couldn't figure out what the default would be (infinity? eleventy-billion?).UPDATE: 'If StringLen($sDelim) = 32 Then...' repositioned and rewritten per suggestions below from AZJIO and guinness.expandcollapse popup; #FUNCTION# ===================================================================== ; Name ..........: _StringRegExpPos ; Description ...: Returns the position of a regular expression pattern within ; a string, similar to StringInStr ; AutoIt Version : V3.3.8.1 ; Syntax ........: _StringRegExpPos($sTest, $sPattern, $iOcc, $iStart) ; Parameter(s): .: $sTest - The string to evaluate ; $sPattern - The regular expression to compare. See ; StringRegExp for pattern definition characters. ; $iOcc - Optional: Which occurrence of the regex to find ; within the test string (Default = 1) ; $iStart - Optional: The starting position of the search ; (Default = 1) ; Return Value ..: Success - Returns the position of the regex pattern ; Failure - Returns 0 if regex pattern not found ; @ERROR - 0: Normal operation @Extended = number of matches ; 1: Invalid "start" or "occurrence" parameter ; 2: Pattern invalid. @Extended = offset of error. ; Author(s) .....: Tim Curran (tim at timcurran dot com) ; Date ..........: 9 January 2013 ; Link ..........: ; Related .......: StringInStr, StringRegExpReplace, _StringRegExpSplit ; Example .......: Yes ; ================================================================================ Func _StringRegExpPos($sTest, $sPattern, $iOcc = 1, $iStart = 1) Local $sDelim, $iHits If $iStart > StringLen($sTest) Then Return SetError(1) ;Delimiter creation snippet by dany from his version of _StringRegExpSplit For $i = 1 To 31 $sDelim &= Chr($i) If Not StringInStr($sTest, $sDelim) Then ExitLoop Next If StringLen($sDelim) = 32 Then Return SetError(3, 0, 0) Local $aResults = StringRegExpReplace(StringMid($sTest, $iStart + (StringLen($sDelim) * ($iOcc - 1))), "(" & $sPattern & ")", $sDelim & "$1") If @error = 2 Then Return SetError(2, @extended, 0) $iHits = @extended If $iHits = 0 Then Return 0 If $iOcc > $iHits Then Return SetError(1) Local $iPos = StringInStr($aResults, $sDelim, 0, $iOcc) SetExtended($iHits) Return $iStart - 1 + $iPos EndFunc ;<== _StringRegExpPosAnd here's some demo code:; 111111111122 2222222233333333334444 ; 123456789012345678901 2345678901234567890123 $demo = "Will this blast last " & Chr(1) & "or is it fading fast?" $pos = _StringRegExpPos($demo, ".{2}ast", 3, 1) ConsoleWrite("@error: " & @error & @TAB & "@extended: " & @extended & @CRLF) ;output="@error: 0 @extended: 3" ConsoleWrite("$pos: " & $pos & @CRLF) ;output="$pos: 38" Edited January 9, 2013 by tcurran
guinness Posted January 7, 2013 Posted January 7, 2013 I kind of agree about the looks, but you're technically wrong. The documentation says the == operator should only be used on string comparisons (which this isn't) that are case sensitive (ditto).It was an error on my part. Fixed the example above. UDF List: _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018
czardas Posted January 9, 2013 Posted January 9, 2013 (edited) When making multiple string replacements within a single string, longer strings should generally be replaced first to avoid erroneously replacing substrings within subsequent search patterns. For this we need to sort the search patterns by length (in descending order). The syntax and error codes are more or less identical to _ArraySort() except only the first four parameters are used. The modified array is returned ByRef. This function will not work with multidimensional arrays. #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w- 7 ;Sort an array's elements by strting length ;Author czardas #include-once #include <Array.au3> Func _ArraySortByLen(ByRef $aArray, $iDescending =0, $iStart =0, $iEnd =0) If Not IsArray($aArray) Or UBound($aArray, 0) > 1 Then Return SetError(1, 0, 0) ; Not a 1D array If Not IsInt($iStart) Or Not IsInt($iEnd) Then Return SetError(5, 0, 0) ; Parameters need to be integers. Local $iBound = UBound($aArray) Local $aElementLen[$iBound][2] $iBound -=1 For $i = 0 To $iBound $aElementLen[$i][0] = StringLen($aArray[$i]) ; Get the length of the element $aElementLen[$i][1] = $aArray[$i] ; The element to sort Next _ArraySort($aElementLen, $iDescending, $iStart, $iEnd) If @error Then Return SetError(@error, 0, 0) ; See _ArraySort() for error codes 2 to 4. For $i = 0 To $iBound $aArray[$i] = $aElementLen[$i][1] Next Return 1 EndFunc ;==> _ArraySortByLen() I though this might be quite useful, so I posted it here. Edited January 9, 2013 by czardas operator64 ArrayWorkshop
Chimaera Posted January 9, 2013 Author Posted January 9, 2013 (edited) It is purely to create the box with the username etc and the jump title for the wiki since the geshi was updated they are probably in need of tweaking but i havent checked since i first made them, you only run the code lower down === _IsInternetConnected === ; produces the jump title {{Snippet Header=== ; produces the box | AuthorURL=35302-guinness=== ; produces the link for user in forums | AuthorName=guinness }} ConsoleWrite("Internet Is Connected" & " = " & _IsInternetConnected() & @CRLF) ; ( Returns "True" Or "False" ) Func _IsInternetConnected() Local $aReturn = DllCall('connect.dll', 'long', 'IsInternetConnected') If @error Then Return SetError(1, 0, False) EndIf Return $aReturn[0] = 0 EndFunc ;==>_IsInternetConnected Edited January 9, 2013 by Chimaera If Ive just helped you ... miracles do happen. Chimaera CopyRobo() * Hidden Admin Account Enabler * Software Location From Registry * Find Display Resolution * _ChangeServices()
FireFox Posted February 9, 2013 Posted February 9, 2013 (edited) This is a "cleaned version" of mouse enter/move/leave window messages based on those posts :expandcollapse popup#include <WindowsConstants.au3> #include <GUIConstantsEx.au3> Global $_iCount = 0 ;not important, just for the example #region GUI Global $hGUI = GUICreate("MyGUI") #region MouseTracking Global $_blIsTracking = False Global Const $TME_LEAVE = 0x2 Global Const $HOVER_DEFAULT = 0xFFFFFFFF Global Const $tagTRACKMOUSEEVENT = "struct; dword Size; dword Flags; hwnd WndTrack; dword HoverTime; endstruct" Global $tTrackMouseEvent = DllStructCreate($tagTRACKMOUSEEVENT) DllStructSetData($tTrackMouseEvent, "Size", DllStructGetSize($tTrackMouseEvent)) DllStructSetData($tTrackMouseEvent, "Flags", $TME_LEAVE) DllStructSetData($tTrackMouseEvent, "WndTrack", $hGUI) DllStructSetData($tTrackMouseEvent, "HoverTime", $HOVER_DEFAULT) Global $pTrackMouseEvent = DllStructGetPtr($tTrackMouseEvent) #endregion MouseTracking GUIRegisterMsg($WM_MOUSEMOVE, "WM_MOUSEMOVE") GUIRegisterMsg($WM_MOUSELEAVE, "WM_MOUSELEAVE") GUISetState(@SW_SHOW, $hGUI) #endregion GUI While GUIGetMsg() <> $GUI_EVENT_CLOSE Sleep(10) WEnd GUIDelete($hGUI) Func WM_MOUSELEAVE($hWnd, $Msg, $wParam, $lParam) $_blIsTracking = False ConsoleWrite("->MOUSE_LEAVE" & @CRLF) Return $GUI_RUNDEFMSG EndFunc ;==>WM_MOUSELEAVE Func WM_MOUSEMOVE($hWnd, $Msg, $wParam, $lParam) If Not $_blIsTracking Then $_blIsTracking = True DllCall("User32.dll", "int", "TrackMouseEvent", "ptr", $pTrackMouseEvent) ConsoleWrite("+>MOUSE_ENTER " & $_iCount & @CRLF) $_iCount += 1 EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_MOUSEMOVE Edited February 22, 2013 by FireFox
FireFox Posted February 22, 2013 Posted February 22, 2013 (edited) Some of you started to talk about the Static keyword, so I made an advanced hotkey example using it with the native HotKeySet function. Edit: Fixed HotKey not released when the GUI is minimized. Edit2: Fixed double HotKetSet on restore. expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <Misc.au3> ;It's not a good idea to set the NOREPEAT flag to True and the NOOVERLAPCALL to False if the function called ;is blocking (e.g: "while" or any dialogbox) as your function will be called until the end of all instances queued. ;these are the flags as in Yashied's HotKey UDF Global $blOptHotKey_NOREPEAT = True, $blOptHotKey_NOOVERLAPCALL = True ;the flag NOBLOCKHOTKEY is the purpose of this example so there is no option for it ;when the GUI is minimized, this last does not receive the "unactivated" WM, we need to catch the syscommand WM. Global $blGUIMinimized = False _Main() Func _Main() Local $hGUI = GUICreate("GUI") GUIRegisterMsg($WM_ACTIVATE, "WM_ACTIVATE") GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND") GUISetState() While GUIGetMsg() <> $GUI_EVENT_CLOSE Sleep(10) WEnd GUIDelete($hGUI) EndFunc ;==>_Main ;call this function when the GUI is un/activated Func WM_ACTIVATE($hWnd, $iMsg, $iwParam, $ilParam) If $iwParam And Not $blGUIMinimized Then ;hWnd activated _HotKey_Enable() Else _Hotkey_Disable() EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_ACTIVATE ;call this function when the GUI receives a system command Func WM_SYSCOMMAND($hWnd, $iMsg, $wParam, $lParam) Local Const $SC_MINIMIZE = 0xF020, $SC_RESTORE = 0xF120 Switch BitAND($wParam, 0xFFF0) Case $SC_MINIMIZE _Hotkey_Disable() $blGUIMinimized = True Case $SC_RESTORE $blGUIMinimized = False EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_SYSCOMMAND ;sets the hotkey Func _HotKey_Enable() HotKeySet("{F1}", "_Help") EndFunc ;==>_HotKey_Enable ;releases the hotkey Func _Hotkey_Disable() HotKeySet("{F1}") EndFunc ;==>_Hotkey_Disable Func _Help() If $blOptHotKey_NOOVERLAPCALL Then Local Static $blFuncFinished = True ;defined for the first call If Not $blFuncFinished Then Return ;the function is already called but not complete $blFuncFinished = False EndIf If $blOptHotKey_NOREPEAT Then While _IsPressed("70") ;F1 key Sleep(10) WEnd EndIf ConsoleWrite("What can I do for you? Time is now: " & @HOUR & ":" & @MIN & ":" & @SEC & ":" & @MSEC & @CRLF) ;demonstrates the NOOVERLAPCALL flag Local $iTimer = TimerInit() While TimerDiff($iTimer) < 2000 Sleep(10) WEnd If $blOptHotKey_NOOVERLAPCALL Then ;sets the function as completed for the next call $blFuncFinished = True EndIf EndFunc ;==>_Help Edited March 19, 2013 by FireFox hotkeySet 1
UEZ Posted February 27, 2013 Posted February 27, 2013 Here a function to find a solution using + - * / as operants. Example: 11 5 3 = 9 -> 11-5+3=9 expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <Array.au3> Global $aOp[4] = ["+","-","*","/"] Global $sTest = "11,,5,,3,=,9" Global Const $hGUI = GUICreate("Math Resolver beta build 2013-02-27 by UEZ", 532, 138, -1, -1) GUISetFont(12, 400, 0, "Arial") GUISetBkColor(0xC0DCC0) Global Const $iOperants = GUICtrlCreateLabel("Operants", 10, 12, 68, 22) Global Const $iInputOperants = GUICtrlCreateInput("+ - * /", 80, 8, 52, 26, BitOR($GUI_SS_DEFAULT_INPUT,$ES_READONLY)) Global Const $iTerm = GUICtrlCreateLabel("Term", 40, 52, 40, 22) Global Const $iInputTerm = GUICtrlCreateInput($sTest, 80, 48, 361, 26) Global Const $iResult = GUICtrlCreateLabel("Result", 30, 100, 47, 22) Global Const $iInputResult = GUICtrlCreateInput("", 80, 96, 361, 26, BitOR($GUI_SS_DEFAULT_INPUT,$ES_READONLY)) Global Const $iResolve = GUICtrlCreateButton("Resolve", 448, 96, 75, 25) GUICtrlSetFont(-1, 11, 400, 0, "Arial") ControlFocus($hGUI, "", $iResolve) GUISetState(@SW_SHOW) Global $aMath Do Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUIDelete() Exit Case $iResolve If Not StringRegExp(GUICtrlRead($iInputTerm), "(\d+,,\d+),=,\d+", 0) Then MsgBox(16 + 262144, "ERROR", "Please check the term and try again!", 30) ContinueLoop EndIf $aMath = StringSplit(GUICtrlRead($iInputTerm) , ",", 2) GUICtrlSetData($iInputResult, BruteForce_Solver($aMath, $aOp)) EndSwitch Until False Func BruteForce_Solver($aMath, $aOp, $bCheckAll = False) Local $aInit = $aMath ;save original array Local $sString = StringStripWS(_ArrayToString($aMath, ","), 8) Local Const $iPosEqual = StringInStr($sString, "=") ;calculate = position If $iPosEqual < 6 Then Return SetError(1, 0, $aInit) Local Const $iCount = StringReplace($sString, ",,", ",,") If Not @extended Then Return SetError(2, 0, "Term Error") Local $aTmp[@extended] ;create an array with count of placeholders for operants Local Const $iMax = UBound($aOp) ^ (UBound($aTmp)) ;calculate all posible combinations Local $i, $j = 0, $k = 0, $l, $sAll, $sCompacted Do For $i = 0 To UBound($aTmp) - 1 ;fill combination of operants index to the array $aTmp[$i] = Mod(Int($j / (2^$k)), UBound($aOp)) $k += 2 Next $l = 0 $i = 0 Do $aMath[$l + 1] = $aOp[$aTmp[$l / 2]] ;insert operants according to operants index array $l += 2 $i += 1 Until $i = UBound($aTmp) $sString = _ArrayToString($aMath, "") If Execute($sString) Then ;check equation $sCompacted = StringStripWS($sString, 8) If $bCheckAll Then $sAll &= $sCompacted & ", " ;save all solutions Else Return $sCompacted ;if equation is true than we found at least 1 solution EndIf EndIf $k = 0 $j += 1 Until $j = $iMax If $bCheckAll And $sAll <> "" Then Return StringTrimRight($sAll, 2) Return SetError(3, 0, "Not resolvable") ;otherwise term not solvable EndFunc It uses the brute force method to find a solution if available. I hope it's bug free. Br, UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
ValeryVal Posted March 15, 2013 Posted March 15, 2013 I like this entertainment. This is your script with Reset button to create the new task without force. Type any correct expression into Result field and press Reset. expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <Array.au3> ;Add by ValeryVal ; - Reset button Global $aOp[4] = ["+","-","*","/"] Global $sTest = "11,,5,,3,=,9" Global Const $hGUI = GUICreate("Math Resolver beta build 2013-02-27 by UEZ", 532, 138, -1, -1) GUISetFont(12, 400, 0, "Arial") GUISetBkColor(0xC0DCC0) Global $iOperants = GUICtrlCreateLabel("Operants", 10, 12, 100, 22) Global $iInputOperants = GUICtrlCreateInput("+ - * /", 110, 8, 330, 26, BitOR($GUI_SS_DEFAULT_INPUT,$ES_READONLY)) Global $iTerm = GUICtrlCreateLabel("Term", 10, 52, 100, 22) Global $iInputTerm = GUICtrlCreateInput($sTest, 110, 48, 330, 26) Global $iReSet = GUICtrlCreateButton("Reset", 448, 48, 75, 25) GUICtrlSetTip($iReSet, 'Create new task from Result content!') Global $iResult = GUICtrlCreateLabel("Result", 10, 100, 100, 22) Global $iInputResult = GUICtrlCreateInput("", 110, 96, 330, 26) Global $iResolve = GUICtrlCreateButton("Resolve", 448, 96, 75, 25) GUICtrlSetTip($iInputResult, 'You can type any simple expression here!') GUICtrlSetFont(-1, 11, 400, 0, "Arial") ControlFocus($hGUI, "", $iResolve) GUISetState(@SW_SHOW) Global $aMath Do Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUIDelete() Exit Case $iResolve If Not StringRegExp(GUICtrlRead($iInputTerm), "(\d+,,\d+),=,\d+", 0) Then MsgBox(16 + 262144, "ERROR", "Please check the term and try again!", 30) ContinueLoop EndIf $aMath = StringSplit(GUICtrlRead($iInputTerm) , ",", 2) GUICtrlSetData($iInputResult, BruteForce_Solver($aMath, $aOp)) Case $iReSet $sTest = StringStripWS(GUICtrlRead($iInputResult), 8) if $sTest then $iPos = StringInStr($sTest,"=") if $iPos then $sTest = StringTrimRight($sTest,StringLen($sTest)-StringInStr($sTest,"=")+1) endif $sTest = $sTest & ",=," & Execute($sTest) for $i = 0 to 3 $sTest = StringReplace($sTest,$aOp[$i],",,") next GUICtrlSetData($iInputTerm,$sTest) GUICtrlSetData($iInputResult,"") endif EndSwitch Until False Func BruteForce_Solver($aMath, $aOp, $bCheckAll = False) Local $aInit = $aMath ;save original array Local $sString = StringStripWS(_ArrayToString($aMath, ","), 8) Local Const $iPosEqual = StringInStr($sString, "=") ;calculate = position If $iPosEqual < 6 Then Return SetError(1, 0, $aInit) Local Const $iCount = StringReplace($sString, ",,", ",,") If Not @extended Then Return SetError(2, 0, "Term Error") Local $aTmp[@extended] ;create an array with count of placeholders for operants Local Const $iMax = UBound($aOp) ^ (UBound($aTmp)) ;calculate all posible combinations Local $i, $j = 0, $k = 0, $l, $sAll, $sCompacted Do For $i = 0 To UBound($aTmp) - 1 ;fill combination of operants index to the array $aTmp[$i] = Mod(Int($j / (2^$k)), UBound($aOp)) $k += 2 Next $l = 0 $i = 0 Do $aMath[$l + 1] = $aOp[$aTmp[$l / 2]] ;insert operants according to operants index array $l += 2 $i += 1 Until $i = UBound($aTmp) $sString = _ArrayToString($aMath, "") If Execute($sString) Then ;check equation $sCompacted = StringStripWS($sString, 8) If $bCheckAll Then $sAll &= $sCompacted & ", " ;save all solutions Else Return $sCompacted ;if equation is true than we found at least 1 solution EndIf EndIf $k = 0 $j += 1 Until $j = $iMax If $bCheckAll And $sAll <> "" Then Return StringTrimRight($sAll, 2) Return SetError(3, 0, "Not resolvable") ;otherwise term not solvable EndFunc Enjoy! The point of world view
FireFox Posted March 16, 2013 Posted March 16, 2013 (edited) Create a transparent edit control from this example.expandcollapse popup#include <WindowsConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> ;required for: $GUI_EVENT_CLOSE #include <Constants.au3> #include <WinAPIEx.au3> ;url: http://www.autoitscript.com/forum/topic/98712-winapiex-udf/ #include <Debug.au3> ;required for: _Assert #region Global Vars Global Const $WM_APP_REDRAWWINDOW = $WM_APP + 1 Global $_hBrushBack = 0, $_hBitmapBack = 0, $_pfnDefEditProc = 0 Global Const $_sBkBitmapFullPath = @ScriptDir & "\autoit_wall_grey_small.bmp" Local $hNew_WndProc = DllCallbackRegister("_MyEdit_Proc", "int", "hwnd;uint;wparam;lparam") Global $_pNew_WndProc = DllCallbackGetPtr($hNew_WndProc) #endregion Global Vars #region GUI Local Const $hGUI = GUICreate("Demo Transparent Edit Control", 358, 208, -1, -1, BitOR($DS_MODALFRAME, $WS_POPUP, $WS_CAPTION, $WS_SYSMENU)) Global Const $tbMyEdit = GUICtrlCreateEdit("", 15, 16, 240, 176, BitOR($ES_MULTILINE, $ES_AUTOHSCROLL, $ES_WANTRETURN, $WS_VSCROLL, $WS_HSCROLL)) ;~ GUIRegisterMsg($WM_INITDIALOG, "WM_INITDIALOG") WM_INITDIALOG($hGUI) GUIRegisterMsg($WM_CTLCOLOREDIT, "WM_CTLCOLOREDIT") GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND") GUIRegisterMsg($WM_DESTROY, "WM_DESTROY") GUISetState(@SW_SHOW, $hGUI) #endregion GUI #region Loop While GUIGetMsg() <> $GUI_EVENT_CLOSE Sleep(10) WEnd GUIDelete($hGUI) #endregion Loop #region WM Func WM_INITDIALOG($hWnd) ;bool $_hBitmapBack = _WinAPI_LoadImage(0, $_sBkBitmapFullPath, $IMAGE_BITMAP, 0, 0, $LR_LOADFROMFILE) _Assert("$_hBitmapBack <> 0") $_hBrushBack = _WinAPI_CreatePatternBrush($_hBitmapBack) _Assert("$_hBrushBack <> 0") ; Subclass edit control Local $hWndEdit = _WinAPI_GetDlgItem($hWnd, $tbMyEdit) ;~ _Assert("$hWndEdit <> 0") ;commented, reason: bug $_pfnDefEditProc = _WinAPI_SetWindowLong($hWndEdit, $GWL_WNDPROC, $_pNew_WndProc) Return False EndFunc ;==>WM_INITDIALOG Func WM_CTLCOLOREDIT($hWnd, $uMsg, $wParam, $lParam) ;HBRUSH Local $hBrush = 0 Switch $uMsg Case $WM_CTLCOLOREDIT _WinAPI_SetTextColor($wParam, _WinAPI_SwitchColor(0x800000)) _WinAPI_SetBkMode($wParam, $TRANSPARENT) $hBrush = $_hBrushBack EndSwitch Return $hBrush EndFunc ;==>WM_CTLCOLOREDIT Func WM_ERASEBKGND($hWnd, $uMsg, $wParam, $lParam) ;bool Local $tRect = _WinAPI_GetClientRect($hWnd) Local $hOldBrush = _WinAPI_SelectObject($wParam, $_hBrushBack) _WinAPI_PatBlt($wParam, 0, 0, DllStructGetData($tRect, "Right") - DllStructGetData($tRect, "Left"), DllStructGetData($tRect, "Bottom") - DllStructGetData($tRect, "Top"), $PATCOPY) _WinAPI_SelectObject($wParam, $hOldBrush) Return True EndFunc ;==>WM_ERASEBKGND Func WM_DESTROY($hWnd, $uMsg, $wParam, $lParam) ;void _WinAPI_DeleteObject($_hBitmapBack) _WinAPI_DeleteObject($_hBrushBack) EndFunc ;==>WM_DESTROY #endregion WM Func _MyEdit_Proc($hWnd, $uMsg, $wParam, $lParam) ;LRESULT CALLBACK Switch $uMsg Case $WM_VSCROLL, $WM_HSCROLL, $WM_MOUSEWHEEL, $WM_KEYDOWN _WinAPI_PostMessage($hWnd, $WM_APP_REDRAWWINDOW, $hWnd, 0) Case $WM_APP_REDRAWWINDOW Return _MyEdit_OnRedrawWindow($wParam, $lParam) EndSwitch Return _WinAPI_CallWindowProc($_pfnDefEditProc, $hWnd, $uMsg, $wParam, $lParam) EndFunc ;==>_MyEdit_Proc Func _MyEdit_OnRedrawWindow($wParam, $lParam) ;HRESULT Local $uFlags = BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_ERASE) _WinAPI_RedrawWindow($wParam, 0, 0, $uFlags) Return 0 EndFunc ;==>_MyEdit_OnRedrawWindow Func _WinAPI_CreatePatternBrush($hbmp) ;int ;By ProgAndy Local $brush = DllCall("gdi32.dll", "long", "CreatePatternBrush", "long", $hbmp) If Not @error Then Return $brush[0] Return 0 EndFunc ;==>_WinAPI_CreatePatternBrushPreview :autoit_wall_grey_small.bmp Edited December 11, 2013 by FireFox
AZJIO Posted March 26, 2013 Posted March 26, 2013 (edited) expandcollapse popup; #FUNCTION# ;================================================================================= ; Name...........: _StringSplitRegExp ; Description ...: Split a string according to a regular expression. ; Syntax.........: _StringSplitRegExp($sString, $sPattern[, $flag = 0[, $sIncludeMatch = 0[, $iCount = 0]]]) ; Parameters ....: $sString - String: String to split. ; $sPattern - String: Regular expression to split on. ; $flag - return count in the first element ; $sIncludeMatch - ; |0 - To exclude a divider (by default) ; |1 - To attach a divider at the left ; |2 - To attach a divider on the right ; $iCount - The number of times to execute the replacement in the string ; Return values .: Success - Array: Array of substrings, the total is in $array[0]. ; Failure - Array: The count is 1 ($array[0]) and the full string is returned ($array[1]) and sets @error: ; |1 No suitable placeholder delimiter could be constructed. ; |2 Bad RegExp pattern, @extended contains the offset of the error in the pattern. ; |3 Delimiter not found. ; Author ........: AZJIO, weaponx, dany ; ============================================================================================ ; Имя функции ...: _StringSplitRegExp ; Описание ........: Разделяет строки с помощью регулярного выражения ; Синтаксис.......: _StringSplitRegExp($sString, $sPattern[, $flag = 0[, $sIncludeMatch = 0[, $iCount = 0]]]) ; Параметры: ; $sString - Строка для деления на части ; $sPattern - Регулярное выражение определяющая строку, которая будет разделителем ; $flag - По умолчанию 0 - возвращает количество элементов в первый элемент массива, иначе не возвращает ; $sIncludeMatch - Включить раздедитель в результат ; |0 - Исключить разделитель (по умолчанию) ; |1 - Разделитель присоединять слева ; |2 - Разделитель присоединять справа ; $iCount - количество выполненных замен ; Возвращаемое значение: Успешно - Массив строк, в котором $array[0] содержит количество строк в массиве ; Неудачно - Массив в котором исходная строка помещается в $array[1], и устанавливает @error: ; |0 - нет ошибок ; |1 - Внутренняя ошибка, не удалось выбрать подстановочный разделитель ; |2 - Регулярное выражение содержит ошибку ; |3 - Регулярное выражение не находит разделитель в строке ; Автор ..........: AZJIO, weaponx, dany ; ============================================================================================ ; http://www.autoitscript.com/forum/topic/139260-autoit-snippets/?p=1065198 ; http://www.autoitscript.com/forum/topic/139260-autoit-snippets/page__st__140#entry1036931 ; http://www.autoitscript.com/forum/topic/65662-stringsplitregexp/ Func _StringSplitRegExp($sString, $sPattern, $flag = 0, $sIncludeMatch = 0, $iCount = 0) Local $sSplit, $sDelim, $sReplace, $Toggle, $iPos = 1 If IsBinary($sString) Then $sString = Hex($sString) $sDelim = Chr(1) Local $aError[2] = [1, $sString] Else Local $aError[2] = [1, $sString] For $i = 1 To 30 $Toggle = Not $Toggle If $Toggle Then ; 1, 30, 3, 28 ... 27, 4, 29, 2 $sDelim &= Chr($i) Else $sDelim &= Chr(32 - $i) EndIf $iPos = StringInStr($sString, $sDelim, 1, 1, $iPos) ; смещение позволяет найти разделитель за 1 проход If Not $iPos Then ExitLoop ; если вхождение не найдено, то разделитель сформирован Next If $iPos Then Return SetError(1, 0, $aError) EndIf Switch $sIncludeMatch Case 0 $sReplace = $sDelim Case 1 $sReplace = "$0" & $sDelim Case 2 $sReplace = $sDelim & "$0" EndSwitch $sSplit = StringRegExpReplace($sString, $sPattern, $sReplace, $iCount) If @error Then Return SetError(2, @extended, $aError) If Not @extended Then Return SetError(3, 0, $aError) If $flag Then $flag = 2 Return StringSplit($sSplit, $sDelim, 1 + $flag) EndFunc ;==>_StringSplitRegExp expandcollapse popup#include <Array.au3> ; $sString = 'wd12kh4nb5016vg456yu' ; $Array = _StringSplitRegExp($sString, '\d+') ; _ArrayDisplay($Array, 'Array') $sString = '<i>Height</i> <b>15</b> <i>Width</i> <b>22</b>' $Array = _StringSplitRegExp($sString, '(?:\h*</?[ib]>\h*)+') If @error Then MsgBox(0, '', '@error = ' & @error) Else _ArrayDisplay($Array, 'Array') EndIf ; #FUNCTION# ;================================================================================= ; Name...........: _StringSplitRegExp ; Description ...: Split a string according to a regular expression. ; Syntax.........: _StringSplitRegExp($sString, $sPattern) ; Parameters ....: $sString - String: String to split. ; $sPattern - String: Regular expression to split on. ; Return values .: Success - Array ; Failure - sets @error: ; |1 - No match ; |2 - Wrong template ; |3 - The template is not provided excluding groups ; Author ........: AZJIO ; Remarks .......: ; ============================================================================================ ; Имя функции ...: _StringSplitRegExp ; Описание ........: Разделяет строки с помощью регулярного выражения ; Синтаксис.......: _StringSplitRegExp($sString, $sPattern) ; Параметры: ; $sString - Строка для деления на части ; $sPattern - Регулярное выражение определяющая строку, которая будет разделителем ; Возвращаемое значение: Успешно - Массив строк ; Неудачно - Устанавливает @error: ; |1 - Нет совпадений ; |2 - Неправильный шаблон ; |3 - В шаблоне не обеспечено исключение групп ; Автор ..........: AZJIO ; Примечания ..: Особенность такого подхода - все группы в патерне должны быть исключены из поиска методом ?: ; ============================================================================================ Func _StringSplitRegExp($sString, $sPattern) If StringRegExp(StringRegExpReplace($sPattern, '\\.', ''), '\((?!\?(?:<!|<=|=|!|:|>))') Then Return SetError(3) Local $aSplit = StringRegExp($sString, '(?s)(.*?)(?:' & $sPattern & '|\z)', 3) ; Local $aSplit = StringRegExp($sString, '(?s)(.*?' & $sPattern & '|.*?\z)', 3) If @error Then Return SetError(@error) If UBound($aSplit) > 1 Then ReDim $aSplit[UBound($aSplit)-1] Return $aSplit EndFunc ;==>_StringSplitRegExp Edited May 21, 2013 by AZJIO FireFox 1 My other projects or all
FireFox Posted March 30, 2013 Posted March 30, 2013 (edited) ;rounds a size to the nearest font size: ;0, 0.25, 0.5, 0.75, 1 ;Mat's version Func _RoundToFontSize($iSize) Return Round($iSize*4)/4 EndFunc Func _RoundToFontSize($iSize) Local Const $iSizeInt = Int($iSize), $iDecimal = $iSize - $iSizeInt Local $iFontRound = 1 Select Case $iDecimal <= .125 $iFontRound = 0 Case $iDecimal < .375 $iFontRound = .25 Case $iDecimal <= .625 $iFontRound = .5 Case $iDecimal < .875 $iFontRound = .75 EndSelect Return $iSizeInt + $iFontRound EndFunc ;==>_RoundToFontSize Edited June 7, 2013 by FireFox
Mat Posted June 7, 2013 Posted June 7, 2013 (edited) For above, you could just use Round($iSize*4)/4 I've just cleared out a huge directory of test scripts (120 of them!), but I found a couple of little snippets I didn't realise I had. This is a simple Damerau–Levenshtein string matching test. It works best on longer strings when characters are switched, missed or added, with the MVP names I've used for an example below, entering "Xeno" will match "UEZ" rather than "Xenobiologist". String distance is literally the number of changes you'd have to make to transform the string. "Xeno" to "UEZ" is only 3, as you delete the O and change 2 characters (comparisons are case insensitive) expandcollapse popup#include <Math.au3> Local $asMVPs[27] = [ _ "AdmiralAlkex", _ "BrewManNH", _ "DaleHohm", _ "FireFox", _ "GEOSoft", _ "guinness", _ "James", _ "jchd", _ "JLogan3o13", _ "KaFu", _ "kylomas", _ "Manadar", _ "martin", _ "Mat", _ "MHz", _ "monoceres", _ "MrCreatoR", _ "ptrex", _ "TheSaint", _ "UEZ", _ "Valuater", _ "water", _ "wraithdu", _ "Xenobiologist", _ "Yashied", _ "YogiBear", _ "Zedna" _ ] Local $sTest = "DelaHom" MsgBox(0, $sTest, $asMVPs[_String_ClosestMatch($sTest, $asMVPs)]) Func _String_ClosestMatch($sInput, $asOptions) If Not IsArray($asOptions) And UBound($asOptions, 0) <> 1 Then Return SetError(1, 0, 0) Local $iMinLen = -1, $iMinInd = -1, $d For $i = 0 To UBound($asOptions) - 1 $d = _String_Distance($sInput, $asOptions[$i]) ConsoleWrite($asOptions[$i] & @TAB & " - " & $d & @LF) If $iMinLen = -1 Or $d < $iMinLen Then $iMinLen = $d $iMinInd = $i EndIf Next Return SetExtended($iMinLen, $iMinInd) EndFunc ;==>_String_ClosestMatch ; http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance#Algorithm Func _String_Distance($s, $t) Local $m = StringLen($s) Local $n = StringLen($t) Local $d[$m + 1][$n + 1] For $i = 0 To $m $d[$i][0] = $i Next For $j = 0 To $n $d[0][$j] = $j Next Local $cost = 0 For $j = 1 To $n For $i = 1 To $m $cost = 1 - Number(StringMid($s, $i, 1) = StringMid($t, $j, 1)) $d[$i][$j] = _Min($d[$i][$j - 1] + 1, _ ; Insertion _Min($d[$i - 1][$j] + 1, _ ; Deletion $d[$i - 1][$j - 1] + $cost)) ; Substitution If $i > 1 And $j > 1 And _ StringMid($s, $i, 1) = StringMid($t, $j - 1, 1) And _ StringMid($s, $i - 1, 1) = StringMid($t, $j, 1) Then $d[$i][$j] = _Min($d[$i][$j], $d[$i - 1][$j - 1] + $cost) EndIf Next Next Return $d[$m][$n] EndFunc ;==>_String_Distance Edited June 7, 2013 by Mat AutoIt Project Listing
FireFox Posted June 7, 2013 Posted June 7, 2013 (edited) Interesting algorithm. It remembers me a topic where someone were looking for something like this. Edited June 7, 2013 by FireFox
Mat Posted June 7, 2013 Posted June 7, 2013 Another one I found. Not sure what I even used this for though. Like StringInStr, but it finds the nth occurrence of any one of a range of characters in a string. expandcollapse popup#include <Math.au3> Local $sIn = "Hello, World!" ConsoleWrite($sIn & @LF) ConsoleWrite(_String_CharInStr($sIn, " .,?!", 0, -1) & @LF) ; Same as StringInStr, but searches for any character within $sChars. ; Returns the index of the actual character in @extended Func _String_CharInStr($sString, $sChars, $iCaseSense = 0, $iOccurence = 1, $iStart = Default, $iCount = Default) Local $iRet = -1, $i If $iCount = Default Then $iCount = StringLen($sString) If $iStart = Default Then If $iOccurence < 0 Then $iStart = StringLen($sString) Else $iStart = 1 EndIf EndIf Local $iEnd = $iStart + $iCount, $iStep = 1 If $iOccurence < 0 Then $iEnd = $iStart - $iCount $iStep = -1 EndIf Local $n = 0, $j For $c = $iStart To $iEnd Step $iStep $j = StringInStr($sChars, StringMid($sString, $c, 1), $iCaseSense) If $j Then $n += $iStep If $n = $iOccurence Then Return SetExtended($j, $c) EndIf Next If $iRet < 0 Then Return 0 Return $iRet EndFunc ;==>_String_CharInStr AutoIt Project Listing
DatMCEyeBall Posted July 8, 2013 Posted July 8, 2013 Improved _ArrayFindAll(): expandcollapse popup#include <Array.au3> ;For _ArrayFindAll() #AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w- 7 Global $Dim = 10, $Timer, $iPercDiff Do $Dim *= 10 ; Create an array and fill it with random numbers Global $avArray[$Dim] For $x = 0 To UBound($avArray) - 1 $avArray[$x] = Random(0, 5, 1) Next ConsoleWrite("$avArray[" & UBound($avArray) & "]" & @CRLF) ; Get how long _ArrayFindAll() takes $Timer = TimerInit() Global $aiResult1 = _ArrayFindAll($avArray, 0) Global $iTimerDiff1 = TimerDiff($Timer) ConsoleWrite("_ArrayFindAll = " & Round($iTimerDiff1, 2) & " ms" & @CRLF) ; Get how long _ArrayFindAllFast() takes $Timer = TimerInit() Global $aiResult2 = _ArrayFindAllFast($avArray, 0) Global $iTimerDiff2 = TimerDiff($Timer) ConsoleWrite("_ArrayFindAllFast = " & Round($iTimerDiff2, 2) & " ms" & @CRLF) ; Display the difference in % If $iTimerDiff1 > $iTimerDiff2 Then $iPercDiff = Round(($iTimerDiff1 - $iTimerDiff2) / $iTimerDiff1 * 100, 2) & "% faster" Else $iPercDiff = Round(($iTimerDiff2 - $iTimerDiff1) / $iTimerDiff1 * 100, 2) & "% slower" EndIf ConsoleWrite("_ArrayFindAllFast() is " & $iPercDiff & " than _ArrayFindAll()" & @CRLF & @CRLF) Until $Dim = 1000000 Func _ArrayFindAllFast(Const ByRef $avArray, $vValue, $iStart = 0, $iEnd = 0, $iCase = 0, $iCompare = 0, $iForward = 1, $iSubItem = -1) If Not IsArray($avArray) Then Return SetError(1, 0, -1) If UBound($avArray, 0) > 2 Or UBound($avArray, 0) < 1 Then Return SetError(2, 0, -1) Local $iUBound = UBound($avArray) - 1 ; Bounds checking If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound If $iStart < 0 Then $iStart = 0 If $iStart > $iEnd Then Return SetError(4, 0, -1) ; Direction (flip if $iForward = 0) Local $iStep = 1 If Not $iForward Then Local $iTmp = $iStart $iStart = $iEnd $iEnd = $iTmp $iStep = -1 EndIf ; same var Type of comparison Local $iCompType = False If $iCompare = 2 Then $iCompare = 0 $iCompType = True EndIf Local $aiFoundData ; Search Switch UBound($avArray, 0) Case 1 ; 1D array search If Not $iCompare Then If Not $iCase Then For $i = $iStart To $iEnd Step $iStep If $iCompType And VarGetType($avArray[$i]) <> VarGetType($vValue) Then ContinueLoop If $avArray[$i] = $vValue Then $aiFoundData &= "|" & $i Next Else For $i = $iStart To $iEnd Step $iStep If $iCompType And VarGetType($avArray[$i]) <> VarGetType($vValue) Then ContinueLoop If $avArray[$i] == $vValue Then $aiFoundData &= "|" & $i Next EndIf Else For $i = $iStart To $iEnd Step $iStep If StringInStr($avArray[$i], $vValue, $iCase) > 0 Then $aiFoundData &= "|" & $i Next EndIf Case 2 ; 2D array search Local $iUBoundSub = UBound($avArray, 2) - 1 If $iSubItem > $iUBoundSub Then $iSubItem = $iUBoundSub If $iSubItem < 0 Then ; will search for all Col $iSubItem = 0 Else $iUBoundSub = $iSubItem EndIf For $j = $iSubItem To $iUBoundSub If Not $iCompare Then If Not $iCase Then For $i = $iStart To $iEnd Step $iStep If $iCompType And VarGetType($avArray[$i][$j]) <> VarGetType($vValue) Then ContinueLoop If $avArray[$i][$j] = $vValue Then $aiFoundData &= "|" & $i Next Else For $i = $iStart To $iEnd Step $iStep If $iCompType And VarGetType($avArray[$i][$j]) <> VarGetType($vValue) Then ContinueLoop If $avArray[$i][$j] == $vValue Then $aiFoundData &= "|" & $i Next EndIf Else For $i = $iStart To $iEnd Step $iStep If StringInStr($avArray[$i][$j], $vValue, $iCase) > 0 Then $aiFoundData &= "|" & $i Next EndIf Next Case Else Return SetError(7, 0, -1) EndSwitch If $aiFoundData <> "" Then Return StringSplit(StringTrimLeft($aiFoundData, 1), "|", 2) Else Return SetError(6, 0, -1) EndIf EndFunc ;==>_ArrayFindAllFast oapjr 1 "Just be fred, all we gotta do, just be fred." -Vocaliod "That is a Hadouken. A KAMEHAMEHA would have taken him 13 days and 54 episodes to form." - Roden Hoxha @tabhooked Clock made of cursors ♣ Desktop Widgets ♣ Water Simulation
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now