Jimmy's Blog Jimmy Ruska's Blog
PHP Get Character Frequency Posted on Wednesday, October 15 2008
Learn to Play Songs by Ear: Ear Training

Someone on youtube asked me to correct their php code. They had to make a function to display the keyword frequency of each character. I think such a function is a good example of how writing things dynamically can help.

Beginners Logic

We loop through each character in the string and compare it to all possibilities creating a counter for each possible character. The person asking made just three counters for the characters a,x and z, had he done so for all alphabetic characters this code would be substantially longer.


<?
$string='Count the character frequency of this string';

$count_chars = explode(' ', $string);
$a = $x = $z = $other = 0;
for($i = 0; $i < sizeof($count_chars); $i++)
{
switch($count_chars[$i])
{
case "a": $a++;
break;

case "x": $x++;
break;

case "z": $z++;
break;

default: $other++;
break;
}
}
print "Instances of <br>a = $a<br>x = $x<br>z = $z<br>";
?>

Advanced Logic

Just for amusement I wrote it as short as could be possible, where $s is the string with characters to count. This code does the same thing as above except it counts all the characters dynamically, not just 3. Sorting is also easily possible.


<?foreach(preg_split('//',$s='Foo',-1,1)as$v)$c[$v]++;?>

Note that I'm using really flexible error handling so it doesn't warn me if a var is undefined. I'll give a more compatible code below. If I wanted to dynamically create the var per character I could use $$v++; instead of $c[$v]++, but then again some characters are against variable naming rules. If we wanted to use only letter frequency could do an eregi test for a-z and continue if it doesn't match.

Preg_Split breaks apart the string into an array of characters and the foreach function loops through each item in the array as variable. The -1 indicates I don't want it to stop after it found an x quantity of matches. The 1 flag indicates to avoid capturing null bytes. We then add the character as an array key inside the $c array and increment it's value. Incrementing an undefined var defaults it to 0 first.

All the work was done in one line. If our task is to make a function that returns an array we could stop with the first line. All the characters in the $s string have been counted and are in the $c array. Now we just have to loop through the values and echo them.


foreach($c as$l=>$f)echo"$l:$f\n";

Again, the array keys are the characters and the value is the quantities.

More Compatibly but Less Tiny

Here it's the same but we're checking if the array value exists before we increment to avoid possible errors.


<?
$c=Array();
foreach(preg_split('//',$string='Stuff',-1,1)as$v)($c[$v])?$c[$v]++:$c[$v]=1;
foreach($c as$letter=>$freq)echo"$letter: $freq (0x".dechex(ord($letter)).")\n";
?>

If the char is in the array, increment its counter, if not, add it to the array and set its counter to 1. I also added a little bit that lets you check the ASCII hex of each char. ord() gets the decimal val of a certain char and dechex makes it base 16.

Making it into a function

If I input the string 'test' into getCharFreq it will return an array with the characters as keys and the frequencies as values. I added $chr parameter in case someone is only looking to see how many times one char appears in the string without the inefficiency of having an array full of counters. For example setting it to 't' checks how many times 't' occurs in test, and will return 2.


<?
function getCharFreq($str,$chr=false){
$c=Array();
if ($chr!==false) return substr_count($str, $chr);
foreach(preg_split('//',$str,-1,1)as$v)($c[$v])?$c[$v]++ :$c[$v]=1;
return $c;
}
var_dump(getCharFreq('test'));
var_dump(getCharFreq('test','t'));
?>



Tags: php get character frequency, char frequency of a string, string frequency of bytes, foreach applied, character loop counter, counting amount of characters text, each letter, each number, item, element



stumble digg delicious


Blog by Jimmy Ruska
Add me: Youtube, Twitter, Facebook, MySpace

Share:

More OMFG-Good Links

See all Posts in the Funny Pictures category.
Download mp3s faster than limewire using google.
I've made 100+ free video tutorials.
See the best of the internet today on one page.