2011-03-06 73 views
4

我有一个函数,它从记录数组中平均某个数值。此值是自然类型或枚举类型三角洲。我有它正确地总结了值,但我的问题是这样的:我如何获得一个数组的长度到一个泛型类型,以便它可以划分整数和三角洲类型数字?Ada通用平均函数

回答

3

在您的数组记录中使用'Length属性;这具有始终工作的优势,即使您的界限有点​​奇怪,如-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; 

您可能需要转换的数值类型,说浮法(点心)等,作为艾达不会进行自动型“的促销活动。”

+0

这只返回一个浮点数,我以为海报要求的函数会返回一个浮点数或离散类型? – NWS 2011-03-07 17:33:56

+0

正确;处理“或”的“返回浮动”部分。 – Shark8 2011-03-07 22:32:59

+0

我解释说或'它会根据泛型的实例返回这个或那个',因为海报要求一个通用的:) – NWS 2011-03-09 10:29:51

1

扩展在Shark8一点在这里...

阿达允许你声明数组类型为无约束。像

type Array_of_Records is array (Natural range <>) of My_Record; 

的东西给你,可用于与开始和结束数组的索引,可能是在Natural范围内的任何记录阵列类型。

之一漂亮的东西,我可以用这样的类型做的是把它作为一个子程序参数,像这样:

function Sum (Vector : in Array_of_Records) return Natural; 

OK,使例程中,我怎么知道数组边界是?通过使用属性,就像这样:

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

for index in Vector'range loop 

当然这个工作,你必须通过一个完全大小的数组到您的总和程序。假设这不是你所拥有的。假设你有一个巨大的数组(缓冲区),并不是所有的值都是有效的?那么,你跟踪什么是有效值,并通过使用切片仅通过那些

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)); 

(警告 - 未编译的代码)

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; 

结果:

整数=>萨姆:21,计数:5,平均:4

浮标=>总:4.09000E + 01,次数:7.00000E + 00,平均: 5.84286E + 00