Ada通用平均功能

时间:2011-03-06 21:12:30

标签: ada

我有一个函数可以平均记录数组中的某个数值。此值是自然类型或枚举类型增量。我正确地总结了这些值,但我的问题是:如何将数组的长度变为泛型类型,以便它可以将整数和delta类型数分开?

3 个答案:

答案 0 :(得分:3)

在您的记录数组中使用'长度属性;即使你的界限有些奇怪,如-18..3,或者像奶酪......果子这样的枚举,这样做的好处就是始终有效。

类似的东西:

Function Average( Input : In Array_of_Records ) Return float is
  -- You say you already have a summation function, so...
  Sum : Natural:= Summation( Input );
Begin
  Return Sum / Input'Length;
End Average;

您可能需要转换数字类型,通过说浮点数(总和)等,因为Ada没有自动类型“促销”。

答案 1 :(得分:3)

这有一些缺陷,但这更接近你想要的吗?

NWS。

with Ada.Text_Io;

procedure Main is

   generic
      type Element_T is private;
      Zero : Element_T;
      One : Element_T;
      type Vec_T is array (Integer range <>) of Element_T;
      with function "+"(Left, Right : in Element_T) return Element_T is <>;
      with function "/"(Left, Right : in Element_T) return Element_T is <>;

   package Arrayops is
      function Sum (Vec : in Vec_T) return Element_T;
      function Count (Vec : in Vec_T) return Element_T;
      function Average (Vec : in Vec_T) return Element_T;
   end Arrayops;

   package body Arrayops is
      function Sum (Vec : in Vec_T) return Element_T is
         S : Element_T := Zero;
      begin
         for I in Vec'First .. Vec'Last loop
            S := S + Vec(I);
         end loop;
         return S;
      end Sum;

      function Count (Vec : in Vec_T) return Element_T is
         C : Element_T := Zero;
      begin
         for I in Vec'First .. Vec'Last loop
            C := C + One;
         end loop;
         return C;
      end Count;

      function Average (Vec : in Vec_T) return Element_T is
         S : constant Element_T := Sum (Vec);
         Len : constant Element_T := Count (Vec);
      begin
         return S / Len;
      end Average;
   end Arrayops;

   type Fl_Arr_T is array (Integer range <>) of Float;
   package Fl_Arr is new Arrayops (Element_T => Float,
                                   Zero => 0.0,
                                   One => 1.0,
                                   Vec_T => Fl_Arr_T);

   type Int_Arr_T is array (Integer range <>) of Integer;
   package Int_Arr is new Arrayops (Element_T => Integer,
                                    Zero => 0,
                                    One => 1,
                                    Vec_T => Int_Arr_T);


   My_Ints   : constant Int_Arr_T (1 .. 5) := (6,7,5,1,2);
   My_Floats : constant Fl_Arr_T (1 .. 7) := (6.1,7.2,5.3,1.4,2.5,8.7,9.7);

   Int_Sum   : constant Integer := Int_Arr.Sum (My_Ints);
   Int_Count : constant Integer := Int_Arr.Count (My_Ints);
   Int_Avg   : constant Integer := Int_Arr.Average (My_Ints);

   Float_Sum   : constant Float := Fl_Arr.Sum (My_Floats);
   Float_Count : constant Float := Fl_Arr.Count (My_Floats);
   Float_Avg   : constant Float := Fl_Arr.Average (My_Floats);

begin

   Ada.Text_Io.Put_Line ("Integers => Sum: " & Integer'Image (Int_Sum) & ", Count: " & Integer'Image (Int_Count) & ", Avg: " & Integer'Image (Int_Avg));
   Ada.Text_Io.Put_Line ("Floats   => Sum: " & Float'Image (Float_Sum) & ", Count: " & Float'Image (Float_Count) & ", Avg: " & Float'Image (Float_Avg));

end Main;

结果:

整数=&gt;总和:21,数量:5,平均值:4

Floats =&gt;总和:4.09000E + 01,计数:7.00000E + 00,平均值:5.84286E + 00

答案 2 :(得分:1)

在这里扩展Shark8 ......

Ada允许您将数组类型声明为不受约束。像

这样的东西
type Array_of_Records is array (Natural range <>) of My_Record;

为您提供一种类型,可用于具有起始和结束数组索引的记录数组,这些索引可以是Natural范围内的任何位置。

我可以用这种类型做的一件非常棒的事情是将它用作子程序参数,如下所示:

function Sum (Vector : in Array_of_Records) return Natural;

好的,所以在这个例程中,我怎么知道数组边界在哪里?通过使用属性,如:

for index in Vector'first..Vector'last loop

for index in Vector'range loop

当然,为了实现这一点,您必须将完美大小的数组传递给Sum例程。补充不是你拥有的。假设你有一个巨大的数组(缓冲区的种类),并不是所有的值都有效?好吧,你跟踪什么是有效值,并使用切片传递仅>

Rec_Buffer : Array_of_Records (1..10_000);
Last_Valid_Rec : Natural := 0;
....
--// Rec_Buffer gets loaded with 2,128 values or something. We pass it into Sum
--// like so:
Ada.Text_IO ("Sum of vector is " & 
             natural'image(Sum (Rec_Buffer (1..Last_Valid_Rec));

(警告 - 未编译的代码)