Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Tri state string compare? (Solved! see update2)

by BrowserUk (Patriarch)
on Dec 13, 2015 at 18:22 UTC ( [id://1150172]=perlquestion: print w/replies, xml ) Need Help??

BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:

I have two strings to compare.

  1. String 1 consists of a mix of 3 characters, a, b & c. Eg. AABCBAABCCCCAB
  2. String 2 consists of a mix pf 2 characters; a & b.Eg. AABABAABABABAB

I need to determine if string 2 contains As everywhere there is an A in string 1; and Bs wherever string 1 contains Bs. I don't care what string 2 contains where string 1 contains Cs.

All I need is a boolean result whether string 2 'matches' string 1. (The above example is a 'match'.)

If it helps, the choice of the 3 characters used is open to change.

The strings can be quite long and there are lots of string 2s to be compared against each string 1; so I'd rather avoid a byte by byte (at the Perl level) comparison.

I think it ought to be possible to get my boolean using some combination of byte-wise boolean string ops; but I haven't hit on which?

Update: The above two samples match because:

AABCBAABCCCCAB AABABAABABABAB AAB BAAB AB ## I don't care what's in string 2 where there is a C +in string 1.

Update2: Solution

Solved it with:

$ab = "AABABAABABABAB";; $abmatch = "AABABAABABABAB";; print +(( $abc & $abmatch ) eq $abmatch) ? 'yes' : 'no';; yes $abnomatch = "ABBABAABABABAB";; print +(( $abc & $abnomatch ) eq $abmatch) ? 'yes' : 'no';; no

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re: Tri state string compare?
by hdb (Monsignor) on Dec 13, 2015 at 18:51 UTC

    Replace all "don't care characters" with . and you have a regex that does the job.

    use strict; use warnings; my $abc = "AABCBAABCCCCAB"; my $ab = "AABABAABABABAB"; $abc =~ s/[^ab]/./gi; print "They match!\n" if $ab =~ /^$abc$/i;

    If you want to use logical operators the following works as well

    print "They match!\n" unless ($abc ^ $ab) =~ /\x{3}/;

      Just a variant that takes the rules of the original question a little more literally and strictly ...

      use strict; use warnings; my $abc = "AABCBAABCCCCAB"; my $ab = "AABABAABABABAB"; $abc =~ s/C/[AB]/g; $abc = qr/^$abc$/; print "They match!\n" if $ab =~ $abc;
      Ron
Re: Tri state string compare? (Solved! see update2)
by GrandFather (Saint) on Dec 13, 2015 at 21:17 UTC

    There's something missing in that solution, or I don't understand it. I'd have expected something like:

    use strict; use warnings; my $abc = 'AABCBAABCCCCAB'; my $yes = 'AABABAABABABAB'; my $no1 = 'ABBABAABABABAB'; my $no2 = 'ABBABAABABAB'; $abc =~ tr/AB/\0/c; print +(($abc & $_) eq $abc) ? "$_: yes\n" : "$_: no\n" for $yes, $no1 +, $no2;

    Prints:

    AABABAABABABAB: yes ABBABAABABABAB: no ABBABAABABAB: no

    The test fails if you change all the Bs to Es of course.

    Premature optimization is the root of all job security
      There's something missing in that solution, or I don't understand it

      Does the fact that I know all my strings will be equal length explain things?

      Here's my test code:

      #! perl -slw use strict; my $pat = 'AAAAAAABCCCCCCCCABAAAAAAA'; my @set = ( 'AAAAAAABAAABABBBABAAAAAAA', 'AAAAAAABAAABBABBABAAAAAAA', 'AAAAAAABAAABBBABABAAAAAAA', 'AAAAAAABBAAABABBABAAAAAAA', 'AAAAAAABBAAABBABABAAAAAAA', 'AAAAAAABBBAAABABABAAAAAAA', 'ABAAAAABAAABABBBABAAAAAAA', 'AAAAAAAAAAABBABBABAAAAAAA', 'AAAAAAABAAABBBABAABAAAAAA', 'AAAAAAABBAAABABBABAAAAAAA', 'AAAAABABBAAABBABAAAAAAAAA', 'AAAAAAABBBAAABABAAAAAAAAA', ); for my $test ( @set ) { printf "$pat\n$test\n%s %s\n\n", $pat & $test, ( $pat & $test ) eq + $test ? 'OK' : 'NO'; } __END__ C:\test>junk77 AAAAAAABCCCCCCCCABAAAAAAA AAAAAAABAAABABBBABAAAAAAA AAAAAAABAAABABBBABAAAAAAA OK AAAAAAABCCCCCCCCABAAAAAAA AAAAAAABAAABBABBABAAAAAAA AAAAAAABAAABBABBABAAAAAAA OK AAAAAAABCCCCCCCCABAAAAAAA AAAAAAABAAABBBABABAAAAAAA AAAAAAABAAABBBABABAAAAAAA OK AAAAAAABCCCCCCCCABAAAAAAA AAAAAAABBAAABABBABAAAAAAA AAAAAAABBAAABABBABAAAAAAA OK AAAAAAABCCCCCCCCABAAAAAAA AAAAAAABBAAABBABABAAAAAAA AAAAAAABBAAABBABABAAAAAAA OK AAAAAAABCCCCCCCCABAAAAAAA AAAAAAABBBAAABABABAAAAAAA AAAAAAABBBAAABABABAAAAAAA OK AAAAAAABCCCCCCCCABAAAAAAA ABAAAAABAAABABBBABAAAAAAA A@AAAAABAAABABBBABAAAAAAA NO AAAAAAABCCCCCCCCABAAAAAAA AAAAAAAAAAABBABBABAAAAAAA AAAAAAA@AAABBABBABAAAAAAA NO AAAAAAABCCCCCCCCABAAAAAAA AAAAAAABAAABBBABAABAAAAAA AAAAAAABAAABBBABA@@AAAAAA NO AAAAAAABCCCCCCCCABAAAAAAA AAAAAAABBAAABABBABAAAAAAA AAAAAAABBAAABABBABAAAAAAA OK AAAAAAABCCCCCCCCABAAAAAAA AAAAABABBAAABBABAAAAAAAAA AAAAA@ABBAAABBABA@AAAAAAA NO AAAAAAABCCCCCCCCABAAAAAAA AAAAAAABBBAAABABAAAAAAAAA AAAAAAABBBAAABABA@AAAAAAA NO

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice.
      A bit more digestible explanation (imo):
      $ perl -e 'printf "$_ => %b\n", ord($_) for qw( A B C @ )' A => 1000001 B => 1000010 C => 1000011 @ => 1000000
      so, "A" & "B" (0b1000001 & 0b1000010) yields "@" (0b1000000), "A" & "C" (0b1000001 & 0b1000011) yields "A" (0b1000001), "B" & "C" yields "B".

      So, for example:

      "ABC" & "ABA" => "ABA" "ABB" & "ABA" => "AB@" "ABC" & "AB" => "AB" # perlop: "the & op acts as though the longer operand # were truncated to the length of the shorter" # so the strings don't have to be equal length # for that to work

        Yes, I was being thick. The penny dropped 30s after seeing BUK's reply.

        Premature optimization is the root of all job security
        A bit more digestible explanation (imo):

        IMO also :)


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice.
        so the strings don't have to be equal length for that to work
        oops! of course, that would work only if the test string shorter that the tested string
Re: Tri state string compare?
by Tux (Canon) on Dec 13, 2015 at 18:28 UTC

    First thing that comes to mind

    my $abc = "AABCBAABCCCCAB"; my $ab = "AABABAABABABAB"; (my $abca = $abc) =~ y/C//d; $abca eq $ab and say "THAY MATCH!";

    Enjoy, Have FUN! H.Merijn

      Que?

      C:\test>p1 $abc = "AABCBAABCCCCAB";; $ab = "AABABAABABABAB";; ( $abca = $abc) =~ y/C//d;; $abca eq $ab and say "THAY MATCH!";; print $abca;; AABBAABAB

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Which is exactly what I would expect. The y/C/d command removes all C occurrences from the modified string, which is a copy of the original string. As your examples did not match in you OP, they also do not in my code snippet.

        But you added an explanation to the OP later, so I interpreted the question other than you meant to ask.


        Enjoy, Have FUN! H.Merijn

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1150172]
Approved by hdb
Front-paged by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2024-04-24 11:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found