home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1986 / 08 / shammas.aug < prev   
Text File  |  1986-08-31  |  11KB  |  369 lines

  1.  
  2. -----------------------------------------------------------------
  3. Listing 1.  Ada procedure to swap two integers.
  4.  
  5.  
  6. procedure Swap(First, Second : in out integer) is
  7.  
  8. Temporary : integer;
  9.  
  10. begin
  11.      Temporary := First;
  12.      First := Second;
  13.      Second := Temporary;
  14. end Swap;
  15.  
  16.  
  17. Listing 2.  Generic Ada procedure to swap two scalars.  
  18.  
  19.  
  20. generic
  21.      -- Declare generic types here
  22.      type Object is private;
  23.      -- List heading for generic routines here
  24. procedure Swap(First, Second : in out Object);
  25.  
  26. -- Full definition of procedures is below
  27. procedure Swap(First, Second : in out Object) is
  28.  
  29. Temporary : Object;
  30.  
  31. begin
  32.      Temporary := First;
  33.      First := Second;
  34.      Second := Temporary;
  35. end Swap;
  36.  
  37.  
  38.  
  39.  
  40. Listing 3.  Generic Ada procedure to return the next element in a circular 
  41. list.
  42.  
  43. generic
  44.      type Circular_Item is (<>);
  45. function Fetch_Next_In_Circular_List(Member : Circular_Item)
  46.                                      return Circular_Item;
  47.  
  48. -- Declare the generic function body 
  49. function Fetch_Next_In_Circular_List(Member : Circular_Item)
  50.                                      return Circular_Item is
  51.  
  52. begin
  53.       -- use predefined LAST attribute
  54.      if Member = Circular_Item'LAST 
  55.        then -- use predefined FIRST attribute
  56.           return Circular_Item'FIRST;
  57.        else -- use predefined SUCCesive attribute
  58.           return Circular_Item'SUCC(Member);
  59.      end if;
  60. end Fetch_Next_In_Circular_List;
  61.  
  62.  
  63. -- Examples for generic instantiation are
  64. -- type Day is (MON, TUE, WED, THU, FRI, SAT, SUN);
  65. -- function NextDay is new Fetch_Next_In_Circular_List(Day);
  66. -- NextDay(TUE) returns WED
  67. -- NextDay(SUN) returns MON
  68.  
  69. -- subtype Hours is integer 0..24;
  70. -- function NextTime is new Fetch_Next_In_Circular_List(Hours);
  71. -- NextTime(4) returns 5
  72. -- NextTime(24) returns 0
  73.  
  74.  
  75. Listing 4.   Generic Ada function that scans an array and returns the largest 
  76. value found. 
  77.  
  78. generic
  79.      type Index_Range is range <>;
  80.      type Member is range <>;
  81.      type List is array (Index_Range) of Member;
  82. funtion Largest(L : List) return Member;
  83.  
  84. funtion Largest(L : List) return Member is
  85.  
  86. -- Initilaize Big to lowest value
  87. Big : Member := Member'FIRST; 
  88.  
  89. begin
  90.      for i in Index_Range loop
  91.           if Big < L(i) then Big := L(i); end if;
  92.      end loop;
  93.      return Big;
  94. end Largest;
  95.  
  96.  
  97. Listing  5.   Generic  Ada function to return the  average  of  a floating 
  98. point typed array. 
  99.  
  100. generic
  101.      type Index_Range is range <>;
  102.      type Element is digits <>;
  103.      type List is array (Index_Range) of Element;
  104. function Average(X : List) return Element;
  105.  
  106. function Average(X : List) return Element is
  107.  
  108. Sum : Element := 0.0; -- Initialize summation
  109.  
  110. begin
  111.      for i in Index_Range loop
  112.           Sum := Sum + X(i);
  113.      end loop;
  114.      return (Sum / FLOAT(Index_Range));
  115. end Average;
  116.  
  117.  
  118. Listing 6.   Generic Ada procedure to solve the mathematical root of a 
  119. function. 
  120.  
  121. generic
  122.      type Floating is digits <>;
  123.      -- declaring a subprogram parameter
  124.      -- the "with" keyword distinguishes it from other
  125.      -- declared generic routines.
  126.      with function F_of_X(X : Floating) return Floating;
  127. procedure Root(Guess : in out Floating; Accuracy : in Floating;
  128.                Iter_Max : in INTEGER; Converge : out BOOLEAN);
  129.  
  130. procedure Root(Guess : in out Floating; Accuracy : in Floating;
  131.                Iter_Max : in INTEGER; Converge : out BOOLEAN) is
  132.  
  133.   Increment, Diff : Floating;
  134.   Iter : INTEGER := 0;
  135.  
  136. begin
  137.      Converge := true;
  138.      loop
  139.           if abs(Guess) > 1.0 
  140.                then Increment := 0.01 * Guess;
  141.                else Increment := 0.01;
  142.           end if;
  143.           Diff := 2.0 * Increment * F_of_X(Guess) /
  144.                   (F_of_X(Guess + Increment) - 
  145.                    F_of_X(Guess - Increment));
  146.           Guess := Guess - Diff;
  147.           Iter := Iter + 1;
  148.           if Iter > Iter_Max then Converge := false; end if;
  149.           if (abs(Diff) < Accuracy) or (not Converge) 
  150.                then exit;
  151.           end if;
  152.      end loop;
  153. end Root;
  154.  
  155.  
  156.  
  157. Listing 7.  Generic Shell sort procedure in Ada.
  158.  
  159. generic
  160.      type Range_Index is (<>);
  161.      type Data is private;
  162.      type List is array (Range_Index range <>) of Data;
  163.      -- declare generic function/operator
  164.      with function ">"(A,B : Data) return BOOLEAN;
  165. procedure Shell_Sort(L : in out List; Num : INTEGER);
  166.  
  167. procedure Shell_Sort(L : in out List; Num : INTEGER) is
  168.  
  169. Offset, I, K : INTEGER;
  170. Tempo : Data;
  171. In_Order : BOOLEAN;
  172.  
  173. begin
  174.      Offset := Num;
  175.      while Offset > 1 loop
  176.           Offset := Offset / 2;
  177.           loop
  178.                In_Order := true;
  179.                K := Num - Offset;
  180.                for J in 1..K loop
  181.                     I := J + Offset;
  182.                     if L(J) > L(I) -- Using the ">" operator
  183.                          then In_Order := false;
  184.                               Tempo := L(I);
  185.                               L(I)  := L(J);
  186.                               L(J)  := Tempo;
  187.                     end if;
  188.                end loop;
  189.                if In_Order then exit; end if;
  190.           end loop; -- open loop
  191.      end loop; -- while loop
  192. end Shell_Sort;
  193.  
  194.  
  195.  
  196.  
  197. Listing  8.   Generic Modula-2 function to search for a  specific value in an 
  198. integer/cardinal array. 
  199.  
  200.  
  201. PROCEDURE LinearSearch(VAR Element : ARRAY OF WORD;  (* input  *)
  202.                        SearchValue : INTEGER;        (* input  *)
  203.                        VAR Index : CARDINAL          (* output *)
  204.                       ) : BOOLEAN;
  205.                          
  206. VAR Found : BOOLEAN;
  207.     hi : CARDINAL;
  208.  
  209. BEGIN
  210.      Index ;= 0; hi := HIGH(Element); Found := FALSE;
  211.      WHILE (Index <= hi) AND (NOT Found) DO
  212.           (* Logical expression tested converts  *)
  213.           (* array element into an integer type  *)
  214.           IF SearchValue = INTEGER(Element[Index])
  215.                THEN Found := TRUE
  216.                ELSE INC(Index)
  217.           END; (* IF *)
  218.      END; (* WHILE *)
  219.      RETURN Found
  220. END LinearSearch;
  221.  
  222.  
  223.  
  224. Listing 9.  Generic Modula-2 Shell sort procedure.
  225.  
  226.  
  227.  
  228. procedure ShellSort(VAR L : ARRAY OF WORD;        (* in/out *)
  229.                     Sample1, 
  230.                     Sample2 : ARRAY OF WORD;      (* input *)
  231.                     Num : CARDINAL;               (* input *)
  232.                     IsGreater : UserDefinedProc); (* input *)
  233.  
  234. VAR Offset, I, K, DataSize : CARDINAL;
  235.     In_Order : BOOLEAN;
  236.  
  237.  
  238. PROCEDURE FetchItem(Item_Num : CARDINAL;       (* input *)
  239.                     VAR Item : ARRAY OF WORD); (* output *)
  240. (* Procedure copies an element from main array in Item *)
  241.  
  242. VAR Count : CARDINAL;
  243.  
  244. BEGIN
  245.      FOR Count := 0 TO DataSize - 1 DO
  246.           Item[Count] := L[Count + Item_Num * DataSize]
  247.      END;
  248. END FetchItem;
  249.  
  250.  
  251. PROCEDURE PutItem(Item_Num : CARDINAL;       (* input *)
  252.                   VAR Item : ARRAY OF WORD); (* output *)
  253. (* Procedure copies an element to main array *)
  254.  
  255. VAR Count : CARDINAL;
  256.  
  257. BEGIN
  258.      FOR Count := 0 TO DataSize - 1 DO
  259.            L[Count + Item_Num * DataSize] := Item[Count]
  260.      END;
  261. END PutItem;
  262.  
  263.  
  264. BEGIN (* --------------- Shell Sort -------------------*)
  265.      DataSize := HIGH(Sample1) + 1;
  266.      Offset := Num;
  267.      WHILE Offset > 1 DO
  268.           Offset := Offset DIV 2;
  269.           REPEAT
  270.                In_Order := TRUE;
  271.                K := Num - 1 - Offset;
  272.                FOR J := 0 TO K DO
  273.                     I := J + Offset;
  274.                     FetchItem(I,Sample1);
  275.                     FetchItem(J,Sample2);
  276.                     (* Logical expression employs     *)
  277.                     (* user-supplied logical function *)
  278.                     IF IsGtreater(Sample1,Sample2) 
  279.                          THEN In_Order := FALSE;
  280.                               (* Swap items *)
  281.                               PutItem(J, Sample1);
  282.                               PutItem(I, Sample2);
  283.                     END; (* IF *)
  284.                END; (* FOR *)
  285.           UNTIL In_Order;
  286.      END; (* WHILE *)
  287. END Shell_Sort;
  288.  
  289.  
  290.  
  291. Listing 10.  Modula-2 function compares "Frequency" fields.
  292.  
  293.  
  294. PROCEDURE GreaterFreq(Field1, Field2 : ARRAY OF WORD) : BOOLEAN;
  295.  
  296. VAR Ptr1, Ptr2 : POINTER TO NameUse; (* record type defined  *)
  297.                                      (* elsewhere in program *)
  298. BEGIN
  299.      (* Get address of records *)
  300.      RecordPointer1 := ADR(Field1);
  301.      RecordPointer2 := ADR(Field2);
  302.      RETURN RecordPointer1^.Frequency > RecordPointer2^.Frequency
  303. END GreaterFreq;
  304.  
  305.  
  306. Listing  11.    Iterator  example.  Professional  Pascal  program compares  a  
  307. list  of names with a list of keys  and  report  any matches found. 
  308.  
  309.  
  310. program Pick_Data;
  311.  
  312. const MAX_NAME = 1000;
  313.       MAX_KEY = 50;
  314.  
  315. type Name_type = String(80);
  316.      Name_Array = array [1..MAX_NAME] of Name_type;
  317.      Key_Array  = array [1..MAX_KEY]  of Name_type;
  318.      Count = array [1..MAX_KEY] of Integer;
  319.  
  320. var K : Integer;
  321.     Names : Name_Array;
  322.     Keys  : Key_Array;
  323.     Key_Count : Count;    
  324.     Num_Name, Num_Key : Integer;
  325.     Name_File, Key_File : Text;
  326.  
  327.  
  328.     iterator Select(Num_Name, Num_Key) : 
  329.                    (Key_Index, Name_Index : Integer);
  330.     var I, J : Integer;
  331.     begin
  332.       (* Loop counter are automatic in Prof. Pascal *)
  333.       for I := 1 to Num_Key do
  334.           for J := 1 to Num_Name do
  335.                if Keys[J] = Names[I] 
  336.                     then begin 
  337.                          Key_Count[J] := Key_Count[J] + 1;
  338.                          Yield(J,I)
  339.                     end
  340.     end;
  341.      
  342. begin
  343.      Reset(Name_File,'NAMES.TXT'); Num_Name := 0; 
  344.      Reset(Key_File,'KEYS.TXT');  Num_Key := 0;
  345.      (* Read names from name file *)
  346.      while not EOF(Name_File) do begin
  347.           Num_Name := Num_Name + 1;
  348.           Readln(Name_File,Names[Num_Name]);
  349.      end;
  350.      Close(Name_File);
  351.      (* Read keys from name file *)
  352.      while not EOF(Key_File) do begin
  353.           Num_Key := Num_Key + 1;
  354.           Key_Count[Num_Key] := 0;
  355.           Readln(Key_File,Keys[Num_Key]);
  356.      end;
  357.      Close(Key_File);
  358.      (* Loop that finds and displays matching keys and names *)
  359.      for Key_Index, Name_Index in Select(Num_Name, Num_Key) do
  360.           Writeln(Keys[Key_Index,'is key # ",Key_Index,
  361.                   ' matches name # ',Name_Index);
  362.  
  363.      (* Loop to display name matching frequency *)
  364.      for K := 1 to Num_Key do
  365.        Writeln('Key # ',K,' has found ',Key_Count,' matched names');
  366.  
  367.                         [END]
  368.  
  369.