Comparing string and number of matching characters

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

shivam0101
Forum Contributor
Posts: 197
Joined: Sat Jun 09, 2007 12:09 am

Comparing string and number of matching characters

Post by shivam0101 »

How to get the number of characters occuring in a string.

Code: Select all

str1='abcdefg';

1. str2='123abcde';
2. str2='1zyzedfd';
3. str2='1bcdefcd';
4. str2='1cccccdd';
i should get,

5
3
6
7
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post by onion2k »

You need to explain the problem better. I don't see how you're getting those numbers.
shivam0101
Forum Contributor
Posts: 197
Joined: Sat Jun 09, 2007 12:09 am

Post by shivam0101 »

str1 is the answer fed by admin.

str2's are the guess answer fed by clients.

I have to find how many characters are matching
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post by onion2k »

The numbers you say you should get don't make any sense. There's no logic to them that I can see. What do you mean by "how many characters are matching"? Take the second one as an example:

Code: Select all

$str1='abcdefg';
$str2='1zyzedfd';
You say that should return 3. Why? If it's because e, d, and f are in $str1 then surely the forth example should return 2 not 7.

Code: Select all

$str1='abcdefg';
$str2='1cccccdd';
Why does that return 7?

Unless you can explain the logic there's no way anyone can help you write any code.
User avatar
Stryks
Forum Regular
Posts: 746
Joined: Wed Jan 14, 2004 5:06 pm

Post by Stryks »

Assuming you want only 1 match to each letter in the original in no particular order.

Code: Select all

<?php
	function getDifference($target, $attempt) {
		$matches = 0;

		$arrTarget = str_split($target);
		foreach($arrTarget as $find) if(strstr($attempt, $find)) $matches++;
		return $matches; 	
	}

	
	$str1='abcdefg';

	$str2='123abcde';
	$str3='1zyzedfd';
	$str4='1bcdefcd';
	$str5='1cccccdd';
	
	echo "Matching $str1 to $str2 - Found " . getDifference($str1, $str2) . "<br>";
	echo "Matching $str1 to $str3 - Found " . getDifference($str1, $str3) . "<br>";
	echo "Matching $str1 to $str4 - Found " . getDifference($str1, $str4) . "<br>";
	echo "Matching $str1 to $str5 - Found " . getDifference($str1, $str5) . "<br>";
	
?>
Alternately, matching them multiple times ... maybe the following.

Code: Select all

<?php
	function getDifference ($target, $attempt) {
		$matches = 0;

		$arrAttempt = str_split($attempt);
		foreach($arrAttempt as $find) if(strstr($target, $find)) $matches++;
		return $matches; 	
	}
?>
But yeah ... your example doesnt say which (in fact it says both).

There is probably a better ways to do this that will (as usual) maky my way look stupid ... but it's just what popped into my mind.

Also, looking back on it, it shouldn't really be called getDifference either. Maybe findMatches or findSame.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Code: Select all

$numOfMatches = preg_match_all('#[' . preg_quote($str1, '#') . ']#', $str2);
User avatar
Stryks
Forum Regular
Posts: 746
Joined: Wed Jan 14, 2004 5:06 pm

Post by Stryks »

Yup ... nice one.

Now I remember why I don't usually post responses to other peoples posts.
shivam0101
Forum Contributor
Posts: 197
Joined: Sat Jun 09, 2007 12:09 am

Post by shivam0101 »

Code: Select all

foreach($guess_numbers as $guess)
   {
       $str_split=str_split($guess);
	   $characters='';
	   $matches=0;
	   foreach($str_split as $str)
	   {
	      if(strstr($winning_number, $str))
		  {
		    $matches++;
		  	$characters.="<b>$str</b>";
		  }
		  else
		  {
		  	$characters.="$str";
		  }
       }
	   
	   if()
	   echo "NUMBER OF MATCHES $matches <br/>
	       $characters <br/>";
I am trying to display like,

Numbers matching 7 characters are:
all guesses which matches 7 characters

Numbers matching 6 characters are:
all guesses which matches 6 characters

......till matching 1 characters
User avatar
Stryks
Forum Regular
Posts: 746
Joined: Wed Jan 14, 2004 5:06 pm

Post by Stryks »

I'm still not really sure what you're trying to do.

You have an array of guesses from somewhere. You want to compare them to the original, and see how close it came to having all the elements. However, you aren't worried if they are in the right order, or if entries are duplicated.

I don't know how that would be useful to you, especially if you don't penalize incorrect guesses as well. I mean, you could try to match a master string of "test" against "abc...xyz" and it would in theory pass.

As for your code, because I can't really tell what you are trying to do, it's hard to say if you're doing it right.

I would advise against naming the result of str_split $str_split though. It's confusing and doesn't really tell you what it' really is.

For the sake of taking a stab with the methodology I don't quite get ....

Code: Select all

        function findMatches ($target, $attempt) {
                $matches = array();

                $arrAttempt = str_split($attempt);
                foreach($arrAttempt as $find) if(strstr($target, $find)) $matches[] = find;
                return $matches;        
        }

        foreach($guess_numbers as $guess) {
        	$found = findMatches($winning_number, $guess);
         	if(is_array($found)) {
         		echo "NUMBER OF MATCHES " . count($found) . "<br/>";
         		echo implode(", ", $found); 
			} else echo "No Matches Found";
		}
(untested)

Have a think about what it is you are expecing to accomplish and try and explain it with some sample data. Maybe theres a better approach.

[edit] Hehehe ... All I did was rewrite what you had I think. Doesn't help you much I guess .... I'll think more on it.
User avatar
Stryks
Forum Regular
Posts: 746
Joined: Wed Jan 14, 2004 5:06 pm

Post by Stryks »

Ok ... maybe ...

Code: Select all

        $match_list = array();
        
        foreach($guess_numbers as $guess) {
        	$found = findMatches($winning_number, $guess);
         	if(is_array($found)) {
         		echo "NUMBER OF MATCHES " . count($found) . "<br/>";
         		echo implode(", ", $found);
         		$match_list[count($found)][] = $guess; 
			} else echo "No Matches Found";
		}
		
		
		echo "<br/><br/>";
		foreach($match_list as $match_num=>$matches) {
			echo "Numbers matching $match_num characters are:<br/>";
			foreach($matches as $match) echo $match;
		}
And that's very very untested.

[edit] My indenting is showing up screwy ... all the braces do match and close all the calls shown.
shivam0101
Forum Contributor
Posts: 197
Joined: Sat Jun 09, 2007 12:09 am

Post by shivam0101 »

Stryks,

Your code is working fine,
How to make it appear in descending or ascending order? like,

matches 7
ABCDEFG
ABCDEFG

matches 6
ABCDEFX
ABCDEFX

..............

till
matches 0
1234567
User avatar
Stryks
Forum Regular
Posts: 746
Joined: Wed Jan 14, 2004 5:06 pm

Post by Stryks »

krsort() should help with that.

Just use it on $match_list before the display loop.

Hope that helps
shivam0101
Forum Contributor
Posts: 197
Joined: Sat Jun 09, 2007 12:09 am

Post by shivam0101 »

Code: Select all

$result_details.="<table width='40'></table>";  
	    $match_list=krsort($match_list);
	   foreach($match_list as $match_num=>$matches) { 
	   $result_details.="<tr><td>Numbers matching $match_num characters are:</td></tr>"; 
	   foreach($matches as $match) $result_details.="<tr><td>$match</td></tr>"; 
	   }
	  $result_details.="</table>";
Invalid argument supplied for foreach()
Last edited by shivam0101 on Thu Oct 04, 2007 12:49 am, edited 1 time in total.
User avatar
Stryks
Forum Regular
Posts: 746
Joined: Wed Jan 14, 2004 5:06 pm

Post by Stryks »

Have a quick re-read of the manual page I posted previously.

The return value for ksort() and krsort() is boolean, not a modified version of the array. They act directly on the array, so they can just be called and the original array used.

It's all in the manual description and example.

To list largest number of matches through to least, I believe krsort() is going to be what you need though.

Let us know how you go.
shivam0101
Forum Contributor
Posts: 197
Joined: Sat Jun 09, 2007 12:09 am

Post by shivam0101 »

That's great. Its working fine.

Thanks Stryks.

Code: Select all

krsort($match_list);      
                   $result_details.="<table width='40'></table>";  
	   foreach($match_list as $match_num=>$matches) { 
	   
	   $result_details.="<tr><td>Numbers matching $match_num characters are:</td></tr>"; 
	   foreach($matches as $match) $result_details.="<tr><td>$match</td></tr>"; 
	   }
	  $result_details.="</table>";
Post Reply