Ada排序复合数组

时间:2019-02-24 21:22:50

标签: sorting ada

我在Ada很新,我有一个问题。 Demo_Array_Sort中的Rosetta Code使用函数“ <”来确定如何对数组进行排序。按名称按字母顺序对其进行排序。我了解这部分。我的问题来自哪里:

如果数组Data有多个具有相同名称的条目,并且我想按值 in Name对列表进行排序,我该怎么做?我试图弄乱重新定义“ <”功能,但没有用。请帮忙!

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO;           use Ada.Text_IO;
with Ada.Containers.Generic_Array_Sort;

procedure Demo_Array_Sort is

function "+" (S : String) return Unbounded_String renames To_Unbounded_String;

type A_Composite is
 record
         Name  : Unbounded_String;
         Value : Unbounded_String;
 end record;

function "<" (L, R : A_Composite) return Boolean is
 begin
 return L.Name < R.Name;
 end "<";

procedure Put_Line (C : A_Composite) is
 begin
      Put_Line (To_String (C.Name) & " " & To_String (C.Value));
 end Put_Line;

type An_Array is array (Natural range <>) of A_Composite;

procedure Sort is new Ada.Containers.Generic_Array_Sort (Natural, A_Composite, An_Array);

  Data : An_Array := (1 => (Name => +"Joe",    Value => +"5531"),
 2 => (Name => +"Adam",   Value => +"2341"),
 3 => (Name => +"Bernie", Value => +"122"),
 4 => (Name => +"Walter", Value => +"1234"),
 5 => (Name => +"David",  Value => +"19"));

begin
   Sort (Data);
 for I in Data'Range loop
      Put_Line (Data (I));
 end loop;
end Demo_Array_Sort; 

示例数据:

 Data : An_Array := (1 => (Name => +"Joe",    Value => +"5531"),
 2 => (Name => +"Adam",   Value => +"2341"),
 3 => (Name => +"Bernie", Value => +"122"),
 4 => (Name => +"Walter", Value => +"1234"),
 5 => (Name => +"David",  Value => +"19")
 6 => (Name => +"David", Value => +"42")
 7 => (Name => +"David", Value => +"5"));

将输出:

Adam 2341   
Bernie 122   
David 5
David 19
David 42   
Joe 5531   
Walter 1234 

2 个答案:

答案 0 :(得分:4)

在概述中,

  1. Value的{​​{1}}分量更改为标量子类型,对于该标量子类型,A_Composite已经适当地defined;我选择了Natural

    "<"
  2. 现在很容易编写处理type A_Composite is record Name : Unbounded_String; Value : Natural; end record; 的{​​{1}}:

    "<"
  3. 相应地更新L.Name = R.Name

    function "<" (L, R : A_Composite) return Boolean is
    begin
       if L.Name < R.Name then return True;
       elsif L.Name = R.Name then return L.Value < R.Value;
       else return False;
       end if;
    end "<";
    

数据:

Put_Line

控制台:

Put_Line (To_String (C.Name) & Natural'Image(C.Value));

答案 1 :(得分:1)

以下是使用Vector容器的示例。

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Vectors;

procedure Main is
   type Surname is (Smith, Jones, Chen, Chavez);
   type Name is (John, Francis, Leslie, Margaret, George, Walter);

   type Person is record
      First : Name;
      Last  : Surname;
   end record;

   function Less(P1: Person; P2 : Person) return boolean is
   begin
      if P1.Last < P2.Last then
         return true;
      elsif
        P1.Last = P2.Last then
         return P1.First < P2.First;
      else
         return false;
      end if;
   end Less;


   procedure Print(P : Person) is
   begin
      Put_Line(P.Last'Image & ", " & P.First'Image);
   end Print;

   package Person_Vector is new Ada.Containers.Vectors(Index_Type   => Natural,
                                                       Element_Type => Person);
   use Person_Vector;
   package Person_Sort is new Generic_Sorting(Less);
   use Person_Sort;

   V : Vector;
   Temp : Person;
begin

   for N in Name loop
      for S in Surname loop
         Temp.First := N;
         Temp.Last := S;
         V.Append(Temp);
      end loop;
   end loop;

   Put_Line("Unsorted list:");
   for P of V loop
      Print(P);
   end loop;
   New_Line;

   Sort(V);

   Put_Line("Sorted list:");

   for P of V loop
      Print(P);
   end loop;

end Main;

该程序的输出为:

Unsorted list:
SMITH, JOHN
JONES, JOHN
CHEN, JOHN
CHAVEZ, JOHN
SMITH, FRANCIS
JONES, FRANCIS
CHEN, FRANCIS
CHAVEZ, FRANCIS
SMITH, LESLIE
JONES, LESLIE
CHEN, LESLIE
CHAVEZ, LESLIE
SMITH, MARGARET
JONES, MARGARET
CHEN, MARGARET
CHAVEZ, MARGARET
SMITH, GEORGE
JONES, GEORGE
CHEN, GEORGE
CHAVEZ, GEORGE
SMITH, WALTER
JONES, WALTER
CHEN, WALTER
CHAVEZ, WALTER

Sorted list:
SMITH, JOHN
SMITH, FRANCIS
SMITH, LESLIE
SMITH, MARGARET
SMITH, GEORGE
SMITH, WALTER
JONES, JOHN
JONES, FRANCIS
JONES, LESLIE
JONES, MARGARET
JONES, GEORGE
JONES, WALTER
CHEN, JOHN
CHEN, FRANCIS
CHEN, LESLIE
CHEN, MARGARET
CHEN, GEORGE
CHEN, WALTER
CHAVEZ, JOHN
CHAVEZ, FRANCIS
CHAVEZ, LESLIE
CHAVEZ, MARGARET
CHAVEZ, GEORGE
CHAVEZ, WALTER

请注意,这些字段是按照程序中指定其枚举的顺序排序的。