xOAT Posted November 18, 2010 Share Posted November 18, 2010 (edited) I am trying to split a string with a delimiter into all combinations. If the given string is "autoit" the output should be: autoit a-utoit au-toit aut-oit auto-it autoi-t a-u-toit a-ut-oit a-uto-it a-utoi-t au-t-oit au-to-it au-toi-t aut-o-it aut-oi-t auto-i-t a-u-t-oit a-u-to-it a-u-toi-t a-ut-o-it a-ut-oi-t a-uto-i-t au-t-o-it au-t-oi-t au-to-i-t aut-o-i-t a-u-t-o-it a-u-t-oi-t a-u-to-i-t a-ut-o-i-t au-t-o-i-t a-u-t-o-i-t The problem I am having is making it compatible with strings of different lengths. I am guessing it can be done with recursion or complex loops. Here is what I have so far: #Include <String.au3> $prefix = "autoit" $length = StringLen ( $prefix ) $delimiter = "-" ;NO DELIMITER ConsoleWrite( $prefix & @CRLF ) ;ONE DELIMITER For $i = 1 To $length - 1 Step 1 $string = _StringInsert( $prefix, $delimiter, $i ) ConsoleWrite( $string & @CRLF ) Next ;TWO DELIMITERS $count = $length - 3 $inc = 1 $dotcount = 1 Do For $i = $length - $count To $length $string = _StringInsert( $prefix, $delimiter, $inc ) $string = _StringInsert( $string, $delimiter, $i ) ConsoleWrite( $string & @CRLF ) Next $count -= 1 $inc += 1 Until $count < 0 This only works with a string length of 6. Help please. Edited November 19, 2010 by xOAT Link to comment Share on other sites More sharing options...
SadBunny Posted November 19, 2010 Share Posted November 19, 2010 (edited) So, if you are guessing it can be done with recursion, why didn't you try recursion yet? Something like this, perhaps? #include <String.au3> $string = "123456" ConsoleWrite($string&@CRLF) _interdash("", $string) Exit Func _interdash($prefix, $string) For $i = 1 To StringLen($string) - 1 ConsoleWrite($prefix & _StringInsert($string, "-", $i) & @CRLF) Next If StringLen($string) > 2 Then $newPrefix = $prefix & StringMid($string, 1, 1) & "-" _interdash($newPrefix, StringMid($string, 2)) EndIf EndFunc ;==>_interdash Edited November 19, 2010 by SadBunny Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
xOAT Posted November 19, 2010 Author Share Posted November 19, 2010 So, if you are guessing it can be done with recursion, why didn't you try recursion yet? Because it hurts my head... Thanks, that is close to what I'm looking for. The intermediate combos are missing like 12-, 123-, etc. There are 2^(length - 1) combinations.Mind completing it for me? Link to comment Share on other sites More sharing options...
GPinzone Posted November 19, 2010 Share Posted November 19, 2010 (edited) Because it hurts my head... Thanks, that is close to what I'm looking for. The intermediate combos are missing like 12-, 123-, etc. There are 2^(length - 1) combinations. Mind completing it for me? It can be solved by using a binary counter from 0 to 2^NumTokens - 1, where the number of tokens is always one less than the length of the string. I can't believe AutoIt doesn't have built in "Decimal to Binary" conversion functions, because that's precisely what you can use to determine when to insert tokens. I can't claim that this is the most efficient algorithm, but it works: expandcollapse popupLocal $String = "abcdef" Local $NumChars = StringLen($String) Local $NumTokens = $NumChars - 1 Local $OutputString Local Const $Token = "-" Local $i, $j For $i = 0 To 2^$NumTokens - 1 $TokenMask = _DecToBinary($i, $NumTokens) $OutputString = "" For $j = 1 To $NumChars - 1 ; Append jth char from string. $OutputString = $OutputString & StringMid($String, $j, 1) ; Insert token when jth character of mask is a 1. If StringMid($TokenMask, $j, 1) = 1 Then $OutputString = $OutputString & $Token EndIf Next ; Append last character in string. $OutputString = $OutputString & StringMid($String, $NumChars, 1) MsgBox(0, "", $OutputString) Next Func _DecToBinary ($DecNum, $NumDigits) Local $i, $tmp, $c Local $BinNum $c = 1 For $i = 1 To $NumDigits $tmp = BitAND ($DecNum, $c) If $tmp = 0 Then $BinNum = "0" & $BinNum Else $BinNum = "1" & $BinNum EndIf $c = BitShift($c, -1) ; Shift left by 1 place Next Return $BinNum EndFunc I found and converted the _DecToBinary algorithm from a completely different programming language. EDIT: Updated the code with better comments so you can understand how it works. Gerard J. Pinzone gpinzone AT yahoo.com Edited November 19, 2010 by CPinzone Gerard J. Pinzonegpinzone AT yahoo.com Link to comment Share on other sites More sharing options...
xOAT Posted November 19, 2010 Author Share Posted November 19, 2010 It can be solved by using a binary counter from 0 to 2^NumTokens - 1, where the number of tokens is always one less than the length of the string. I can't believe AutoIt doesn't have built in "Decimal to Binary" conversion functions, because that's precisely what you can use to determine when to insert tokens. I can't claim that this is the most efficient algorithm, but it works: -snip- I found and converted the _DecToBinary function from a completely different language. Thanks for this! I am not concerned with its efficiency, so its perfect. Link to comment Share on other sites More sharing options...
sfmike Posted November 19, 2010 Share Posted November 19, 2010 I've got a similar issue where I have to figure out where to split my string. Below is an example of the field I need to split. IRC (Chat) 194(IRC (Chat) 194): As you can see, the string is repeated inside quotes. The field is variable in length and the delimeters are used inside the string as well. How can i strip out the correct pair of parenthesis and compare the strings? If the things are different, I keep the whole string. If they match, I strip out the duplicate data inside the paraenthesis. Thanks, Mike Link to comment Share on other sites More sharing options...
jchd Posted November 19, 2010 Share Posted November 19, 2010 Using a generic regexp, depending on the _structure_ of your input string. If you whish to test if the input is of the form: X(X) where X is something like IRC (Chat) 194 why not use a regexp pattern like (.+?)\(\1\) It should be close to working for you, even if it involves some backtracking. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
SadBunny Posted November 19, 2010 Share Posted November 19, 2010 It can be solved by using a binary counter from 0 to 2^NumTokens - 1, where the number of tokens is always one less than the length of the string. I can't believe AutoIt doesn't have built in "Decimal to Binary" conversion functions, because that's precisely what you can use to determine when to insert tokens. I can't claim that this is the most efficient algorithm, but it works:Nice one! Yeah I didn't actually manually verify the output of my example Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
sfmike Posted November 19, 2010 Share Posted November 19, 2010 Using a generic regexp, depending on the _structure_ of your input string.If you whish to test if the input is of the form: X(X) where X is something like IRC (Chat) 194why not use a regexp pattern like (.+?)\(\1\)It should be close to working for you, even if it involves some backtracking.I'm pretty new to this stuff. I'm looking through the help files but not seeing any references to those special characters (.+?)\(\1\). where should I be looking?Thanks Mike Link to comment Share on other sites More sharing options...
jchd Posted November 19, 2010 Share Posted November 19, 2010 OK, sorry I've a bit elliptic about that. Try this: $mystring = "IRC (Chat) 194(IRC (Chat) 194):" $match = StringRegExp($mystring, "(.+?)\(\1\):") ;; $match will be = 1 if $mystring is of the form X(X): where X is a more or less arbitrary string ;; I understood the final colon to be part of the input, hence I made it part of the pattern This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
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