Page 1 of 2

Comparing string and number of matching characters

Posted: Fri Sep 28, 2007 7:59 am
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

Posted: Fri Sep 28, 2007 8:04 am
by onion2k
You need to explain the problem better. I don't see how you're getting those numbers.

Posted: Fri Sep 28, 2007 8:17 am
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

Posted: Fri Sep 28, 2007 8:29 am
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.

Posted: Fri Sep 28, 2007 8:51 am
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.

Posted: Fri Sep 28, 2007 9:59 am
by feyd

Code: Select all

$numOfMatches = preg_match_all('#[' . preg_quote($str1, '#') . ']#', $str2);

Posted: Fri Sep 28, 2007 9:27 pm
by Stryks
Yup ... nice one.

Now I remember why I don't usually post responses to other peoples posts.

Posted: Tue Oct 02, 2007 4:44 am
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

Posted: Tue Oct 02, 2007 7:13 am
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.

Posted: Tue Oct 02, 2007 7:27 am
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.

Posted: Wed Oct 03, 2007 11:49 pm
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

Posted: Wed Oct 03, 2007 11:58 pm
by Stryks
krsort() should help with that.

Just use it on $match_list before the display loop.

Hope that helps

Posted: Thu Oct 04, 2007 12:36 am
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()

Posted: Thu Oct 04, 2007 12:44 am
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.

Posted: Thu Oct 04, 2007 1:00 am
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>";