Announcement

Collapse
No announcement yet.

Tally Wrong Choice

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Stuart McLachlan
    replied
    Originally posted by Michael Mattias View Post

    REGEXPR supports searching for whole words. "It's In The Manual"
    Great demo of REGEXPR including whole word search here..
    More apposite demo here:
    '
    Code:
    #COMPILE EXE
    #DIM ALL
    
    FUNCTION PBMAIN () AS LONG
        LOCAL strtarget,strSearch AS STRING
        strTarget = "ice ice iceberg ice$" & $CRLF & "rice" & $TAB & "ice,Ice."
        strSearch = "ice"
        ? STR$(RegExWholeWords(strTarget,strSearch,0)) & " matches"
    END FUNCTION
    
    FUNCTION RegExWholeWords(BYVAL strTarget AS STRING, strSearch AS STRING,CaseSensitive AS LONG) AS LONG
        LOCAL lPos,lCount AS LONG
        LOCAL strMask AS STRING
        strMask = "\b" & strSearch & "\b"
        IF CaseSensitive THEN strMask += "\c"
        REGEXPR strMask IN strTarget TO lPos
        WHILE lPos > 0
            INCR lCount
            REGEXPR strMask IN strTarget AT lPos + LEN(strsearch) TO lPos
        WEND
        FUNCTION = lCount
    END FUNCTION
    '

    Leave a comment:


  • Pierre Bellisle
    replied
    No need to say...

    Leave a comment:


  • Michael Mattias
    replied
    The code above would only be used to search for whole words
    REGEXPR supports searching for whole words. "It's In The Manual"

    Great demo of REGEXPR including whole word search here... REGEXPR and REGREPL demo January 16, 2002

    BIAS ALERT: I am not a neutral source on the greatness of that demo.

    Leave a comment:


  • Mike Doty
    replied
    Tally may be Right Choice
    Stuart added CaseSensitive flag
    Code:
    #DIM ALL
    FUNCTION PBMAIN ()  AS LONG
     LOCAL sMain,sMatch AS STRING,CaseSensitive AS LONG
     sMain  = "ice ice, ice mice ice."
     sMatch = "ice"
     ? "Pierre" + STR$(Pierre(sMain,sMatch)) + $CR +_
       "Stuart" + STR$(Stuart(sMain,sMatch,CaseSensitive)) + $CR +_
       "Mike"   + STR$(Mike(sMain,sMatch))
    END FUNCTION
    '
    FUNCTION Pierre(BYVAL sMain AS STRING,BYVAL sMatch AS STRING) AS LONG
     LOCAL index        AS LONG
     LOCAL WordCount    AS LONG
     LOCAL LenSubString AS LONG
     LenSubString = LEN(sMatch)
     sMain = SHRINK$(sMain, $WHITESPACE & ",.?!=%$&") '<- Add all non word characters
     FOR index = 1 TO PARSECOUNT(sMain, sMatch)
      IF LEN(PARSE$(sMain, $SPC, index)) = LenSubString THEN INCR WordCount
     NEXT
     FUNCTION = WordCount
    END FUNCTION
    '
    FUNCTION Stuart(BYVAL strTarget AS STRING, strSearch AS STRING,CaseSensitive AS LONG) AS LONG
        LOCAL strNonLetters,strReplacer AS STRING
        strNonletters = CHR$(1 TO 64,91 TO 96,123 TO 255)
        strReplacer = STRING$(LEN(strNonLetters),CHR$(26)) ' ASCII 26 = SUBstitute
    
        REPLACE ANY strNonLetters WITH strReplacer IN strTarget
        strTarget =SHRINK$(strTarget,CHR$(26))
        REPLACE CHR$(26) WITH CHR$(26,26) IN strTarget
        strTarget = CHR$(26) & strTarget & CHR$(26)
    
        IF CaseSensitive THEN
            FUNCTION = TALLY(strTarget, CHR$(26) & strSearch & CHR$(26))
        ELSE
            FUNCTION = TALLY(UCASE$(strTarget), CHR$(26) & UCASE$(strSearch) & CHR$(26))
        END IF
    END FUNCTION
    '
    FUNCTION Mike(BYVAL sMain AS STRING, BYVAL sMatch AS STRING) AS LONG
     LOCAL i,icount,LengthMinus1 AS LONG
     sMain = SHRINK$(sMain, $WHITESPACE & ",.?!=%$&") '<- Add all non word characters
     sMain = WRAP$(sMain," "," ")
     sMatch = WRAP$(sMatch,$SPC,$SPC)
     LengthMinus1 = LEN(sMatch) -1
     i = INSTR(sMain,sMatch)
     WHILE i
      INCR iCount
      i = INSTR(i+LengthMinus1,sMain,sMatch)
     WEND
     FUNCTION = iCount
    END FUNCTION

    Leave a comment:


  • Stuart McLachlan
    replied
    Originally posted by Mike Doty View Post
    Test all at same time.
    My bad! I edited my code without commenting on the edit. Note that it now has a CaseSensitive flag.



    Leave a comment:


  • Mike Doty
    replied
    Stuart TALLY (no looping) and CaseSensitive flag.
    Code:
    FUNCTION PBMAIN AS LONG
     LOCAL sMain,sMatch AS STRING,CaseSensitive AS LONG
     sMain  = "ice ice, ice mice ice."
     sMatch = "ice"
     ? "Pierre"+STR$(Pierre(sMain,sMatch))+$CR +"Stuart"+STR$(Stuart(sMain,sMatch,CaseSensitive))+$CR+"Mike"+STR$(Mike(sMain,sMatch))
    END FUNCTION
    '
    FUNCTION Pierre(BYVAL sMain AS STRING,BYVAL sMatch AS STRING) AS LONG
     LOCAL index        AS LONG
     LOCAL WordCount    AS LONG
     LOCAL LenSubString AS LONG
     LenSubString = LEN(sMatch)
     sMain = SHRINK$(sMain, $WHITESPACE & ",.?!=%$&") '<- Add all non word characters
     FOR index = 1 TO PARSECOUNT(sMain, sMatch)
      IF LEN(PARSE$(sMain, $SPC, index)) = LenSubString THEN INCR WordCount
     NEXT
     FUNCTION = WordCount
    END FUNCTION
    '
    FUNCTION Stuart(BYVAL strTarget AS STRING, strSearch AS STRING,CaseSensitive AS LONG) AS LONG
     LOCAL strNonLetters,strReplacer AS STRING
     strNonletters = CHR$(1 TO 64,91 TO 96,123 TO 255)
     strReplacer = STRING$(LEN(strNonLetters),CHR$(26)) ' ASCII 26 = SUBstitute
     REPLACE ANY strNonLetters WITH strReplacer IN strTarget
     strTarget =SHRINK$(strTarget,CHR$(26))
     REPLACE CHR$(26) WITH CHR$(26,26) IN strTarget
     strTarget = CHR$(26) & strTarget & CHR$(26)
     IF CaseSensitive THEN
      FUNCTION = TALLY(strTarget, CHR$(26) & strSearch & CHR$(26))
     ELSE
      FUNCTION = TALLY(UCASE$(strTarget), CHR$(26) & UCASE$(strSearch) & CHR$(26))
     END IF
    END FUNCTION
    '
    FUNCTION Mike(BYVAL sMain AS STRING, BYVAL sMatch AS STRING) AS LONG
     LOCAL i,icount,LengthMinus1 AS LONG
     sMain = SHRINK$(sMain, $WHITESPACE & ",.?!=%$&") '<- Add all non word characters
     sMain = WRAP$(sMain," "," "): sMatch = WRAP$(sMatch,$SPC,$SPC)
     LengthMinus1 = LEN(sMatch) -1: i = INSTR(sMain,sMatch)
     WHILE i:INCR iCount: i = INSTR(i+LengthMinus1,sMain,sMatch):WEND
     FUNCTION = iCount
    END FUNCTION

    Leave a comment:


  • Stuart McLachlan
    replied
    Another method:

    (If you want to search for "words" containing apostrophes and/or hyphens, modify strNonLetters)

    '
    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE ONCE "WIN32API.INC"
    
    
    FUNCTION PBMAIN () AS LONG
        LOCAL strtarget,strSearch AS STRING
        strTarget = "ice ice iceberg ice$" & $CRLF & "rice" & $TAB & "ice,Ice."
        strSearch = "ice"
        ? STR$(TallyWholeWords(strTarget,strSearch,0)) & " matches"
    END FUNCTION
    
    FUNCTION TallyWholeWords(BYVAL strTarget AS STRING, strSearch AS STRING,CaseSensitive AS LONG) AS LONG
        LOCAL strNonLetters,strReplacer AS STRING
        strNonletters = CHR$(1 TO 64,91 TO 96,123 TO 255)
        strReplacer = STRING$(LEN(strNonLetters),CHR$(26)) ' ASCII 26 = SUBstitute
    
        REPLACE ANY strNonLetters WITH strReplacer IN strTarget
        strTarget =SHRINK$(strTarget,CHR$(26))
        REPLACE CHR$(26) WITH CHR$(26,26) IN strTarget
        strTarget = CHR$(26) & strTarget & CHR$(26)
    
        IF CaseSensitive THEN
            FUNCTION = TALLY(strTarget, CHR$(26) & strSearch & CHR$(26))
        ELSE
            FUNCTION = TALLY(UCASE$(strTarget), CHR$(26) & UCASE$(strSearch) & CHR$(26))
        END IF
    
    END FUNCTION
    '

    Leave a comment:


  • Mike Doty
    replied
    Pierre,
    Added LenSubString
    Code:
    #DIM ALL
    FUNCTION PBMAIN () AS LONG
     LOCAL sMainString AS STRING
     LOCAL sSubString AS STRING
     LOCAL index AS LONG
     LOCAL WordCount AS LONG
     LOCAL LenSubString AS LONG
    
     sMainString = "ice ice, ice mice iceberg ice$ ice."
     sSubString = "ice"
     LenSubString = LEN(sSubString)
     sMainString = SHRINK$(sMainString, $WHITESPACE & ",.?!=%$&") '<- Add all non word characters
     FOR index = 1 TO PARSECOUNT(sMainString, sSubString)
      IF LEN(PARSE$(sMainString, $SPC, index)) = LenSubString THEN INCR WordCount
     NEXT
     ? STR$(WordCount)
    END FUNCTION

    Now using SHRINK$ from Pierre this will also work.
    Code:
    FUNCTION PBMAIN() AS LONG
     LOCAL sMain, sSearch AS STRING
     sMain  = "ice ice, ice mice ice."
     sSearch= "ice"
     ? STR$(WordCount(sMain,sSearch))
    END FUNCTION
    
    FUNCTION WordCount(BYVAL sMain AS STRING, BYVAL SearchFor AS STRING) AS LONG
    
     LOCAL i,icount,LengthMinus1 AS LONG
    
     sMain = SHRINK$(sMain, $WHITESPACE & ",.?!=%$&") '<- Add all non word characters
     sMain = WRAP$(sMain," "," ")
    
     SearchFor = WRAP$(SearchFor,$SPC,$SPC)
    
     LengthMinus1 = LEN(SearchFor) -1
     i = INSTR(sMain,SearchFor)
     WHILE i
      INCR iCount
      i = INSTR(i+LengthMinus1,sMain,SearchFor)
     WEND
     FUNCTION = iCount
     'https://forum.powerbasic.com/forum/user-to-user-discussions/powerbasic-for-windows/795149-tally-wrong-choice#post795163
    END FUNCTION

    Leave a comment:


  • Pierre Bellisle
    replied
    Mike,
    Any man that have passed Rod's test is an happy man ! :-)

    Dale,
    Post 11 and 22

    Leave a comment:


  • Dale Yarker
    replied
    Originally posted by Mike Doty View Post
    Code:
    Looking for an exact word ice
    ice. ice, "ice" and others are also valid.
    FUNCTION PBMAIN () AS LONG
    ? STR$(TALLY("dice, spice lice icey","ice")) 'tally finds 4, but 0 are the word ice
    END FUNCTION'
    Where is "I would expect 4" in post 19. Sorry if I simply can't see it.

    Leave a comment:


  • Mike Doty
    replied
    What about "ice ice, ice mice ice." I would expect 4.
    Pierre,
    Nice, passes Rods's post #11.

    Dale,
    change "ice" to "ice"
    ?

    Leave a comment:


  • Dale Yarker
    replied
    Looking for an exact word ice
    Then change match string from "ice" to " ice" to force looking for a word. (Without a space it is just 3 letters surrounded by anything.)

    Cheers,

    Leave a comment:


  • Pierre Bellisle
    replied
    Gary, depending on your exact goal and context, this one might be interesting for you...
    It is not optimized for speed but for little footprint in the ide.
    I have not exactly the same view but I think it's what you like...
    It should be robust enough.

    Code:
     LOCAL sMainString AS STRING
     LOCAL sSubString  AS STRING
     LOCAL index       AS LONG
     LOCAL WordCount   AS LONG
    
     sMainString = "ice ice iceberg ice$ %ice   iceice" & $CRLF & "rice" & $TAB & "ice,ice."
     sSubString  = "ice"  
    
     sMainString = SHRINK$(sMainString, $WHITESPACE & ",.?!=%$&") '<- Add all non word characters you want
     FOR index = 1 TO PARSECOUNT(sMainString, sSubString)
       IF LEN(PARSE$(sMainString, $SPC, index)) = LEN(sSubString) THEN INCR WordCount
     NEXT
    
     ? "[" & sMainString & "]" & $CRLF & "[" & sSubString & "]" & $CRLF & "Count: " & STR$(WordCount)

    Leave a comment:


  • Mike Doty
    replied
    Code:
    Looking for an exact word ice
    ice. ice, "ice"  and others are also valid.
    FUNCTION PBMAIN () AS LONG
     ? STR$(TALLY("dice, spice lice icey","ice")) 'tally finds 4, but 0 are the word ice
    END FUNCTION'

    Leave a comment:


  • Kerry Farmer
    replied
    I coded it

    Code:
    DIM s AS STRING
    DIM ss AS STRING
    s = "ice"
    ss = "ice ice"
    ? TALLY (ss,s)
    WAITKEY$ 
    Gives 2

    DIM s AS STRING
    Code:
    DIM ss AS STRING
    s = "ice"
    ss = "iceice"
    ? TALLY (ss,s)
    WAITKEY$
    Gives 2

    Code:
    DIM s AS STRING
    DIM ss AS STRING
    s = "a"
    ss = "a a a a"
    ? TALLY 
    Gives 4

    Code:
    DIM s AS STRING
    DIM ss AS STRING
    s = "a"
    ss = "aaaa"
    ? TALLY (ss,s)
    WAITKEY$
    Gives 4

    which is totally what i expected.

    This is important to me - so forgive my denseness

    What point am I missing?

    Windows 10, latest PBCC

    Thanks

    Leave a comment:


  • Kerry Farmer
    replied
    Thanks Mike

    So if my string was 'aaaa' how many would it tally? [I should code it!]

    Leave a comment:


  • Mike Doty
    replied
    Code:
    'count = TALLY (mainstring,matchstring)
    FUNCTION PBMAIN () AS LONG
     ? STR$(TALLY("a a a a","a")) '4
     ? STR$(TALLY("a a a a","a ")) '3
    END FUNCTION

    Leave a comment:


  • Kerry Farmer
    replied
    Dale

    Duh - I do not understand sorry

    If my string was 'a space a space a space a', then how many a's would tally count?

    Leave a comment:


  • Dale Yarker
    replied
    To count the number of letter 'a' the match string would be "a".
    To count the number of word 'a' the match string would be " a ".
    In " ice ice " the space between the ice's is part of the first match, therefore the second ice does not have a leading space so does not match. (ref post 1 code)
    TALLY works as advertised, just not what Gary "wanted", so title of this thread.

    Cheers,

    Leave a comment:


  • Kerry Farmer
    replied
    So if I wanted to count the number of 'a's in a string, it would not work unless each 'a' is at least two spaces away from the next 'a'????

    Good heavens. That is definitely a weakness - bordering on a bug

    I guess you could REMOVE$ everything except 'a' and then use a LEN?? But that might be slow??

    Leave a comment:

Working...
X