home *** CD-ROM | disk | FTP | other *** search
- ############################################################################
- #
- # File: longstr.icn
- #
- # Subject: Procedure to match longest string
- #
- # Authors: Jerry Nowlin, Steve Wampler, Kenneth Walker, Bob
- # Alexander, and Richard Goerwitz
- #
- # Date: June 1, 1991
- #
- ###########################################################################
- #
- # 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
-