Levenshtein distance: Difference between revisions
Content added Content deleted
(Added PL/M translation of Action!) |
|||
Line 4,442: | Line 4,442: | ||
End;</lang> |
End;</lang> |
||
Output is the same as for version 1. |
Output is the same as for version 1. |
||
=={{header|PL/M}}== |
|||
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator) |
|||
{{Trans|Action!}} |
|||
<lang pli>100H: /* CALCULATE THE LEVENSHTEIN DISTANCE BETWEEN STRINGS */ |
|||
/* TRANS:ATED FROM THE ACTION! SAMPLE */ |
|||
/* CP/M BDOS SYSTEM CALL, IGNORE THE RETURN VALUE */ |
|||
BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END; |
|||
PR$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END; |
|||
PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END; |
|||
PR$NL: PROCEDURE; CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END; |
|||
PR$NUMBER: PROCEDURE( N ); /* PRINTS A NUMBER IN THE MINIMUN FIELD WIDTH */ |
|||
DECLARE N ADDRESS; |
|||
DECLARE V ADDRESS, N$STR ( 6 )BYTE, W BYTE; |
|||
V = N; |
|||
W = LAST( N$STR ); |
|||
N$STR( W ) = '$'; |
|||
N$STR( W := W - 1 ) = '0' + ( V MOD 10 ); |
|||
DO WHILE( ( V := V / 10 ) > 0 ); |
|||
N$STR( W := W - 1 ) = '0' + ( V MOD 10 ); |
|||
END; |
|||
CALL PR$STRING( .N$STR( W ) ); |
|||
END PR$NUMBER; |
|||
DECLARE WIDTH LITERALLY '17'; /* ALLOW STRINGS UP TO 16 CHARACTERS */ |
|||
DECLARE MATRIX$SIZE LITERALLY '289'; /* 17*17 ELEMENTS */ |
|||
DECLARE STRING LITERALLY '( WIDTH )BYTE'; |
|||
SCOPY: PROCEDURE( WORD, STR ); /* CONVEET PL/M STYLE STRING TO ACTION! */ |
|||
DECLARE ( WORD, STR ) ADDRESS; |
|||
DECLARE ( W BASED WORD, S BASED STR ) STRING; |
|||
DECLARE ( I, C ) BYTE; |
|||
I = 0; |
|||
DO WHILE( ( C := S( I ) ) <> '$' ); |
|||
W( I := I + 1 ) = C; |
|||
END; |
|||
W( 0 ) = I; |
|||
END SCOPY; |
|||
SET2DM: PROCEDURE( MATRIX, X, Y, VAL ); |
|||
DECLARE ( MATRIX, X, Y, VAL ) ADDRESS; |
|||
DECLARE M BASED MATRIX ( MATRIX$SIZE )ADDRESS; |
|||
M( X + ( Y * WIDTH ) ) = VAL; |
|||
END SET2DM; |
|||
GET2DM: PROCEDURE( MATRIX, X, Y )ADDRESS; |
|||
DECLARE ( MATRIX, X, Y, VAL ) ADDRESS; |
|||
DECLARE M BASED MATRIX ( MATRIX$SIZE )ADDRESS; |
|||
RETURN M( X + ( Y * WIDTH ) ); |
|||
END GET2DM; |
|||
LEVENSHTEIN$DISTANCE: PROCEDURE( S1, S2 )ADDRESS; |
|||
DECLARE ( S1, S2 ) ADDRESS; |
|||
DECLARE STR1 BASED S1 STRING, STR2 BASED S2 STRING; |
|||
DECLARE MATRIX ( MATRIX$SIZE ) ADDRESS; |
|||
DECLARE ( RESULT, MIN, K, L, I, J, M, N ) BYTE; |
|||
RESULT = 0; |
|||
M = STR1( 0 ); |
|||
N = STR2( 0 ); |
|||
DO I = 0 TO MATRIX$SIZE - 1; MATRIX( I ) = 0; END; |
|||
DO I = 0 TO M; CALL SET2DM( .MATRIX, I, 1, I ); END; |
|||
DO J = 0 TO N; CALL SET2DM( .MATRIX, 1, J, J ); END; |
|||
DO J = 1 TO N; |
|||
DO I = 1 TO M; |
|||
IF STR1( I ) = STR2( J ) THEN DO; |
|||
CALL SET2DM( .MATRIX, I, J, GET2DM( .MATRIX, I - 1, J - 1 ) ); |
|||
END; |
|||
ELSE DO; |
|||
MIN = GET2DM( .MATRIX, I - 1, J ) + 1; /* DELETION */ |
|||
K = GET2DM( .MATRIX, I, J - 1 ) + 1; /* INSERTION */ |
|||
L = GET2DM( .MATRIX, I - 1, J - 1 ) + 1; /* SUBSTITUTION */ |
|||
IF K < MIN THEN MIN = K; |
|||
IF L < MIN THEN MIN = L; |
|||
CALL SET2DM( .MATRIX, I, J, MIN ); |
|||
END; |
|||
END; |
|||
END; |
|||
RETURN GET2DM( .MATRIX, M, N ); |
|||
END LEVENSHTEIN$DISTANCE; |
|||
TEST: PROCEDURE( W1, W2 ); |
|||
DECLARE ( W1, W2 ) ADDRESS; |
|||
DECLARE ( WORD$1, WORD$2 ) STRING; |
|||
DECLARE RESULT ADDRESS; |
|||
CALL SCOPY( .WORD$1, W1 ); |
|||
CALL SCOPY( .WORD$2, W2 ); |
|||
CALL PR$STRING( W1 ); CALL PR$STRING( .' -> $' ); CALL PR$STRING( W2 ); |
|||
CALL PR$STRING( .', LEVENSHTEIN DISTANCE: $' ); |
|||
CALL PR$NUMBER( LEVENSHTEIN$DISTANCE( .WORD$1, .WORD$2 ) ); |
|||
CALL PR$NL; |
|||
END TEST; |
|||
/* TEST CASES */ |
|||
CALL TEST( .'KITTEN$', .'SITTING$' ); |
|||
CALL TEST( .'ROSETTACODE$', .'RAISETHYSWORD$' ); |
|||
CALL TEST( .'QWERTY$', .'QWERYT$' ); |
|||
CALL TEST( .( 'ACTION', 33, '$' ), .'PL/M$' ); |
|||
EOF</lang> |
|||
{{out}} |
|||
<pre> |
|||
KITTEN -> SITTING, LEVENSHTEIN DISTANCE: 3 |
|||
ROSETTACODE -> RAISETHYSWORD, LEVENSHTEIN DISTANCE: 8 |
|||
QWERTY -> QWERYT, LEVENSHTEIN DISTANCE: 2 |
|||
ACTION! -> PL/M, LEVENSHTEIN DISTANCE: 4 |
|||
</pre> |
|||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |