############################################################################ # # File: longstr.icn # # Subject: Procedure to match longest string # # Author: Jerry Nowlin # # Date: June 1, 1991 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # Contributors: Stephen B. Wampler, Kenneth Walker, Bob Alexander, # and Richard E. Goerwitz # ############################################################################ # # Version: 1.9 # ############################################################################ # # longstr(l,s,i,j) works like any(), except that instead of taking a # cset as its first argument, it takes instead a list or set of # strings (l). Returns i + *x, where x is the longest string in l # for which match(x,s,i,j) succeeds. Fails if no match occurs. # # Defaults: # s &subject # i &pos if s is defaulted, otherwise 1 # j 0 # # Errors: # The only manual error-checking that is done is to test l to # be sure it is, in fact, a list or set. Errors such as non- # string members in l, and non-integer i/j parameters, are # caught by the normal Icon built-in string processing and sub- # scripting mechanisms. # ############################################################################ procedure longstr(l,s,i,j) local elem, tmp_table static l_table initial l_table := table() # # No-arg invocation wipes out all static structures, and forces an # immediate garbage collection. # if (/l, /s) then { l_table := table() collect() # do it NOW return # return &null } # # Is l a list, set, or table? # type(l) == ("list"|"set"|"table") | stop("longstr: list, set, or table expected (arg 1)") # # Sort l longest-to-shortest, and keep a copy of the resulting # structure in l_table[l] for later use. # if /l_table[l] := [] then { tmp_table := table() # keys = lengths of elements, values = elements every elem := !l do { /tmp_table[*elem] := [] put(tmp_table[*elem], elem) } # sort by key; stuff values, in reverse order, into a list every put(l_table[l], !sort(tmp_table,3)[*tmp_table*2 to 2 by -2]) } # # First element in l_table[l] to match is the longest match (it's # sorted longest-to-shortest, remember?). # return match(!l_table[l],s,i,j) end