Thread Rating:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Alphabetical sort of characters within a string.
#11
(04-25-2024, 01:07 AM)Pete Wrote: A simply way to get the letters in a word or phrase sorted in alphabetical order...

Code: (Select All)
a$ = "uncopyrightable"
For i = 1 To 26
    If InStr(LCase$(a$), Chr$(96 + i)) Then Print Chr$(96 + i);
Next


If you'd like to see how many times a letter occurred, it's just a little more code...

Code: (Select All)
a$ = "lots of letters repeated"
For i% = 1 To 26
    seed% = InStr(LCase$(a$), Chr$(96 + i%))
    If seed% Then
        Do
            If InStr(seed%, LCase$(a$), Chr$(96 + i%)) Then
                Print Chr$(96 + i%);
                seed% = InStr(seed%, LCase$(a$), Chr$(96 + i%)) + 1
            Else
                Exit Do
            End If
        Loop
    End If
Next

Pete

+1 that's pretty cool pete, here is quicker
Code: (Select All)
a$ = "lots of letters repeated"
For i% = 1 To 26
    seed% = InStr(LCase$(a$), Chr$(96 + i%))
    While seed%
        Print Chr$(96 + i%);
        seed% = InStr(seed% + 1, LCase$(a$), Chr$(96 + i%))
    Wend
Next
b = b + ...
Reply
#12
When I coded just a bit ago, I thought it might just need a hair cut, and it did!

I think we both deserve a +1 for this effort!

Pete
Reply
#13
(04-25-2024, 01:40 AM)Pete Wrote: When I coded just a bit ago, I thought it might just need a hair cut, and it did!

I think we both deserve a +1 for this effort!

Pete

and steve's use of string was good too!
b = b + ...
Reply
#14
(04-25-2024, 01:28 AM)bplus Wrote: +1 that's pretty cool pete, here is quicker
Code: (Select All)
a$ = "lots of letters repeated"
For i% = 1 To 26
    seed% = InStr(LCase$(a$), Chr$(96 + i%))
    While seed%
        Print Chr$(96 + i%);
        seed% = InStr(seed% + 1, LCase$(a$), Chr$(96 + i%))
    Wend
Next
Wow! That is off the planet! Thanks so much guys. Even though I've been messing with basic on and off since 1989, when I see some of the examples here I feel similar to when I watch some people playing guitar on youtube. Makes me wonder why i even try... BTW the purpose of this is to find anagrams in a long list of words. Thanks again.
Reply
#15
Code: (Select All)
a$ = "this is uncopyrightable"
FOR i% = 1 TO 26
  FOR j% = 1 TO LEN(a$)
    t$ = UCASE$( MID$(a$,j%,1) )
    IF ASC(t$) = 64 + i% THEN PRINT t$;
  NEXT
NEXT
Reply
#16
(04-25-2024, 04:45 AM)Circlotron Wrote:
(04-25-2024, 01:28 AM)bplus Wrote: +1 that's pretty cool pete, here is quicker
Code: (Select All)
a$ = "lots of letters repeated"
For i% = 1 To 26
    seed% = InStr(LCase$(a$), Chr$(96 + i%))
    While seed%
        Print Chr$(96 + i%);
        seed% = InStr(seed% + 1, LCase$(a$), Chr$(96 + i%))
    Wend
Next
Wow! That is off the planet! Thanks so much guys. Even though I've been messing with basic on and off since 1989, when I see some of the examples here I feel similar to when I watch some people playing guitar on youtube. Makes me wonder why i even try... BTW the purpose of this is to find anagrams in a long list of words. Thanks again.
You may also be interested in something such as this then:  https://qb64phoenix.com/forum/showthread.php?tid=72

That's my Scrabble Word List maker, which does a good ob making words from various combinations of letters.  Smile
Reply
#17
(04-25-2024, 04:50 AM)CharlieJV Wrote:
Code: (Select All)
a$ = "this is uncopyrightable"
FOR i% = 1 TO 26
  FOR j% = 1 TO LEN(a$)
    t$ = UCASE$( MID$(a$,j%,1) )
    IF ASC(t$) = 64 + i% THEN PRINT t$;
  NEXT
NEXT

@CharlieJV almost same as Pete's only without instr both suffer from taking ucase$ or lcase$ more often than needed, asc can take a 2nd argument and work faster than mid$ for single letter.
Code: (Select All)
a$ = "this is uncopyrightable"
ua$ = UCase$(a$) ' do this once
For i% = 1 To 26
    For j% = 1 To Len(a$)
        If Asc(ua$, j%) = 64 + i% Then Print Chr$(i% + 64);
    Next
Next

i think instr will go faster than testing every letter in word 26 times.

i am suspecting steve's or my mod of anacode$ with string$ will be faster than pete's using instr in alpha order, i like the fact we count over the length of word only once and there is no if testing when producing the return string from counts array. it is count len(word$) + 26 string alpha steps versus instr length of word and if find instr again and another if find... length of word x 2 ifs over 26 letters steps ie they both have to go 26 letter steps but no if's in steve's/my mod with string$.

i will test by anacoding a dictionary with both methods, might consider throwing out the need for ucase$/lcase$ as entire dictionary is all capitals to start.
b = b + ...
Reply
#18
here are the 2 test routines written as functions check my optimizing
Code: (Select All)
_Title "anaCode$ versus peteCode$" ' b+ 2022-11-17 mod 2024-04-24 decodeAnacode sub
test$(0) = "grmaana"
test$(1) = "angiogram"
test$(2) = "naagrma"
test$(3) = "telgram"
test$(4) = "gramana"
test$(5) = "gram"
test$(6) = "nag"
test$(7) = "tag"
test$(8) = "am"
test$(9) = "grip"

For i = 0 To 9
    Print test$(i), AnaCode$(UCase$(test$(i))), peteCode$(UCase$(test$(i)))
Next

' return sorted anagram code string for any word, call ucase$(wrd$) for all caps
Function AnaCode$ (wrd$) ' anaCode$ converts word to an Anagram pattern
    ' wrd$ is assumed to be in all capitals!!!
    ' number of A's in first, number of B's in 2nd, number of C's in third
    Dim As Integer L(26), i, p
    Dim rtn$
    For i = 1 To Len(wrd$)
        p = Asc(wrd$, i) - 64 ' A=1, B=2...
        L(p) = L(p) + 1
    Next
    For i = 1 To 26
        rtn$ = rtn$ + String$(L(i), Chr$(i + 64)) ' thanks steve for string$ idea
    Next
    AnaCode$ = rtn$
End Function

Function peteCode$ (a$) 'converts word to an Anagram pattern
    ' a$ is assumed to be all caps call ucase$(a$) if not
    Dim i%, seed%, rtn$
    For i% = 1 To 26
        seed% = InStr(a$, Chr$(64 + i%))
        While seed%
            rtn$ = rtn$ + Chr$(64 + i%)
            seed% = InStr(seed% + 1, a$, Chr$(64 + i%))
        Wend
    Next
    peteCode$ = rtn$
End Function
b = b + ...
Reply
#19
(04-25-2024, 11:13 AM)bplus Wrote:
(04-25-2024, 04:50 AM)CharlieJV Wrote:
Code: (Select All)
a$ = "this is uncopyrightable"
FOR i% = 1 TO 26
  FOR j% = 1 TO LEN(a$)
    t$ = UCASE$( MID$(a$,j%,1) )
    IF ASC(t$) = 64 + i% THEN PRINT t$;
  NEXT
NEXT

@CharlieJV almost same as Pete's only without instr both suffer from taking ucase$ or lcase$ more often than needed, asc can take a 2nd argument and work faster than mid$ for single letter.
Code: (Select All)
a$ = "this is uncopyrightable"
ua$ = UCase$(a$) ' do this once
For i% = 1 To 26
    For j% = 1 To Len(a$)
        If Asc(ua$, j%) = 64 + i% Then Print Chr$(i% + 64);
    Next
Next

i think instr will go faster than testing every letter in word 26 times.

i am suspecting steve's or my mod of anacode$ with string$ will be faster than pete's using instr in alpha order, i like the fact we count over the length of word only once and there is no if testing when producing the return string from counts array. it is count len(word$) + 26 string alpha steps versus instr length of word and if find instr again and another if find... length of word x 2 ifs over 26 letters steps ie they both have to go 26 letter steps but no if's in steve's/my mod with string$.

i will test by anacoding a dictionary with both methods, might consider throwing out the need for ucase$/lcase$ as entire dictionary is all capitals to start.

Yeah, I could have called UCASE$ once outside of the looping, but I was going for shortest amount of code vs performance.

That said, UCASE$ x times for a single character vs UCASE$ 1 time for x characters, would there be a difference? 

Yeah, not in love with that second parameter for ASC.  I'm a little bit too much old school there.
Reply
#20
How is ASC( ua$, j%) faster than MID$(a$,j%,1) ? Don't they have to do the same kind of work to get that one character in that one position?

And if there is a benefit, is it being nullified by calling the extra CHR$ and the addition in the param?
Reply




Users browsing this thread: 5 Guest(s)