Soundex: Difference between revisions

2,951 bytes added ,  13 years ago
m (→‎{{header|Tcl}}: use better template)
Line 136:
*******************************************************************************</lang>
--[[User:Clippersolutions|Clippersolutions]] 23:14, 4 November 2010 (UTC)--[[User:Clippersolutions|Clippersolutions]] 23:14, 4 November 2010 (UTC)
 
=={{header|D}}==
This D implementation is long because it contains a ddoc text, design by contract (a long post-condition), sanity asserts, unittests and comments. A quite shorter version may be written that loses the safety net that's necessary in serious coding.
 
This version uses dynamic heap allocations in some places (replace, toupper, several string join) to allow a higher level style of coding, but this function may also be written to perform zero heap allocations. It may even return a char[4] by value, or use a given buffer like the C version.
 
(This function is not pure because the standard library Phobos of DMD 2.050 is not yet pure-corrected, so std.string.replace() is not pure yet).
<lang d>import std.string: toupper, replace;
import std.ctype: isupper;
 
/**
Soundex is a phonetic algorithm for indexing names by
sound, as pronounced in English.
See: http://en.wikipedia.org/wiki/Soundex
*/
/*pure*/ string soundex(const string name)
out(result) { // postcondition
assert(result.length == 4);
assert(result[0] == '0' || isupper(result[0]));
 
if (name.length == 0)
assert(result == "0000");
 
// this is too much fiddly
int charCount = 0;
foreach (dchar c; name)
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
charCount++;
assert((charCount == 0) == (result == "0000"));
} body {
// digits holds the soundex values for the alphabet
enum digits = "01230120022455012623010202";
string firstChar, result;
 
// translate alpha chars in name to soundex digits
foreach (dchar c; name.toupper()) {
if (c >= 'A' && c <= 'Z') {
if (!firstChar.length)
firstChar ~= c; // remember first letter
char d = digits[c - 'A'];
// duplicate consecutive soundex digits are skipped
if (!result.length || d != result[$ - 1])
result ~= d;
}
}
 
// return 000 if the name is
if (!firstChar.length)
return "0000";
 
// replace first digit with first alpha character
assert(result.length > 0);
result = firstChar ~ result[1 .. $];
 
// remove all 0s from the soundex code
result = result.replace("0", "");
 
// return soundex code padded to 4 zeros
return (result ~ "0000")[0 .. 4];
}
 
 
unittest { // tests of soundex()
auto tests = [["", "0000"], ["12346", "0000"], ["he", "H000"],
["soundex", "S532"], ["example", "E251"],
["ciondecks", "C532"], ["ekzampul", "E251"],
["résumé", "R250"], ["Robert", "R163"],
["Rupert", "R163"], ["Rubin", "R150"],
["Ashcraft", "A226"], ["Ashcroft", "A226"]];
foreach (pair; tests)
assert(soundex(pair[0]) == pair[1]);
}
 
void main() {}</lang>
 
=={{header|Forth}}==
Anonymous user