Jaro similarity: Difference between revisions
Add C# implementation
SqrtNegInf (talk | contribs) m (→{{header|Raku}}: a little more idiomatic, two more tests) |
(Add C# implementation) |
||
(32 intermediate revisions by 21 users not shown) | |||
Line 1:
{{task}}
The Jaro distance is a measure of edit distance between two strings; its inverse, called the ''Jaro similarity'', is a measure of two strings' similarity: the higher the value, the more similar the strings are. The score is normalized such that '''0''' equates to no similarities and '''1''' is an exact match.
;;Definition
The Jaro
: <math>d_j = \left\{
Line 24 ⟶ 20:
Two characters from <math>s_1</math> and <math>s_2</math> respectively, are considered ''matching'' only if they are the same and not farther apart than <math>\left\lfloor\frac{\max(|s_1|,|s_2|)}{2}\right\rfloor-1</math> characters.
Each character of <math>s_1</math> is compared with all its matching characters in <math>s_2</math>. Each difference in position is half a ''transposition''; that is, the number of transpositions is half the number of characters which are common to the two strings but occupy different positions in each one.
Line 50 ⟶ 42:
;Task
Implement the Jaro
* ("MARTHA", "MARHTA")
Line 60 ⟶ 52:
* [[wp:Jaro-Winkler_distance|Jaro–Winkler distance]] on Wikipedia.
<br><br>
=={{header|11l}}==
{{trans|Python}}
<syntaxhighlight lang="11l">F jaro(s, t)
V s_len = s.len
V t_len = t.len
I s_len == 0 & t_len == 0
R 1.0
V match_distance = (max(s_len, t_len) I/ 2) - 1
V s_matches = [0B] * s_len
V t_matches = [0B] * t_len
V matches = 0
V transpositions = 0
L(i) 0 .< s_len
V start = max(0, i - match_distance)
V end = min(i + match_distance + 1, t_len)
L(j) start .< end
I t_matches[j]
L.continue
I s[i] != t[j]
L.continue
s_matches[i] = 1B
t_matches[j] = 1B
matches++
L.break
I matches == 0
R 0.0
V k = 0
L(i) 0 .< s_len
I !s_matches[i]
L.continue
L !t_matches[k]
k++
I s[i] != t[k]
transpositions++
k++
R ((Float(matches) / s_len) +
(Float(matches) / t_len) +
((matches - transpositions / 2) / matches)) / 3
L(s, t) [(‘MARTHA’, ‘MARHTA’),
(‘DIXON’, ‘DICKSONX’),
(‘JELLYFISH’, ‘SMELLYFISH’)]
print(‘jaro('#.', '#.') = #.10’.format(s, t, jaro(s, t)))</syntaxhighlight>
{{out}}
<pre>
jaro('MARTHA', 'MARHTA') = 0.9444444444
jaro('DIXON', 'DICKSONX') = 0.7666666667
jaro('JELLYFISH', 'SMELLYFISH') = 0.8962962963
</pre>
=={{header|Action!}}==
<
DEFINE STRING="CHAR ARRAY" ; sys.act
DEFINE ASCII_SpaceBar="32"
Line 93 ⟶ 144:
IF Max<(I-L) THEN Max=I-L FI
Min=S2
IF Min>(I+L-1) THEN Min=I+L-1 FI
FOR K=Max TO Min DO
IF str1(I)=str2(K) THEN
Line 132 ⟶ 183:
PUTE()
SCopy(Word_1,"
PrintF("%S - %S%E",Word_1,Word_2)
result=JaroDistance(Word_1,Word_2)
PrintF("Jaro Distance=%U%E%E",result)
SCopy(Word_1,"
PrintF("%S - %S%E",Word_1,Word_2)
result=JaroDistance(Word_1,Word_2)
Line 147 ⟶ 198:
PrintF("Jaro Distance=%U%E%E",result)
RETURN
</syntaxhighlight>
{{out}}
<pre>MARTHA, MARHTA: 94
Line 155 ⟶ 206:
=={{header|Ada}}==
<
procedure Jaro_Distances is
Line 245 ⟶ 296:
Show_Jaro ("JELLYFISH", "SMELLYFISH");
Show_Jaro (S1 (3 .. 8), S1 (13 .. 18));
end Jaro_Distances;</
{{out}}
Line 255 ⟶ 306:
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
/* ARM assembly Raspberry PI */
Line 609 ⟶ 660:
</syntaxhighlight>
=={{header|Arturo}}==
<syntaxhighlight lang="rebol">loop [
["MARTHA" "MARHTA"]
["DIXON" "DICKSONX"]
["JELLYFISH" "SMELLYFISH"]
] 'pair ->
print [pair "-> Jaro similarity:" round.to: 3 jaro first pair last pair]</syntaxhighlight>
{{out}}
<pre>[MARTHA MARHTA] -> Jaro similarity: 0.944
[DIXON DICKSONX] -> Jaro similarity: 0.767
[JELLYFISH SMELLYFISH] -> Jaro similarity: 0.896</pre>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f JARO_DISTANCE.AWK
BEGIN {
Line 665 ⟶ 731:
function max(x,y) { return((x > y) ? x : y) }
function min(x,y) { return((x < y) ? x : y) }
</syntaxhighlight>
{{out}}
<pre>
Line 673 ⟶ 739:
0.8962963 'JELLYFISH' 'SMELLYFISH'
</pre>
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<syntaxhighlight lang="bbcbasic"> PRINT "Jaro similarity between the two strings:"
PROCDescribeJaro("MARTHA", "MARHTA")
PROCDescribeJaro("DIXON", "DICKSONX")
PROCDescribeJaro("JELLYFISH", "SMELLYFISH")
PROCDescribeJaro("DWAYNE", "DUANE")
PROCDescribeJaro("a", "b")
PROCDescribeJaro("", "")
END
DEF FNMax(a, b)=(a + b + ABS(a - b)) / 2
DEF FNMin(a, b)=(a + b - ABS(a - b)) / 2
DEF PROCDescribeJaro(word1$, word2$)
LOCAL d%, i%, j%, k%, l1%, l2%, m%, t%
PRINT " '" word1$ "' and '" word2$ "'" TAB(30) "= ";
IF word1$ == "" IF word2$ == "" PRINT;1 : ENDPROC
l1%=LENword1$
l2%=LENword2$
IF l1% < l2% SWAP l1%, l2% SWAP word1$, word2$
d%=l1% / 2 - 1
j%=1
FOR i%=1 TO l2%
IF MID$(word2$, i%, 1) == MID$(word1$, j%, 1) THEN
m%+=1
MID$(word1$, j%)=" "
ELSE
FOR k%=FNMax(1, i% - d%) TO FNMin(l1%, i% + d%)
IF MID$(word2$, i%, 1) == MID$(word1$, k%, 1) THEN
t%+=1
m%+=1
MID$(word1$, k%)=" "
IF k% > j% j%=k%
ENDIF
NEXT
ENDIF
j%+=1
NEXT
IF m% == 0 THEN
PRINT;0
ELSE
PRINT;(m% / l2% + m% / l1% + ((m% - (t% >> 1)) / m%)) / 3
ENDIF
ENDPROC</syntaxhighlight>
{{out}}
<pre>Jaro similarity between the two strings:
'MARTHA' and 'MARHTA' = 0.944444444
'DIXON' and 'DICKSONX' = 0.766666667
'JELLYFISH' and 'SMELLYFISH' = 0.896296296
'DWAYNE' and 'DUANE' = 0.822222222
'a' and 'b' = 0
'' and '' = 1</pre>
=={{header|C}}==
<
#include <string.h>
#include <ctype.h>
Line 764 ⟶ 886:
printf("%f\n", jaro("DIXON", "DICKSONX"));
printf("%f\n", jaro("JELLYFISH", "SMELLYFISH"));
}</
{{out}}
<pre>
Line 770 ⟶ 892:
0.766667
0.896296
</pre>
=={{header|C#}}==
{{trans|Java}}
<syntaxhighlight lang="C#">
using System;
public class JaroDistance {
public static double Jaro(string s, string t) {
int s_len = s.Length;
int t_len = t.Length;
if (s_len == 0 && t_len == 0) return 1;
int match_distance = Math.Max(s_len, t_len) / 2 - 1;
bool[] s_matches = new bool[s_len];
bool[] t_matches = new bool[t_len];
int matches = 0;
int transpositions = 0;
for (int i = 0; i < s_len; i++) {
int start = Math.Max(0, i - match_distance);
int end = Math.Min(i + match_distance + 1, t_len);
for (int j = start; j < end; j++) {
if (t_matches[j]) continue;
if (s[i] != t[j]) continue;
s_matches[i] = true;
t_matches[j] = true;
matches++;
break;
}
}
if (matches == 0) return 0;
int k = 0;
for (int i = 0; i < s_len; i++) {
if (!s_matches[i]) continue;
while (!t_matches[k]) k++;
if (s[i] != t[k]) transpositions++;
k++;
}
return (((double)matches / s_len) +
((double)matches / t_len) +
(((double)matches - transpositions / 2.0) / matches)) / 3.0;
}
public static void Main(string[] args) {
Console.WriteLine(Jaro("MARTHA", "MARHTA"));
Console.WriteLine(Jaro("DIXON", "DICKSONX"));
Console.WriteLine(Jaro("JELLYFISH", "SMELLYFISH"));
}
}
</syntaxhighlight>
{{out}}
<pre>
0.944444444444445
0.766666666666667
0.896296296296296
</pre>
=={{header|C++}}==
{{trans|C}}
<
#include <iostream>
#include <string>
Line 822 ⟶ 1,008:
cout << jaro("JELLYFISH", "SMELLYFISH") << endl;
return 0;
}</
=={{header|Clojure}}==
<
(ns test-project-intellij.core
(:gen-class))
Line 907 ⟶ 1,093:
(println (jaro "DIXON" "DICKSONX"))
(println (jaro "JELLYFISH" "SMELLYFISH"))
</syntaxhighlight>
{{out}}
<pre>
Line 914 ⟶ 1,100:
0.8962963
</pre>
=={{header|CLU}}==
{{trans|C}}
<syntaxhighlight lang="clu">max = proc [T: type] (a, b: T) returns (T)
where T has lt: proctype (T,T) returns (bool)
if a<b then return(b) else return(a) end
end max
min = proc [T: type] (a, b: T) returns (T)
where T has lt: proctype (T,T) returns (bool)
if a<b then return(a) else return(b) end
end min
jaro = proc (s1, s2: string) returns (real)
s1_len: int := string$size(s1)
s2_len: int := string$size(s2)
if s1_len = 0 & s2_len = 0 then return(1.0)
elseif s1_len = 0 | s2_len = 0 then return(0.0)
end
dist: int := max[int](s1_len, s2_len)/2 - 1
s1_match: array[bool] := array[bool]$fill(1,s1_len,false)
s2_match: array[bool] := array[bool]$fill(1,s2_len,false)
matches: real := 0.0
transpositions: real := 0.0
for i: int in int$from_to(1, s1_len) do
start: int := max[int](1, i-dist)
end_: int := min[int](i+dist, s2_len)
for k: int in int$from_to(start, end_) do
if s2_match[k] then continue end
if s1[i] ~= s2[k] then continue end
s1_match[i] := true
s2_match[k] := true
matches := matches + 1.0
break
end
end
if matches=0.0 then return(0.0) end
k: int := 1
for i: int in int$from_to(1, s1_len) do
if ~s1_match[i] then continue end
while ~s2_match[k] do k := k + 1 end
if s1[i] ~= s2[k] then
transpositions := transpositions + 1.0
end
k := k+1
end
transpositions := transpositions / 2.0
return( ((matches / real$i2r(s1_len)) +
(matches / real$i2r(s2_len)) +
((matches - transpositions) / matches)) / 3.0)
end jaro
start_up = proc ()
po: stream := stream$primary_output()
stream$putl(po, f_form(jaro("MARTHA", "MARHTA"), 1, 6))
stream$putl(po, f_form(jaro("DIXON", "DICKSONX"), 1, 6))
stream$putl(po, f_form(jaro("JELLYFISH", "SMELLYFISH"), 1, 6))
end start_up</syntaxhighlight>
{{out}}
<pre>0.944444
0.766667
0.896296</pre>
=={{header|COBOL}}==
{{trans|Java}}
<
identification division.
program-id. JaroDistance.
Line 1,016 ⟶ 1,270:
((matches - transpositions / 2) / matches)) / 3
.
</syntaxhighlight>
{{out}}
<pre>
Line 1,026 ⟶ 1,280:
=={{header|CoffeeScript}}==
{{trans|C++}}
<
l1 = s1.length
l2 = s2.length
Line 1,055 ⟶ 1,309:
console.log jaro "MARTHA", "MARHTA"
console.log jaro "DIXON", "DICKSONX"
console.log jaro "JELLYFISH", "SMELLYFISH"</
{{Out}}
<pre>0.9444444444444445
Line 1,063 ⟶ 1,317:
=={{header|Crystal}}==
{{trans|Ruby}}
<
return 1.0 if s == t
Line 1,107 ⟶ 1,361:
JELLYFISH SMELLYFISH
).each_slice(2) { |(s ,t)| puts "jaro(#{s}, #{t}) = #{"%.10f" % jaro(s, t)}" }
</syntaxhighlight>
{{out}}
<pre>
Line 1,117 ⟶ 1,371:
=={{header|D}}==
{{trans|Kotlin}}
<
int s1_len = cast(int) s1.length;
int s2_len = cast(int) s2.length;
Line 1,156 ⟶ 1,410:
writeln(jaro( "DIXON", "DICKSONX"));
writeln(jaro("JELLYFISH", "SMELLYFISH"));
}</
<pre>0.944444
0.766667
0.896296</pre>
=={{header|Delphi}}==
See [https://rosettacode.org/wiki/Jaro_distance#Pascal Pascal].
=={{header|Elixir}}==
{{trans|Ruby}}
{{works with|Elixir|1.3}}
<
def distance(s, t) when is_binary(s) and is_binary(t), do:
distance(to_charlist(s), to_charlist(t))
Line 1,221 ⟶ 1,478:
|> Enum.each(fn [s,t] ->
:io.format "jaro(~s, ~s) = ~.10f~n", [inspect(s), inspect(t), Jaro.distance(s, t)]
end)</
{{out}}
Line 1,231 ⟶ 1,488:
Elixir has a built-in function (<code>String.jaro_distance</code>).
=={{header|Emacs Lisp}}==
{{trans|Python}}
<syntaxhighlight lang="lisp">
(let ()
(defun jaro (s1 s2)
(let (mw mflags1 mflags2 fn-reset-mflags fn-reset-all-mflags fn-cnt-trans)
(setq mflags1 (make-vector (length s1) nil))
(setq mflags2 (make-vector (length s2) nil))
(setq mw (1- (/ (max (length s1) (length s2)) 2)))
(setq fn-reset-mflags
(lambda (idx)
(let ((start (max 0 (- idx mw)))
(end (min (1- (length s2)) (+ idx mw))))
(cl-loop for i from start to end do
(when (and (not (elt mflags1 idx))
(not (elt mflags2 i)))
(when (equal (elt s1 idx) (elt s2 i))
(aset mflags1 idx 't)
(aset mflags2 i 't) ) ) ) ) ) )
(setq fn-reset-all-mflags
(lambda ()
(dotimes (idx (length s1))
(funcall fn-reset-mflags idx) ) ) )
(setq fn-cnt-trans
(lambda ()
(let ((cur2 0) (transposition 0))
(dotimes (cur1 (length s1))
(when (aref mflags1 cur1)
(while (not (aref mflags2 cur2))
(setq cur2 (1+ cur2)) )
(when (not (equal (aref s1 cur1)
(aref s2 cur2)))
(setq transposition (1+ transposition)) )
(setq cur2 (1+ cur2))
)
)
transposition ) ) )
(funcall fn-reset-all-mflags)
(let ((m (seq-count (lambda (f) f) mflags1))
(tr (funcall fn-cnt-trans)))
;;(message "matches: %s, transposition: %s, |s1|: %d |s2|: %d" m tr (length s1) (length s2))
(if (= m 0)
0
(progn (/ (+ (/ (float m) (length s1)) (/ (float m) (length s2)) (/ (float (- m (/ (float tr) 2))) m) ) 3))
) ) ) )
(let ((params '(("MARTHA" "MARHTA")
("DIXON" "DICKSONX")
("JELLYFISH" "SMELLYFISH"))))
(dolist (p params)
(message "jaro(%s, %s) = %f"
(nth 0 p) (nth 1 p)
(jaro (nth 0 p) (nth 1 p)))
)
)
)
</syntaxhighlight>
{{out}}
<pre>
jaro(MARTHA, MARHTA) = 0.944444
jaro(DIXON, DICKSONX) = 0.766667
jaro(JELLYFISH, SMELLYFISH) = 0.896296
</pre>
=={{header|F_Sharp|F#}}==
<
// Calculate Jaro distance of 2 strings. Nigel Galloway: August 7th., 2020
let fG n g=Seq.map2(fun n g->if g=1 then Some n else None) n g |> Seq.choose id
Line 1,246 ⟶ 1,571:
printfn "DIXON DICKSONX->%f" (J "DIXON" "DICKSONX")
printfn "JELLYFISH SMELLYFISH->%f" (J "JELLYFISH" "SMELLYFISH")
</syntaxhighlight>
{{out}}
<pre>
Line 1,255 ⟶ 1,580:
=={{header|Factor}}==
{{works with|Factor|0.99 development release 2019-03-17+}}
<
math.order sequences sequences.extras ;
IN: rosetta-code.jaro-distance
Line 1,288 ⟶ 1,613:
] 2 4 mnapply ;
MAIN: jaro-demo</
{{out}}
<pre>
Line 1,298 ⟶ 1,623:
=={{header|FreeBASIC}}==
<
' compile with: fbc -s console
Line 1,354 ⟶ 1,679:
Print : Print "hit any key to end program"
Sleep
End</
{{out}}
<pre> jaro (MARTHA, MARHTA) = 0.9444444444444444
Line 1,361 ⟶ 1,686:
=={{header|Go}}==
<
import "fmt"
Line 1,429 ⟶ 1,754:
fmt.Printf("%f\n", jaro("DIXON", "DICKSONX"))
fmt.Printf("%f\n", jaro("JELLYFISH", "SMELLYFISH"))
}</
{{out}}
<pre>
Line 1,438 ⟶ 1,763:
=={{header|Haskell}}==
<
import Data.Maybe (mapMaybe)
import Text.Printf (printf)
---------------------- JARO DISTANCE ---------------------
jaro :: Ord a => [a] -> [a] -> Float
jaro x y
| otherwise =
(1 / 3)
* ( (m / s1) + (m / s2) + ((m - t) / m))
where
f = fromIntegral . length
[m, t] =
[f, fromIntegral . transpositions]
<*> [matches x y]
[s1, s2] = [f] <*> [x, y]
matches :: Eq a => [a] -> [a] -> [(Int, a)]
matches s1 s2 =
let [(l1, xs), (l2, ys)] =
sortOn
fst
((length >>= (,)) <$> [s1, s2])
r = quot l2 2 - 1
in mapMaybe
( \(c, n) ->
-- Initial chars out of range ?
let offset = max 0 (n - (r + 1))
>>= (\i -> Just (offset + i, c
(zip xs [1 ..])
transpositions :: Ord a => [(Int, a)] -> Int
transpositions =
length
. filter (uncurry (>))
. (zip <*> tail)
main :: IO ()
main =
mapM_ putStrLn $
fmap
intercalate
[s1, s2, printf "%.3f\n" $ jaro s1 s2]
)
[ ("DWAYNE", "DUANE"),
("MARTHA", "MARHTA"),
("DIXON", "DICKSONX"),
("JELLYFISH", "SMELLYFISH")
]</syntaxhighlight>
{{Out}}
<pre>DWAYNE -> DUANE -> 0.822
Line 1,492 ⟶ 1,833:
{{trans|Kotlin}}
{{works with|Neko|2.1.0}}
<
private static function jaro(s1: String, s2: String): Float {
var s1_len = s1.length;
Line 1,530 ⟶ 1,871:
Sys.println(jaro("JELLYFISH", "SMELLYFISH"));
}
}</
{{Out}}
<pre>0.944444444444445
0.766666666666667
0.896296296296296</pre>
=={{header|IS-BASIC}}==
<syntaxhighlight lang="is-basic">100 PROGRAM "Jaro.bas"
110 DO
120 READ IF MISSING EXIT DO:A$,B$
130 PRINT A$;", ";B$;":";JARO(A$,B$)
140 LOOP
150 DEF JARO(A$,B$)
160 LET J=1:LET M,T,JARO=0:LET S1=LEN(A$):LET S2=LEN(B$)
170 IF S1>S2 THEN
180 LET Z$=A$:LET A$=B$:LET B$=Z$
190 LET Z=S1:LET S1=S2:LET S2=Z
200 END IF
210 LET MAXDIST=INT(S2/2)
220 FOR I=1 TO S1
230 IF A$(I)=B$(J) THEN
240 LET M=M+1:CALL CHANGE(B$," ",J)
250 ELSE
260 FOR K=MAX(1,I-MAXDIST) TO MIN(S2,I+MAXDIST)
270 IF A$(I)=B$(K) THEN
280 LET T=T+1:LET M=M+1:CALL CHANGE(B$," ",K)
290 IF K>J THEN LET J=K
300 END IF
310 NEXT
320 END IF
330 IF J<S2 THEN LET J=J+1
340 NEXT
350 IF M<>0 THEN
360 LET T=INT(T/2)
370 LET JARO=(M/S1+M/S2+((M-T)/M))/3
380 END IF
390 END DEF
400 DEF CHANGE(REF S$,C$,POS)
410 LET S$=S$(:POS-1)&C$&S$(POS+1:)
420 END DEF
430 DATA MARTHA,MARHTA
440 DATA DIXON,DICKSONX
450 DATA JELLYFISH,SMELLYFISH
460 DATA DWAYNE,DUANE</syntaxhighlight>
=={{header|J}}==
Line 1,540 ⟶ 1,920:
Implementation:
<
d=. ((x >.&# y)%2)-1
e=. (x =/y) * d >: |x -/&(i.@#) y
Line 1,550 ⟶ 1,930:
s2=. #y
((m%s1)+(m%s2)+(m-t)%m)%3
)</
Task examples:
<
0.944444
'DIXON' jaro 'DICKSONX'
0.766667
'JELLYFISH' jaro 'SMELLYFISH'
0.896296</
=={{header|Java}}==
<
public static double jaro(String s, String t) {
int s_len = s.length();
Line 1,611 ⟶ 1,991:
System.out.println(jaro("JELLYFISH", "SMELLYFISH"));
}
}</
{{out}}
<pre>
Line 1,620 ⟶ 2,000:
=={{header|jq}}==
{{trans|Wren}}
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
<syntaxhighlight lang="jq">def jaro($s1; $s2):
($s1|length) as $le1
| if
else ((((if $le2 > $le1 then $le2 else $le1 end) / 2) | floor) - 1) as $dist
| {matches: 0, matches2: [], matches2: [], transpos: 0 }
| reduce range(
(($i - $dist) |
| (($i + $dist + 1) | if
| until(.k >= $stop;
then
|
else .k += 1
end) )
| if .matches == 0 then 0
else .k = 0
| reduce range(0; $le1) as $i (.;
if .matches1[$i]
then until(.k >= $le2 or .matches2[.k]; .k += 1)
| if .k < $le2 and ($s1[$i:$i+1] != $s2[.k:.k+1]) then .transpos += 1 else . end
| .k += 1
else .
end )
| .transpos /= 2
| (.matches/$le1 + .matches/$le2 + ((.matches - .transpos)/.matches)) / 3
end
end ;
def task:
[["MARTHA","MARHTA"],
["DIXON", "DICKSONX"],
["JELLYFISH","SMELLYFISH"],
["ABC","DEF"]][]
| (jaro(.[0]; .[1]) * 1000 | floor / 1000) as $d
| "jaro(\(.[0]); \(.[1])) => \($d)";
task</syntaxhighlight>
{{out}}
<pre>
jaro(MARTHA; MARHTA) => 0.944
jaro(DIXON; DICKSONX) => 0.766
jaro(JELLYFISH; SMELLYFISH) => 0.896
jaro(ABC; DEF) => 0
</pre>
=={{header|Julia}}==
{{works with|Julia|
<
m = t = p
matchstd = max(length(s1), length(s2)) / 2 - 1
for
(c1 == c2) && (abs(i2 - i1) ≤ matchstd) && (m += 1)
end
end
t = (m - p) / 2
end
@show jarodistance("MARTHA", "MARHTA")
@show jarodistance("DIXON", "DICKSONX")
@show
</syntaxhighlight>
{{out}}
<pre>
jarodistance("
jarodistance("
jarodistance("JELLYFISH", "SMELLYFISH") = 0.8870370370370371
</pre>
=={{header|Kotlin}}==
{{trans|Java}}
<
fun distance(s1: String, s2: String): Double {
val s1_len = s1.length
Line 1,721 ⟶ 2,118:
println(Jaro.distance("DIXON", "DICKSONX"))
println(Jaro.distance("JELLYFISH", "SMELLYFISH"))
}</
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">ClearAll[JaroDistance]
JaroDistance[s_String, t_String] := Module[{slen, tlen, maxdistance, smatches, tmatches, matches, transpositions, start, end, k, schar, tchar},
slen = StringLength[s];
tlen = StringLength[t];
schar = Characters[s];
tchar = Characters[t];
If[slen == tlen == 0,
1
,
maxdistance = Floor[Max[slen, tlen]/2] - 1;
smatches = ConstantArray[False, slen];
tmatches = ConstantArray[False, tlen];
matches = transpositions = 0;
Do[
start = Max[0, i - maxdistance];
end = Min[i + maxdistance + 1, tlen];
start = Max[1, i - maxdistance];
end = Min[i + maxdistance + 1, tlen];
Do[
If[! tmatches[[j]],
If[schar[[i]] == tchar[[j]],
smatches[[i]] = True;
tmatches[[j]] = True;
matches++;
Break[];
]
]
,
{j, start, end}
]
,
{i, slen}
];
If[matches == 0,
0
,
k = 1;
Do[
If[smatches[[i]],
While[! tmatches[[k]],
k++;
];
If[schar[[i]] != tchar[[k]],
transpositions++;
];
k++;
]
,
{i, slen}
];
N@(matches/slen + matches/tlen + (matches - transpositions/2)/matches)/3
]
]
]
JaroDistance["DWAYNE", "DUANE"]
JaroDistance["MARTHA", "MARHTA"]
JaroDistance["DIXON", "DICKSONX"]
JaroDistance["JELLYFISH", "SMELLYFISH"]</syntaxhighlight>
{{out}}
<pre>0.822222
0.944444
0.766667
0.896296</pre>
=={{header|Nim}}==
{{trans|Kotlin}}
<syntaxhighlight lang="nim">import lenientops
func jaro(s1, s2: string): float =
if s1.len == 0 and s2.len == 0: return 1
if s1.len == 0 or s2.len == 0: return 0
let matchDistance = max(s1.len, s2.len) div 2 - 1
var s1Matches = newSeq[bool](s1.len)
var s2Matches = newSeq[bool](s2.len)
var matches = 0
for i in 0..s1.high:
for j in max(0, i - matchDistance)..min(i + matchDistance, s2.high):
if not s2Matches[j] and s1[i] == s2[j]:
s1Matches[i] = true
s2Matches[j] = true
inc matches
break
if matches == 0: return 0
var transpositions = 0.0
var k = 0
for i in ..s1.high:
if not s1Matches[i]: continue
while not s2Matches[k]: inc k
if s1[i] != s2[k]: transpositions += 0.5
inc k
result = (matches / s1.len + matches / s2.len + (matches - transpositions) / matches) / 3
echo jaro("MARTHA", "MARHTA")
echo jaro("DIXON", "DICKSONX")
echo jaro("JELLYFISH", "SMELLYFISH")</syntaxhighlight>
{{out}}
<pre>0.9444444444444445
0.7666666666666666
0.8962962962962964</pre>
=={{header|Objeck}}==
{{trans|Java}}
<
function : Main(args : String[]) ~ Nil {
Jaro("MARTHA", "MARHTA")->PrintLine();
Line 1,774 ⟶ 2,278:
((matches->As(Float) - transpositions/2.0) / matches)) / 3.0;
}
}</
{{output}}
Line 1,788 ⟶ 2,292:
{{Works with|PARI/GP|2.7.4 and above}}
<
\\Jaro distance between 2 strings s1 and s2.
\\ 4/12/16 aev
Line 1,824 ⟶ 2,328:
jaroDist("DWAYNE","DUANE");
}
</
{{Output}}
Line 1,836 ⟶ 2,340:
=={{header|Pascal}}==
<
program Jaro_distance;
uses SysUtils, Math;
//converted from C source by /u/bleuge
function ssJaroWinkler(s1, s2: string): double;
var
l1, l2, match_distance, matches, i, k, trans: integer;
bs1, bs2: array[1..255] of boolean; //used to avoid getmem, max string length is 255
begin
l1 := length(s1);
l2 := length(s2);
fillchar(bs1, sizeof(bs1), 0); //set booleans to false
fillchar(bs2, sizeof(bs2), 0);
if l1 = 0 then
if l2 = 0 then
else
match_distance := (max(l1, l2) div 2) - 1;
matches := 0;
trans := 0;
for i := 1 to l1 do
begin
for k := max(1, i - match_distance) to min(i + match_distance, l2) do
begin
if bs2[k] then
bs1[i] := true;
bs2[k] := true;
inc(matches);
break;
end;
end;
if matches = 0 then
k := 1;
for i := 1 to l1 do
begin
if (bs1[i] = false) then
continue;
inc(k);
if s1[i] <> s2[k] then
inc(trans);
inc(k);
end;
trans := trans div 2;
result := ((matches / l1) + (matches / l2) + ((matches - trans) / matches)) / 3;
end;
begin
//test
{$IFNDEF LINUX}readln;{$ENDIF}
end.</syntaxhighlight>
{{out}}
<pre>
Line 1,892 ⟶ 2,411:
=={{header|Perl}}==
<
use warnings;
use List::Util qw(min max);
Line 1,929 ⟶ 2,448:
printf "%.3f\n", jaro(@$_[0], @$_[1]) for
['MARTHA', 'MARHTA'], ['DIXON', 'DICKSONX'], ['JELLYFISH', 'SMELLYFISH'],
['I repeat myself', 'I repeat myself'], ['', ''];</
{{out}}
<pre>0.944
Line 1,938 ⟶ 2,457:
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">jaro</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">str1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">str2</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">str1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">str1</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">str2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">str2</span><span style="color: #0000FF;">))</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">len1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">str1</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">len2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">str2</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">match_distance</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">len1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len2</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">match_count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">half_transposed</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">len1</span><span style="color: #0000FF;">==</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">len2</span><span style="color: #0000FF;">==</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000080;font-style:italic;">-- count the number of matches</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">m1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len1</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">m2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">len1</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">match_distance</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">to</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">len2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">match_distance</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">m2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">str1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">str2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">m1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #000000;">m2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #000000;">match_count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">match_count</span><span style="color: #0000FF;">==</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000080;font-style:italic;">-- count the number of half-transpositions</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">len1</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">m1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #000000;">m2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">do</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> <span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #000000;">half_transposed</span> <span style="color: #0000FF;">+=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">str1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">str2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">])</span>
<span style="color: #000000;">k</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">transpositions</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">half_transposed</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">not_transposed</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">match_count</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">transpositions</span>
<span style="color: #000080;font-style:italic;">--
-- return the average of:
-- percentage/fraction of the
-- percentage/fraction of
-- percentage/fraction of matches that were not transposed.
--</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">match_count</span><span style="color: #0000FF;">/</span><span style="color: #000000;">len1</span> <span style="color: #0000FF;">+</span>
<span style="color: #000000;">match_count</span><span style="color: #0000FF;">/</span><span style="color: #000000;">len2</span> <span style="color: #0000FF;">+</span>
<span style="color: #000000;">not_transposed</span><span style="color: #0000FF;">/</span><span style="color: #000000;">match_count</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">3</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">testcouples</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #008000;">"CRATE"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TRACE"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"JONES"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"JOHNSON"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"ABCVWXYZ"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"CABVWXYZ"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"DWAYNE"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"DUANE"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"MARTHA"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"MARHTA"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"DIXON"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"DICKSONX"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"JELLYFISH"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"SMELLYFISH"</span><span style="color: #0000FF;">}}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">testcouples</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">testcouples</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%f <== jaro(\"%s\", \"%s\")\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">jaro</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">),</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,018 ⟶ 2,539:
{{Works with|Python|3}}
<
from __future__ import division
Line 2,081 ⟶ 2,602:
if __name__ == '__main__':
main()</
{{out}}
<pre>jaro('MARTHA', 'MARHTA') = 0.9444444444
Line 2,091 ⟶ 2,612:
{{Trans|Haskell}}
{{Works with|Python|3}}
<
from functools import reduce
Line 2,331 ⟶ 2,852:
# MAIN ---
if __name__ == '__main__':
main()</
{{Out}}
<pre>Jaro distances:
Line 2,347 ⟶ 2,868:
Returns an exact value for the Jaro distance.
<
;; {{trans|C}}
(require data/bit-vector)
Line 2,414 ⟶ 2,935:
(exact->inexact (jaro-distance "DIXON" "DICKSONX")); 0.766667
(jaro-distance "JELLYFISH" "SMELLYFISH"); 0.896296
(exact->inexact (jaro-distance "JELLYFISH" "SMELLYFISH"))); 0.896296</
{{out}}
Line 2,428 ⟶ 2,949:
(formerly Perl 6)
{{trans|Perl}}
<syntaxhighlight lang="raku"
return 1 if $s eq $t;
my $
my $
my $
my ($matches, @
for ^@s -> $i {
my $start = 0 max $i - $
my $end = $i + $
for $start .. $end -> $j {
next if @
(@
$matches++ and last;
}
Line 2,450 ⟶ 2,971:
my ($k, $transpositions) = (0, 0);
for ^@s -> $i {
next unless @
$k++ until @
$transpositions++ if @s[$i] ne @t[$k];
$k++;
}
( $matches/$
}
say jaro(.key, .value).fmt: '%.3f' for
'MARTHA' => 'MARHTA', 'DIXON' => 'DICKSONX', 'JELLYFISH' => 'SMELLYFISH',
'I repeat myself' => 'I repeat myself', '' => '';
</syntaxhighlight>
{{out}}
<pre>0.944
Line 2,470 ⟶ 2,992:
=={{header|REXX}}==
<
@.= /*define a default for the @. array. */
parse arg @.1 /*obtain an optional character string. */
Line 2,477 ⟶ 2,999:
@.3= 'JELLYFISH SMELLYFISH'
@.4= 'DWAYNE DUANE'
end /* [↑]
do j=1 while @.j\=='' /*process all the strings in the list. */
d= jaroD(@.j)
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
jaroD: procedure; arg s.1 s.2 .; L1= length(s.1); L2= length(s.2); m= 0
if L1==0 | L2==0 then return 0 /*check if any string is a null string.*/
f= max(L1, L2) % 2 - 1 /*calculate furthest distanced allowed.*/
r.=
do k=1 for L1; p= pos( substr(s.1, k, 1), s.2, max(1, k-f) )
r.k= p
Line 2,493 ⟶ 3,016:
else r.k= 0 /* ··· otherwise, don't count it.*/
end /*k*/
t= 0
do o=1 for L1; om= o - 1; if r.o==0 | r.om==0 then iterate
if pos( substr(s.1, o, 1), s.2)==0 then iterate
Line 2,500 ⟶ 3,023:
if m==0 then return 0
return (m/L1 + m/L2 + (m-t)/m) / 3</
{{out|output|text= when using the default inputs:}}
<pre>
Line 2,510 ⟶ 3,033:
=={{header|Ring}}==
<
# Project : Jaro distance
Line 2,560 ⟶ 3,083:
b = temp
return [a, b]
</syntaxhighlight>
Output:
<pre>
Line 2,569 ⟶ 3,092:
=={{header|Ruby}}==
<
return 1.0 if s == t
Line 2,616 ⟶ 3,139:
).each_slice(2) do |s,t|
puts "jaro(#{s.inspect}, #{t.inspect}) = #{'%.10f' % jaro(s, t)}"
end</
{{out}}
<pre>
Line 2,626 ⟶ 3,149:
=={{header|Rust}}==
{{trans|C++}}
<
pub fn jaro(s1: &str, s2: &str) -> f64 {
Line 2,666 ⟶ 3,189:
let pairs = [("MARTHA", "MARHTA"), ("DIXON", "DICKSONX"), ("JELLYFISH", "SMELLYFISH")];
for p in pairs.iter() { println!("{}/{} = {}", p.0, p.1, jaro(p.0, p.1)); }
}</
{{Out}}
<pre>MARTHA/MARHTA = 0.9444444444444445
Line 2,674 ⟶ 3,197:
=={{header|Scala}}==
{{trans|Java}}
<
def distance(s1: String, s2: String): Double = {
Line 2,710 ⟶ 3,233:
val strings = List(("MARTHA", "MARHTA"), ("DIXON", "DICKSONX"), ("JELLYFISH", "SMELLYFISH"))
strings.foreach { s => println(distance(s._1, s._2)) }
}</
=={{header|Sidef}}==
<
return 1 if (s == t)
Line 2,763 ⟶ 3,286:
] {
say "jaro(#{pair.map{.join.dump}.join(', ')}) = #{'%.10f' % jaro(pair...)}"
}</
{{out}}
<pre>
Line 2,774 ⟶ 3,297:
Here we use the [https://ideas.repec.org/c/boc/bocode/s457850a.html jarowinkler] package from SSC. To install the package, type
<syntaxhighlight lang
Now the program for the task:
<
input str20 a str20 b
DWAYNE DUANE
Line 2,789 ⟶ 3,312:
format %8.3f jaro
format %-20s a b
list a b jaro</
'''Output'''
Line 2,803 ⟶ 3,326:
=={{header|Swift}}==
<
let s_len: Int = s.count
let t_len: Int = t.count
Line 2,892 ⟶ 3,415:
print("DIXON/DICKSONX:", jaroWinklerMatch("DIXON", "DICKSONX"))
print("JELLYFISH/SMELLYFISH:", jaroWinklerMatch("JELLYFISH", "SMELLYFISH"))
</syntaxhighlight>
{{out}}
Line 2,903 ⟶ 3,426:
=={{header|Tcl}}==
<
set l1 [string length $s1]
set l2 [string length $s2]
Line 2,940 ⟶ 3,463:
} {
puts "[jaro $s $t]:\t$s / $t"
}</
{{out}}
Line 2,949 ⟶ 3,472:
=={{header|Turbo-Basic XL}}==
<
10 DIM Word_1$(20), Word_2$(20), Z$(20)
11 CLS
Line 2,965 ⟶ 3,488:
12050 IF Word_1$(I,I)=Word_2$(J,J) THEN M=M+1: Word_2$(J,J)=" ": GO# JMP_JWD
12060 Max=1 : IF Max<(I-L) THEN Max=I-L
12070 Min=S2 : IF Min>(I+L-1) THEN Min=I+L-1
12080 FOR K=Max TO Min
12090 IF Word_1$(I,I)=Word_2$(K,K) THEN N=N+1: M=M+1: Word_2$(K,K)=" ": IF K>J THEN J=K
Line 2,991 ⟶ 3,514:
12310 ? "Jaro Winkler Distance=";Result
12320 ENDPROC
</syntaxhighlight>
{{out}}
<pre>MARTHA, MARHTA: 0.9444444433
Line 2,998 ⟶ 3,521:
=={{header|VBA}}==
<syntaxhighlight lang="vb">
Option Explicit
Line 3,043 ⟶ 3,566:
JaroWinkler = JaroWinkler + (1 - JaroWinkler) * l * WorksheetFunction.Min(0.25, p)
End Function
</syntaxhighlight>
=={{header|V (Vlang)}}==
{{trans|Python}}
<syntaxhighlight lang="v (vlang)">import math
fn jaro(str1 string, str2 string) f64 {
s1_len := str1.len
s2_len := str2.len
if s1_len == 0 && s2_len == 0 {
return 1
}
if s1_len == 0 || s2_len == 0 {
return 0
}
match_distance := math.max<int>(s1_len,s2_len)/2 - 1
mut str1_matches := []bool{len: s1_len}
mut str2_matches := []bool{len: s2_len}
mut matches := 0
mut transpositions := 0.0
for i in 0..s1_len {
start := math.max<int>(0,i - match_distance)
end := math.min<int>(i + match_distance, s2_len)
for k in start..end {
if str2_matches[k] {
continue
}
if str1[i] != str2[k] {
continue
}
str1_matches[i] = true
str2_matches[k] = true
matches++
break
}
}
if matches == 0 {
return 0
}
mut k := 0
for i in 0..s1_len {
if !str1_matches[i] {
continue
}
for !str2_matches[k] {
k++
}
if str1[i] != str2[k] {
transpositions++
}
k++
}
transpositions /= 2
return (matches/f64(s1_len) +
matches/f64(s2_len) +
(matches-transpositions)/matches) / 3
}
fn main() {
println(jaro("MARTHA", "MARHTA"))
println(jaro("DIXON", "DICKSONX"))
println(jaro("JELLYFISH", "SMELLYFISH"))
}</syntaxhighlight>
{{out}}
<pre>0.9444444444444445
0.7666666666666666
0.8962962962962964
</pre>
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
<
var jaro = Fn.new { |s1, s2|
Line 3,092 ⟶ 3,685:
System.print(Fmt.f(0, jaro.call("MARTHA", "MARHTA")))
System.print(Fmt.f(0, jaro.call("DIXON", "DICKSONX")))
System.print(Fmt.f(0, jaro.call("JELLYFISH", "SMELLYFISH")))</
{{out}}
Line 3,102 ⟶ 3,695:
=={{header|zkl}}==
<
fcn _jaro(str1,str2, matchDistance){
cs:=Sink(String);
Line 3,122 ⟶ 3,715:
( matches/s1Len + matches/s2Len +
((matches - transpositions)/matches) ) / 3.0
}</
<
T("MARTHA","MARHTA"), T("DIXON","DICKSONX"), T("JELLYFISH","SMELLYFISH"))){
println(0'|jaro("%s","%s") = %.10f|.fmt(s,t,jaro(s,t)));
}</
{{out}}
<pre>
Line 3,136 ⟶ 3,729:
=={{header|ZX Spectrum Basic}}==
{{trans|FreeBASIC}}
<
20 LET a$="DIXON": LET b$="DICKSONX": PRINT a$;", ";b$;": ";: GO SUB 1000: PRINT jaro
30 LET a$="JELLYFISH": LET b$="SMELLYFISH": PRINT a$;", ";b$;": ";: GO SUB 1000: PRINT jaro
Line 3,157 ⟶ 3,750:
5000 REM Functions
5010 DEF FN x(a,b)=(a AND a>b)+(b AND a<b)+(a AND a=b): REM max function
5020 DEF FN n(a,b)=(a AND a<b)+(b AND a>b)+(a AND a=b): REM min function</
{{out}}
<pre>MARTHA, MARHTA: 0.94444444
|