Simple Searching algorithms

It is always interesting (a bit frightening) to pose the following simple problems to third year students. Only about 33% of the class seem to be able to do them!

Suppose we have an integer array named MyArray, with possible subscripts running from 0 through 100 in which we have the N elements of a list stored in the array elements MyArray[1] ... MyArray[N].

Write a parameterised function (in any language of your choice, but as syntactically correct as possible) that will accept the array and the value of N as actual parameters or arguments, scan the list and return the value of the smallest element in the list.

Write another parameterised function that will accept the array, the value of N and a further integer Item as actual parameters or arguments and return a suitable indication of whether Item can be found among the elements of the list.

Indicate any precautions that might be needed to handle values of N that might be out of range.

Many people simply do not appreciate how dangerous it is to program algorithms like these without paying attention to the very real problems that arise if attempts are made to access array elements that do not exist. And many do not read the specification - the list to be processed is not stored in elements List[0] ... List[N- 1] but in List[1] ... List[N]. As a result, many attempts at solutions have nasty off-by-one errors.


C++ version

// Test bed program for simple functions // P.D. Terry, Rhodes University, 2000 *) #include <iostream.h> #include <assert.h> #include <stdlib.h> #define bool int int smallest (int Arr[], int Length) { // return smallest of the elements in Arr[1] ... Arr[Length] assert(Length < 100); int min = Arr[1]; for (int i = 2; i <= Length; i++) { if (Arr[i] < min) min = Arr[i]; } return min; } bool found(int Arr[], int Length, int Item) { // return true iff Item is to be found in Arr[1] ... Arr[Length] assert(Length < 100); Arr[0] = Item; for (int i = Length; Arr[i] != Item; i--); return i != 0; } void main (void) { int MyArray[100], Item = 45, N = 15; for (int i = 1; i <= N; i++) cout << (MyArray[i] = 4 + rand() % 100) << "\n"; cout << "Smallest:" << smallest(MyArray, N) << "\n"; if (found(MyArray, N, Item)) cout << Item << " found\n"; else cout <<"Item not found"; }


Java version

import java.io.*; import java.util.*; public class Comp { // Test bed program for simple functions // P.D. Terry, Rhodes University, 2000 *) static void assert(boolean condition, String s) { if (!condition) System.err.println(s); } static int smallest (int Arr[], int Length) { // return smallest of the elements in Arr[1] ... Arr[Length] assert(Length < 100, "Array bounds exceeded"); int min = Arr[1]; for (int i = 2; i <= Length; i++) { if (Arr[i] < min) min = Arr[i]; } return min; } static boolean found(int Arr[], int Length, int Item) { // return true iff Item is to be found in Arr[1] ... Arr[Length] assert(Length < 100, "Array bounds exceeded"); Arr[0] = Item; int i; for (i = Length; Arr[i] != Item; i--); return i != 0; } public static void main (String[] args) { Random generator = new Random(); int MyArray [] = new int[100]; int Item = 45, N = 15; for (int i = 1; i <= N; i++) { MyArray[i] = 4 + generator.nextInt() % 100; System.out.println(MyArray[i]); } System.out.println("Smallest: " + smallest(MyArray, N)); if (found(MyArray, N, Item)) System.out.println(Item + " found"); else System.out.println(Item + " not found"); } }


Modula-2 version

MODULE Test; IMPORT StdIO, Execution, PseudoRandom; TYPE AnArray = ARRAY [0 .. 100] OF INTEGER; PROCEDURE Smallest (Arr : AnArray; Length : INTEGER) : INTEGER; (* Return smallest of the elements in Arr1] ... Arr[N] *) VAR Min, I : INTEGER; BEGIN Execution.Assert(Length < 100, "Array Bounds exceeded"); Min := Arr[1]; FOR I := 2 TO Length DO IF Arr[I] < Min THEN Min := Arr[I] END END; RETURN Min END Smallest; PROCEDURE Found (Arr : AnArray; Length : INTEGER; Item : INTEGER) : BOOLEAN; (* Return TRUE iff Item is to be found in Array[1] ... Array[Length] *) VAR I : INTEGER; BEGIN Execution.Assert(Length < 100, "Array Bounds exceeded"); Arr[0] := Item; I := Length; WHILE (Arr[I] # Item) DO DEC(I) END; RETURN I > 0 END Found; VAR MyArray : AnArray; Item, N, I : INTEGER; BEGIN N := 15; Item := 45; FOR I := 1 TO N DO MyArray[I] := PseudoRandom.RandomCard(100); StdIO.WriteInt(MyArray[I], 0); StdIO.WriteLn END; StdIO.WriteString("Smallest: "); StdIO.WriteInt(Smallest(MyArray, N), 0); StdIO.WriteLn; StdIO.WriteInt(Item, 0); IF Found(MyArray, N, Item) THEN StdIO.WriteString(" found") ELSE StdIO.WriteString(" not found") END; END Test.


Pascal version

PROGRAM Test; (* Test bed program for simple functions P.D. Terry, Rhodes University, 2000 *) TYPE AnArray = ARRAY [0 .. 100] OF INTEGER; PROCEDURE Assert (Condition : BOOLEAN); BEGIN IF NOT Condition THEN BEGIN WriteLn('Assertion failed'); HALT END END; FUNCTION Smallest (Arr : AnArray; Length : INTEGER) : INTEGER; (* Return smallest of the elements in Arr1] ... Arr[N] *) VAR Min, I : INTEGER; BEGIN Assert(Length < 100); Min := Arr[1]; FOR I := 2 TO Length DO IF Arr[I] < Min THEN Min := Arr[I]; Smallest := Min END; FUNCTION Found (Arr : AnArray; Length : INTEGER; Item : INTEGER) : BOOLEAN; (* Return TRUE iff Item is to be found in Array[1] ... Array[Length] *) VAR I : INTEGER; BEGIN Arr[0] := Item; I := Length; WHILE (Arr[I] <> Item) DO I := I - 1; Found := I > 0 END; VAR MyArray : AnArray; Item, N, I : INTEGER; BEGIN Randomize; N := 15; Item := 45; FOR I := 1 TO N DO BEGIN MyArray[I] := Random(100); WriteLn(MyArray[I]); END; WriteLn('Smallest: ', Smallest(MyArray, N)); IF Found(MyArray, N, Item) THEN WriteLn(Item, ' found') ELSE WriteLn(Item, ' not found') END.


Clang version

PROGRAM Test; (* Test bed program for simple functions P.D. Terry, Rhodes University, 2000 *) CONST TRUE = 1; FALSE = 0; FUNCTION Smallest (Arr [], Length); (* Return smallest of the elements in Arr1] ... Arr[N] *) VAR Min, I; BEGIN IF Length > 100 THEN BEGIN Write('Assertion failed'); RETURN 0 END; Min := Arr[1]; I := 2; WHILE I <= Length DO BEGIN IF Arr[I] < Min THEN Min := Arr[I]; I := I + 1; END; RETURN Min END; FUNCTION Found (Arr[], Length, Item); (* Return TRUE iff Item is to be found in Array[1] ... Array[Length] *) VAR I; BEGIN IF Length > 100 THEN BEGIN Write('Assertion failed'); RETURN FALSE END; Arr[0] := Item; I := Length; WHILE Arr[I] <> Item DO I := I - 1; IF I > 0 THEN RETURN TRUE; IF I = 0 THEN RETURN FALSE; END; VAR MyArray[100], Item, N, I; BEGIN N := 15; Item := 45; I := 1; WHILE I <= N DO BEGIN MyArray[I] := I + 12; Write(MyArray[I]); I := I + 1; END; Write('Smallest: ', Smallest(MyArray, N)); IF Found(MyArray, N, Item) = TRUE THEN Write(Item, ' found'); IF Found(MyArray, N, Item) = FALSE THEN Write(Item, ' not found') END.


Umbriel version

MODULE Test; (* Test bed program for simple functions P.D. Terry, Rhodes University, 2000 *) TYPE AnArray = ARRAY [0 .. 100] OF INTEGER; PROCEDURE Smallest (Arr : AnArray; Length : INTEGER) : INTEGER; (* Return smallest of the elements in Arr1] ... Arr[N] *) VAR Min, I : INTEGER; BEGIN Assert(Length < 100); Min := Arr[1]; FOR I := 2 TO Length DO IF Arr[I] < Min THEN Min := Arr[I] END END; RETURN Min END Smallest; PROCEDURE Found (Arr : AnArray; Length : INTEGER; Item : INTEGER) : BOOLEAN; (* Return TRUE iff Item is to be found in Array[1] ... Array[Length] *) VAR I : INTEGER; BEGIN Assert(Length < 100); Arr[0] := Item; I := Length; WHILE (Arr[I] # Item) DO DEC(I) END; RETURN I > 0 END Found; VAR MyArray : AnArray; Item, N, I : INTEGER; BEGIN N := 15; Item := 45; FOR I := 1 TO N DO MyArray[I] := RANDOM(100); WriteLn(MyArray[I]) END; WriteLn("Smallest: ", Smallest(MyArray, N)); IF Found(MyArray, N, Item) THEN WriteLn(Item, " found") ELSE WriteLn(Item, " not found") END END Test.