note 36900 added to function.levenshtein
| From: | genialbrainmachine at dot IHATESPAM dot tiscali dot it | Date: | Sun, 26 Oct 2003 16:55:37 +0000 |
| Subject: | note 36900 added to function.levenshtein | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-59331@lists.php.net to get a copy of this message | ||
I wrote this function to have an "intelligent" comparison between data to be written in a
DB
and already existent data. Not ony calculating distances but also balancing distances for
each field.
<?php
/*
This function calculate a balanced percentage distance between an array of strings
"$record" and a compared array "$compared", balanced through an array of
weights "$weight". The three arrays must have the same indices.
For an unbalanced distance, set all weights to 1.
The used formula is:
percentage distance = sum(field_levenshtein_distance * field_weight) / sum(record_field_length *
field_weight) * 100
*/
function search_similar($record, $weights, $compared, $precision=2) {
$field_names = array_keys($record);
# "Weighted length" of $record and "weighted distance".
foreach ($field_names as $field_key) {
$record_weight += strlen($record[$field_key]) * $weights[$field_key];
$weighted_distance += levenshtein($record[$field_key],$compared[$field_key]) *
$weights[$field_key];
}
# Building the result..
if ($record_weight) {
return round(($weighted_distance / $record_weight * 100),$precision);
} elseif ((strlen(implode("",$record)) == 0) &&
(strlen(implode("",$compared)) == 0)) { // empty records
return round(0,$precision);
} elseif (array_sum($weights) == 0) { // all weights == 0
return round(0,$precision);
} else {
return false;
}
/*
Be very careful distinguising 0 result and false result.
The function results 0 ('0.00' if $precision is 2 and so on) if:
- $record and $compared are equals (even if $record and $compared are empty);
- all weights are 0 (the meaning could be "no care about any field").
Conversely, the function results false if $record is empty, but the weights
are not all 0 and $compared is not empty. That cause a "division by 0" error.
I wrote this kind of check:
if ($rel_dist = search_similar(...)) {
print $rel_dist;
} elseif ($rel_dist == "0.00") { // supposing that $precision is 2
print $rel_dist;
} else {
print "infinite";
}
*/
}
?>
----
Manual Page -- http://www.php.net/manual/en/function.levenshtein.php
Edit -- http://master.php.net/manage/user-notes.php?action=edit+36900
Delete -- http://master.php.net/manage/user-notes.php?action=delete+36900&report=yes
Reject -- http://master.php.net/manage/user-notes.php?action=reject+36900&report=yes
Search -- http://master.php.net/manage/user-notes.php