2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -8,11 +8,16 @@ The task should demonstrate:
* Comparing two strings to see if one is lexically ordered after than the other
* How to achieve both case sensitive comparisons and case insensitive comparisons within the language
* How the language handles comparison of numeric strings if these are not treated lexically
* Demonstrate any other kinds of string comparisons that the language provides, particularly as it relates to your type system. For example, you might demonstrate the difference between generic/polymorphic comparison and coercive/allomorphic comparison if your language supports such a distinction.
* Demonstrate any other kinds of string comparisons that the language provides, particularly as it relates to your type system.   For example, you might demonstrate the difference between generic/polymorphic comparison and coercive/allomorphic comparison if your language supports such a distinction.
Here "generic/polymorphic" comparison means that the function or operator you're using doesn't always do string comparison, but bends the actual semantics of the comparison depending on the types one or both arguments; with such an operator, you achieve string comparison only if the arguments are sufficiently string-like in type or appearance. In contrast, a "coercive/allomorphic" comparison function or operator has fixed string-comparison semantics regardless of the argument type; instead of the operator bending, it's the arguments that are forced to bend instead and behave like strings if they can, and the operator simply fails if the arguments cannot be viewed somehow as strings. A language may have one or both of these kinds of operators; see the Perl 6 entry for an example of a language with both kinds of operators.
<br>
Here "generic/polymorphic" comparison means that the function or operator you're using doesn't always do string comparison, but bends the actual semantics of the comparison depending on the types one or both arguments; with such an operator, you achieve string comparison only if the arguments are sufficiently string-like in type or appearance.
'''See also:'''<!-- Note that this part might go away, as it is handled by the “basic data operation” template -->
* [[Integer comparison]]
* [[String matching]]
* [[Compare a list of strings]]
In contrast, a "coercive/allomorphic" comparison function or operator has fixed string-comparison semantics regardless of the argument type; &nbsp; instead of the operator bending, it's the arguments that are forced to bend instead and behave like strings if they can, &nbsp; and the operator simply fails if the arguments cannot be viewed somehow as strings. &nbsp; A language may have one or both of these kinds of operators; &nbsp; see the Perl 6 entry for an example of a language with both kinds of operators.
;Related tasks:
* &nbsp; [[Integer comparison]]
* &nbsp; [[String matching]]
* &nbsp; [[Compare a list of strings]]
<br><br>

View file

@ -0,0 +1,67 @@
STRING a := "abc ", b := "ABC ";
# when comparing strings, Algol 68 ignores trailing blanks #
# so e.g. "a" = "a " is true #
# test procedure, prints message if condition is TRUE #
PROC test = ( BOOL condition, STRING message )VOID:
IF condition THEN print( ( message, newline ) ) FI;
# equality? #
test( a = b, "a = b" );
# inequality? #
test( a /= b, "a not = b" );
# lexically ordered before? #
test( a < b, "a < b" );
# lexically ordered after? #
test( a > b, "a > b" );
# Algol 68's builtin string comparison operators are case-sensitive. #
# To perform case insensitive comparisons, procedures or operators #
# would need to be written #
# e.g. #
# compare two strings, ignoring case #
# Note the "to upper" PROC is an Algol 68G extension #
# It could be written in standard Algol 68 (assuming ASCII) as e.g. #
# PROC to upper = ( CHAR c )CHAR: #
# IF c < "a" OR c > "z" THEN c #
# ELSE REPR ( ( ABS c - ABS "a" ) + ABS "A" ) FI; #
PROC caseless comparison = ( STRING a, b )INT:
BEGIN
INT a max = UPB a, b max = UPB b;
INT a pos := LWB a, b pos := LWB b;
INT result := 0;
WHILE result = 0
AND ( a pos <= a max OR b pos <= b max )
DO
CHAR a char := to upper( IF a pos <= a max THEN a[ a pos ] ELSE " " FI );
CHAR b char := to upper( IF b pos <= b max THEN b[ b pos ] ELSE " " FI );
result := ABS a char - ABS b char;
a pos +:= 1;
b pos +:= 1
OD;
IF result < 0 THEN -1 ELIF result > 0 THEN 1 ELSE 0 FI
END ; # caseless comparison #
# compare two strings for equality, ignoring case #
PROC equal ignoring case = ( STRING a, b )BOOL: caseless comparison( a, b ) = 0;
# similar procedures for inequality and lexical ording ... #
test( equal ignoring case( a, b ), "a = b (ignoring case)" );
# Algol 68 is strongly typed - strings cannot be compared to e.g. integers #
# unless procedures or operators are written, e.g. #
# e.g. OP = = ( STRING a, INT b )BOOL: a = whole( b, 0 ); #
# OP = = ( INT a, STRING b )BOOL: b = a; #
# etc. #
# Algol 68 also has <= and >= comparison operators for testing for #
# "lexically before or equal" and "lexically after or equal" #
test( a <= b, "a <= b" );
test( a >= b, "a >= b" );
# there are no other forms of string comparison builtin to Algol 68 #

View file

@ -0,0 +1,67 @@
begin
string(10) a;
string(12) b;
a := "abc";
b := "ABC";
% when comparing strings, Algol W ignores trailing blanks %
% so e.g. "a" = "a " is true %
% equality? %
if a = b then write( "a = b" );
% inequality? %
if a not = b then write( "a not = b" );
% lexically ordered before? %
if a < b then write( "a < b" );
% lexically ordered after? %
if a > b then write( "a > b" );
% Algol W string comparisons are case-sensitive. To perform case %
% insensitive comparisons, procedures would need to be written %
% e.g. as in the following block (assuming the character set is ASCII) %
begin
% convert a character to upper-case %
integer procedure toupper( integer value c ) ;
if c < decode( "a" ) or c > decode( "z" ) then c
else ( c - decode( "a" ) ) + decode( "A" );
% compare two strings, ignoring case %
% note that strings can be at most 256 characters long in Algol W %
integer procedure caselessComparison ( string(256) value a, b ) ;
begin
integer comparisonResult, pos;
comparisonResult := pos := 0;
while pos < 256 and comparisonResult = 0 do begin
comparisonResult := toupper( decode( a(pos//1) ) )
- toupper( decode( b(pos//1) ) );
pos := pos + 1
end;
if comparisonResult < 0 then -1
else if comparisonResult > 0 then 1
else 0
end caselessComparison ;
% compare two strings for equality, ignoring case %
logical procedure equalIgnoringCase ( string(256) value a, b ) ;
( caselessComparison( a, b ) = 0 );
% similar procedures for inequality and lexical ording ... %
if equalIgnoringCase( a, b ) then write( "a = b (ignoring case)" )
end caselessComparison ;
% Algol W is strongly typed - strings cannot be compared to e.g. integers %
% e.g. "if a = 23 then ..." would be a syntax error %
% Algol W also has <= and >= comparison operators for testing for %
% "lexically before or equal" and "lexically after or equal" %
if a <= b then write( "a <= b" );
if a >= b then write( "a >= b" );
% there are no other forms of string comparison builtin to Algol W %
end.

View file

@ -2,28 +2,27 @@ with Ada.Text_IO, Ada.Strings.Equal_Case_Insensitive;
procedure String_Compare is
procedure Print_Comparison (A, B: String) is
use Ada.Text_IO;
Function eq(Left, Right : String) return Boolean
renames Ada.Strings.Equal_Case_Insensitive;
procedure Print_Comparison (A, B : String) is
begin
Put_Line
( """" & A & """ and """ & B & """: " &
(if A = B then "equal, " elsif eq(A,B)
then "case-insensitive-equal, " else "not equal at all, ") &
(if A /= B then "/=, " else "") &
(if A < B then "before, " else "") &
(if A > B then "after, " else "") &
(if A <= B then "<=, " else "(not <=), ") & "and " &
(if A >= B then ">=. " else "(not >=).") );
Ada.Text_IO.Put_Line
("""" & A & """ and """ & B & """: " &
(if A = B then
"equal, "
elsif Ada.Strings.Equal_Case_Insensitive (A, B) then
"case-insensitive-equal, "
else "not equal at all, ") &
(if A /= B then "/=, " else "") &
(if A < B then "before, " else "") &
(if A > B then "after, " else "") &
(if A <= B then "<=, " else "(not <=), ") &
(if A >= B then ">=. " else "(not >=)."));
end Print_Comparison;
begin
Print_Comparison("this", "that");
Print_Comparison("that", "this");
Print_Comparison("THAT", "That");
Print_Comparison("this", "This");
Print_Comparison("this", "this");
Print_Comparison("the", "there");
Print_Comparison("there", "the");
Print_Comparison ("this", "that");
Print_Comparison ("that", "this");
Print_Comparison ("THAT", "That");
Print_Comparison ("this", "This");
Print_Comparison ("this", "this");
Print_Comparison ("the", "there");
Print_Comparison ("there", "the");
end String_Compare;

View file

@ -0,0 +1,29 @@
REM >strcomp
shav$ = "Shaw, George Bernard"
shakes$ = "Shakespeare, William"
:
REM test equality
IF shav$ = shakes$ THEN PRINT "The two strings are equal" ELSE PRINT "The two strings are not equal"
:
REM test inequality
IF shav$ <> shakes$ THEN PRINT "The two strings are unequal" ELSE PRINT "The two strings are not unequal"
:
REM test lexical ordering
IF shav$ > shakes$ THEN PRINT shav$; " is lexically higher than "; shakes$ ELSE PRINT shav$; " is not lexically higher than "; shakes$
IF shav$ < shakes$ THEN PRINT shav$; " is lexically lower than "; shakes$ ELSE PRINT shav$; " is not lexically lower than "; shakes$
REM the >= and <= operators can also be used, & behave as expected
:
REM string comparison is case-sensitive by default, and BBC BASIC
REM does not provide built-in functions to convert to all upper
REM or all lower case; but it is easy enough to define one
:
IF FN_upper(shav$) = FN_upper(shakes$) THEN PRINT "The two strings are equal (disregarding case)" ELSE PRINT "The two strings are not equal (even disregarding case)"
END
:
DEF FN_upper(s$)
LOCAL i%, ns$
ns$ = ""
FOR i% = 1 TO LEN s$
IF ASC(MID$(s$, i%, 1)) >= ASC "a" AND ASC(MID$(s$, i%, 1)) <= ASC "z" THEN ns$ += CHR$(ASC(MID$(s$, i%, 1)) - &20) ELSE ns$ += MID$(s$, i%, 1)
NEXT
= ns$

View file

@ -0,0 +1,37 @@
Macro StrTest(Check,tof)
Print("Test "+Check+#TAB$)
If tof=1 : PrintN("true") : Else : PrintN("false") : EndIf
EndMacro
Procedure.b StrBool_eq(a$,b$) : ProcedureReturn Bool(a$=b$) : EndProcedure
Procedure.b StrBool_n_eq(a$,b$) : ProcedureReturn Bool(a$<>b$) : EndProcedure
Procedure.b StrBool_a(a$,b$) : ProcedureReturn Bool(a$>b$) : EndProcedure
Procedure.b StrBool_b(a$,b$) : ProcedureReturn Bool(a$<b$) : EndProcedure
Procedure.b NumBool_eq(a$,b$) : ProcedureReturn Bool(Val(a$)=Val(b$)) : EndProcedure
Procedure.b NumBool_n_eq(a$,b$) : ProcedureReturn Bool(Val(a$)<>Val(b$)) : EndProcedure
Procedure.b NumBool_a(a$,b$) : ProcedureReturn Bool(Val(a$)>Val(b$)) : EndProcedure
Procedure.b NumBool_b(a$,b$) : ProcedureReturn Bool(Val(a$)<Val(b$)) : EndProcedure
Procedure Compare(a$,b$,cs.b=1,num.b=0)
If Not cs : a$=UCase(a$) : b$=UCase(b$) : EndIf
PrintN("a = "+a$) : PrintN("b = "+b$)
If Not num : StrTest(" a=b ",StrBool_eq(a$,b$)) : Else : StrTest(" a=b ",NumBool_eq(a$,b$)) : EndIf
If Not num : StrTest(" a<>b ",StrBool_n_eq(a$,b$)) : Else : StrTest(" a<>b ",NumBool_n_eq(a$,b$)) : EndIf
If Not num : StrTest(" a>b ",StrBool_a(a$,b$)) : Else : StrTest(" a>b ",NumBool_a(a$,b$)) : EndIf
If Not num : StrTest(" a<b ",StrBool_b(a$,b$)) : Else : StrTest(" a<b ",NumBool_b(a$,b$)) : EndIf
EndProcedure
If OpenConsole()
PrintN("String comparison - ")
a$="Abcd" : b$="abcd"
PrintN(#CRLF$+"- case sensitive:")
Compare(a$,b$)
PrintN(#CRLF$+"- case insensitive:")
Compare(a$,b$,0)
a$="1241" : b$="222"
PrintN(#CRLF$+"- num-string; lexically compared:")
Compare(a$,b$)
PrintN(#CRLF$+"- num-string; numerically compared:")
Compare(a$,b$,1,1)
Input()
EndIf

View file

@ -0,0 +1,35 @@
s1 = 'mnopqrs'
s2 = 'mnopqrs'
s3 = 'mnopqr'
s4 = 'nop'
s5 = 'nOp'
OUTPUT = 'Case sensitive comparisons:'
OUTPUT = LEQ(s1, s2) s1 ' and ' s2 ' are equal (LEQ).'
OUTPUT = IDENT(s1, s2) s1 ' and ' s2 ' are equal (IDENT).'
OUTPUT =
OUTPUT = LNE(s1, s3) s1 ' and ' s3 ' are not equal (LNE).'
OUTPUT = ~LEQ(s1, s3) s1 ' and ' s3 ' are not equal (~LEQ).'
OUTPUT = DIFFER(s1, s3) s1 ' and ' s3 ' are not equal (DIFFER).'
OUTPUT =
OUTPUT = LGE(s1, s3) s1 ' is greater than or equal to ' s3 ' (LGE).'
OUTPUT = LLE(s3, s1) s3 ' is less than or equal to ' s1 ' (LLE).'
OUTPUT =
OUTPUT = LGT(s4, s1) s4 ' is greater than ' s1 ' (LGT).'
OUTPUT = LLT(s1, s4) s1 ' is less than ' s4 ' (LLT).'
OUTPUT =
OUTPUT = "Case insensitive comparison:"
OUTPUT = LEQ(s4, REPLACE(s5, &UCASE, &LCASE)) s4 ' and ' s5 ' are equal.'
OUTPUT =
OUTPUT = 'String and numeric conversions and comparisons:'
OUTPUT = EQ('1234', 1234) '"1234" and 1234 are equal (coerce to integer).'
OUTPUT = LEQ('1234', 1234) '"1234" and 1234 are equal (coerce to string).'
OUTPUT =
OUTPUT = GT('1234', 1233) '"1234" is greater than 1233 (numeric comparison).'
OUTPUT = LT('1233', 1234) '"1233" is less than 1234 (numeric comparison).'
END