Thread View: net.lang.pascal
5 messages
5 total messages
Started by idc
Wed, 06 Aug 1986 10:31
Linear search again
Author: idc
Date: Wed, 06 Aug 1986 10:31
Date: Wed, 06 Aug 1986 10:31
57 lines
2151 bytes
2151 bytes
A small contribution to the debate re. forced termination of linear search
in Pascal. Below is a little program in ISO level 1 Pascal that
illustrates the method. It is not original; for example see the paper
R.G. Dromey, "Forced termination of loops", Softw.pract.exp., pp 29-40,
Vol. 15 No. 1, January 1985.
which I strongly recommend. It has only two disadvantages over the
state indicators method: (i) The index variable cannot have the same
subrange as the indextype of the array (but that is not possible with
conformant array parameters anyway), and (ii) really the same as (i),
-maxint may not be the lower bound (in general pred(lowerbound) must be
defined. N.B. Neither a goto nor a Boolean in sight! Read the ref. for
full details.
Here is the example dressed up as a "find a character in a string" function.
------------
program ForcedTerminationTest(Output);
function find(ch:Char; string: packed array[lo..hi:Integer] of Char):Integer;
{
* pre: lo > -maxint
* post: if find(ch,string) = -maxint then true else string[find(ch,string)]=ch
}
var
i, N: Integer;
begin
{ -- Initialise loop variables }
i := lo-1; N := hi;
{ -- Linear search with possible forced termination on hit }
while i <> N do
if string[i+1]=ch then N := i else i := i+1;
{ -- Test termination state }
if i <> hi then find := i+1 else find := -maxint
end{ find};
begin
{ -- Test cases }
writeln(Output,
find('!', 'Forced termination is a good thing!'):1,
' ',
find('?', 'There is no question mark in this string')
)
end.
----------
ps. am really ian@ux.cs.man.ac.uk but am experiencing trouble posting from there.
Re: Linear search again
Author: Chris Torek
Date: Thu, 07 Aug 1986 21:54
Date: Thu, 07 Aug 1986 21:54
67 lines
2864 bytes
2864 bytes
In article <871@minster.UUCP> idc@minster.UUCP (idc) writes:
>Below is a little program in ISO level 1 Pascal that
>illustrates [a] method [of forced termination of linear search].
>
>Here is the example dressed up as a "find a character in a string" function.
>
>function find(ch:Char; string: packed array[lo..hi:Integer] of Char):Integer;
>{
>* pre: lo > -maxint
>* post: if find(ch,string) = -maxint then true else string[find(ch,string)]=ch
>}
> var
> i, N: Integer;
>begin
> { -- Initialise loop variables }
> i := lo-1; N := hi;
> { -- Linear search with possible forced termination on hit }
> while i <> N do
> if string[i+1]=ch then N := i else i := i+1;
> { -- Test termination state }
> if i <> hi then find := i+1 else find := -maxint
>end{ find};
Actually, I am not entirely satisified with any of these notations.
If I were instructing a person to find an object, I might say
something like `search starting at low and going forward, until
either you find it or you get to hi'; so in a computer language,
I might prefer, e.g.:
{ return the position of the specified character in the given
string, or -maxint if not found }
function find(ch: char; string: packed array[l..h: integer] of char):
integer;
var
i, answer: integer;
begin
{ assume it will not be found }
answer := -maxint;
{ iterate only until it is found }
for i in [l..h] until answer <> -maxint do
if string[i] = ch then answer := i
end for;
find := answer
end;
This puts the termination condition directly in the `for' loop.
I think (I am at home or I would check) that the language Mesa,
developed by Xerox, has a loop of this form (indeed, the loop can
declare `i' as well, just for the duration of the loop itself,
which is also appropriate)---though in Mesa one would be more
likely to write
-- apologies for syntax; it has been a while
find: PROC [ch: CHAR, string: LONG STRING]
RETURNS [pos: CARDINAL, found: BOOL];
BEGIN
FOR i:CARDINAL in [0..String.Length[string]] DO
IF string[i] = ch THEN RETURN [i, TRUE];
ENDLOOP;
RETURN [0, FALSE];
END;
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP: seismo!umcp-cs!chris
CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu
Multiple loop exits (was linear search revisited)
Author: Arthur M. Keller
Date: Fri, 08 Aug 1986 09:40
Date: Fri, 08 Aug 1986 09:40
56 lines
2490 bytes
2490 bytes
First, let me say that I am opposed to unrestricted use of GOTOs.
However, I do like the ability to prematurely exit from a construct.
The argument that premature exits from constructs (FOR loops,
functions, etc.) represent multiple exits from the construct is
misguided. There is only one exit from the construct. There are
merely multiple ways of getting there. Having an explicit exit
in a construct is often better than implicitly falling through to
the bottom.
Consider the following way of writing the linear search using invented syntax:
found := false;
FOR "search foo" index := low TO high DO
IF foo[index]=key
THEN location := index;
EXIT "search foo";
ENDIF;
ENDFOR "search foo";
Semantics of naming BEGINs and ENDs:
A loop may be named at either the BEGIN or the END. Both will name the
block. If both are present, they must match exactly.
Semantics of the EXIT construct:
EXIT causes execution to continue at the end of the named BEGIN-END block
if a name is specified, or at the end of the innermost BEGIN-END block
if no name is specified.
To implement the semantics of CONTINUE using the EXIT construct:
FOR "outer" ....
BEGIN "inner"
EXIT "inner"; (* means CONTINUE with the next iteration of the loop *)
EXIT "outer"; (* means leave the FOR loop altogether *)
END "inner";
ENDFOR "outer";
An EXIT is particularly helpful for thinking like:
you know you're done when
abcdfefgtgf
or ajsadjdfjaldjla
or asdasdsadsadasd
Once you make any of these true, you can exit.
An EXIT is also helpful for handling exceptions and errors without
unnecessarily cluttering up code to ensure than nothing is done
in the event of an error.
Arthur
--
------------------------------------------------------------------------------
Arpanet: ARK@SALLY.UTEXAS.EDU
UUCP: {gatech,harvard,ihnp4,pyramid,seismo}!ut-sally!ark
Re: Linear search again
Author: Ben Cranston
Date: Sat, 09 Aug 1986 00:56
Date: Sat, 09 Aug 1986 00:56
20 lines
1492 bytes
1492 bytes
In article <2785@umcp-cs.UUCP> chris@maryland.UUCP (Chris Torek) writes:
> find: PROC [ch: CHAR, string: LONG STRING]
> RETURNS [pos: CARDINAL, found: BOOL];
> BEGIN
> FOR i:CARDINAL in [0..String.Length[string]] DO
> IF string[i] = ch THEN RETURN [i, TRUE];
> ENDLOOP;
> RETURN [0, FALSE];
> END;
I always avoided these nonstandard returns because they make it painful to
drop in debug print statements. I would always slap in WRITELN(MYARGS) at
the top, and WRITELN('Returning from FIND') at the bottom, and wonder why
I never saw the 'Returning from FIND' output... If you are trying to find
an infinite loop this can be really misleading.
--
umd5.UUCP <= {seismo!umcp-cs,ihnp4!rlgvax}!cvl!umd5!zben
Ben Cranston zben @ umd2.UMD.EDU Kingdom of Merryland Sperrows 1100/92
umd2.BITNET "via HASP with RSCS"
Re: debug prints (was Re: Linear search again)
Author: Chris Torek
Date: Sat, 09 Aug 1986 01:17
Date: Sat, 09 Aug 1986 01:17
39 lines
2206 bytes
2206 bytes
>In article <2785@umcp-cs.UUCP> I wrote:
[an example of how a Mesa programmer would probably write `find']:
>> find: PROC [ch: CHAR, string: LONG STRING]
>> RETURNS [pos: CARDINAL, found: BOOL];
>> BEGIN
>> FOR i:CARDINAL in [0..String.Length[string]] DO
>> IF string[i] = ch THEN RETURN [i, TRUE];
>> ENDLOOP;
>> RETURN [0, FALSE];
>> END;
In article <1174@umd5> zben@umd5.umd.edu (Ben Cranston) writes:
>I always avoided these nonstandard returns because they make it painful to
>drop in debug print statements. I would always slap in WRITELN(MYARGS) at
>the top, and WRITELN('Returning from FIND') at the bottom, and wonder why
>I never saw the 'Returning from FIND' output... If you are trying to find
>an infinite loop this can be really misleading.
Ah, but in Mesa, no one ever seems to use debug prints: for there is
a very complete debugger that is always accessible. For that matter,
if you did wish to wrap `find' with debug print statements, you could
simply rename the procedure to `findInternal' and add
-- Again, details may be wrong; all the manuals are four miles
-- away.
find: PROC [ch: CHAR, string: LONG STRING]
RETURNS [pos: CARDINAL, found: BOOL];
BEGIN
Msg.PutMsg["Enter find"L];
[pos, found] _ internalFind[ch, string];--`_' represents left-arrow
Msg.PutMsg["Exit find"L];
RETURN [pos, found];
END;
Indeed, this technique works in every language.
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP: seismo!umcp-cs!chris
CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads