使用Ada的列表的笛卡尔积

问题描述 投票:1回答:1

我目前正在Ada中对此(https://rosettacode.org/wiki/Cartesian_product_of_two_or_more_lists)进行编程,我正在尝试在不同的集合之间进行笛卡尔积。我需要帮助弄清楚它,主要问题是如何能够声明空对,并计算如果它是空的,那么结果应该是空的。谢谢!

我要使用的数字:

{1, 2} × {3, 4}
{3, 4} × {1, 2}
{1, 2} × {}
{} × {1, 2}

我的代码:

with Ada.Text_IO; use Ada.Text_IO; -- Basically importing the functions that will be used to print out the results.

procedure Hello is -- Procedure is where variables & functions are declared!
    type T_Pair is array(1..2) of Integer; -- Declare a type of array that contains a set of 2 numbers (Used for final result!).
    type T_Result is array(1..4) of T_Pair; -- Declare a type of array that contains a set of T_Pair(s), used to hold the result.

    Demo1 : T_Result;
    Demo1A : T_Pair := (1, 2);
    Demo1B : T_Pair := (3, 4);


    function Fun_CartProd(p1: T_Pair; p2: T_Pair) return T_Result is
        results: T_Result;
        i: integer := 1;
    begin
        for j in 1..2 loop
            for h in 1..2 loop
                results(i) := (p1(j), p2(h));
                i := i + 1;
            end loop;
        end loop;
        return results;
    end Fun_CartProd;
begin -- This is where the statements go
    Demo1 := Fun_CartProd(Demo1A, Demo1B);
    for K in 1 .. Demo1'length loop
        Put(" [");
        for B in 1 .. Demo1(K)'length loop
            Put(Integer'Image(Demo1(K)(B)));
            if Demo1(K)'length /= B then
                Put(",");
            end if;
        end loop;
        Put("]");
        if Demo1'length /= K then
            Put(",");
        end if;
    end loop;
    Put_Line(""); -- Create a new line.
end Hello;
ada
1个回答
0
投票

由于每组整数可以是任意长度,包括空,所以我将从可以处理所有这些情况的类型开始:

type Integer_Set is array(Positive range <>) of Integer;

您可以这样表示空集:

Empty_Set : constant Integer_Set(1..0) := (others => <>);

另一个问题不仅在于每个集合中有多少个元素,还包括您将要找到多少个集合。为此,我建议使用某种容器。数组不能在这里工作,因为每个单独的集合可以具有不同的大小(包括空),但是Ada可以处理各种“不确定的”容器。这是使用向量的示例:

package Set_Vectors is new Ada.Containers.Indefinite_Vectors
   (Index_Type   => Positive,
    Element_Type => Integer_Set);

然后您可以将一个空结果表示为:

Empty_Vector : constant Set_Vectors.Vector := Set_Vectors.Empty_Vector;

现在您可以创建一个接受集合向量并返回笛卡尔乘积的函数,该笛卡尔积也将成为集合向量:

function Cartesian_Product(Inputs : Set_Vectors.Vector) return Set_Vectors.Vector;

如果输入集之一为空,则返回Empty_Vector。您可以通过检查输入集的长度属性结果来检查其中一个输入集是否为空。如果为空,则为0。例如:

for Set of Inputs loop
   if Set'Length = 0 then
      return Empty_Vector;
   end if;
   -- Maybe do other stuff here if you need
end loop;

注意,您呈现的逻辑仅假设输入对。我没有足够的经验来转换您的逻辑以考虑变量输入,但是如果您需要,也许有人可以对此发表评论。

© www.soinside.com 2019 - 2024. All rights reserved.