“Ada”的实际错误;元素“U型”;当向量包含字符串时,必须是确定的子类型

“Ada”的实际错误;元素“U型”;当向量包含字符串时,必须是确定的子类型,ada,Ada,我的目标是以括号表示法打印具有N个节点的所有形式的树,可以根据上下文无关语法定义如下: T→ 树是空的 T→ (T.T)具有左右子节点的节点 例如,具有3个节点的所有树将如下所示: () ()(()) ().() (.(.) ()(()) 我用Ada编写了以下代码 with Ada.Containers; use Ada.Containers; with Ada.Containers.Vectors; with Ada.Text_IO; use Ada.Text_IO; with Ada.C

我的目标是以括号表示法打印具有N个节点的所有形式的树,可以根据上下文无关语法定义如下:

T→ 树是空的

T→ (T.T)具有左右子节点的节点

例如,具有3个节点的所有树将如下所示:

()

()(())

().()

(.(.)

()(())

我用Ada编写了以下代码

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

with Ada.Text_IO; use Ada.Text_IO;

with Ada.Command_Line;
procedure Ass1 is 
     X: Positive := Positive'Value(Ada.Command_Line.Argument(1));
    package String_Vectors is new Ada.Containers.Vectors
     (Index_Type   => Natural,
      Element_Type => String);

    function tree(N: Integer) return String_Vectors.Vector is
    Strings : String_Vectors.Vector;    
    begin
        if N = 1 then
            Strings.Append("(.)");
            return Strings;
        end if;
        for T in tree(N - 1).Iterate loop
            Strings.Append("(" & T & ".)");
            Strings.Append("(." & T & ")");
        end loop;
    return Strings;
    end tree;


begin
    Ada.Text_IO.Put_Line(Ass1(X));
end;
但我得到了这个错误:

ass1.adb:9:09: instantiation error at a-convec.ads:375
ass1.adb:9:09: unconstrained element type in array declaration
ass1.adb:11:27: actual for "Element_Type" must be a definite subtype
ass1.adb:21:36: invalid operand types for operator "&"
ass1.adb:22:37: invalid operand types for operator "&"
ass1.adb:29:16: no candidate interpretations match the actuals:
ass1.adb:29:16: missing argument for parameter "Item" in call to "Put_Line" declared at a-textio.ads:259
ass1.adb:29:26: expected type "Standard.String"
ass1.adb:29:26: found private type "Ada.Containers.Vectors.Vector" from instance at line 9
ass1.adb:29:26:   ==> in call to "Put_Line" at a-textio.ads:263
x86_64-linux-gnu-gnatmake-7: "ass1.adb" compilation error
什么是确定的子类型?为什么字符串不是?我认为&在Ada中用于字符串连接

---------编辑---------- 根据答案,我将代码更改为:

with Ada.Containers; use Ada.Containers;
with Ada.Containers.Indefinite_Vectors;

with Ada.Text_IO; use Ada.Text_IO;

with Ada.Command_Line;
procedure Tree is
         X: Positive := Positive'Value(Ada.Command_Line.Argument(1));
        package String_Vectors is new Ada.Containers.Indefinite_Vectors
         (Index_Type   => Natural,
          Element_Type => String);

        function Tree(N: Integer) return String_Vectors.Vector is
        Strings : String_Vectors.Vector;
        begin
            if N = 1 then
                Strings.Append("(.)");
                return Strings;
            end if;
            for T in Tree(N - 1).Iterate loop
                Strings.Append("(" & T & ".)");
                Strings.Append("(." & T & ")");
            end loop;
        return Strings;
        end Tree;


begin
    Ada.Text_IO.Put_Line(Tree(X));
end;
但我仍然得到以下错误:

gnatmake tree.adb 6
gcc -c tree.adb
tree.adb:21:36: invalid operand types for operator "&"
tree.adb:22:37: invalid operand types for operator "&"
tree.adb:29:16: no candidate interpretations match the actuals:
tree.adb:29:16: missing argument for parameter "Item" in call to "Put_Line" declared at a-textio.ads\
:498
tree.adb:29:26: expected type "Standard.String"
tree.adb:29:26: found private type "Ada.Containers.Indefinite_Vectors.Vector" from instance at line \
9
tree.adb:29:26:   ==> in call to "Put_Line" at a-textio.ads:508
gnatmake: "tree.adb" compilation error


操作数问题仍然存在。Put_行根据文档可以接受一个参数,那么为什么缺少一个参数呢?我也不理解私有类型“不定向量.向量”的错误

确定子类型是编译时已知大小的子类型。有关它的更多信息,您可以在中找到。您的字符串没有声明长度,因此是不确定类型

解决方案:

  • 如果您知道将存储在Vector中的字符串的大小,则可以声明它,例如:
  • 改为使用无界_字符串,这也需要更改进一步的代码(在任何地方使用无界_字符串或将其转换为字符串):
  • 使用不定_向量代替向量:
  • 接下来的所有错误(这一个也带有“&”)都是第一个问题(字符串_向量定义错误)的结果


    更新至问题的新版本:

    这里需要注意的事情仍然很少:

  • 追加(第21行和第22行)-当您想将一种类型添加到另一种类型(在您的示例中为字符串和向量游标)时,必须将其中一种类型强制转换为另一种类型。因此,这条线看起来应该是:
  • 首先将向量光标强制转换为Natural,然后将其强制转换为String,以便将它们连接起来

  • Put_Line(第29行)-在Ada中,您不能以这种方式打印向量(如果我猜这是您想要做的吗?),如果您想要打印向量的内容,您必须打印其每个元素:

  • 其他错误也应该是,这两个问题的影响(至少对我来说,所有的东西都可以编译并工作)。

    一个确定的子类型是一个在编译时已知大小的子类型。有关它的更多信息,您可以在中找到。您的字符串没有声明长度,因此是不确定类型

    解决方案:

  • 如果您知道将存储在Vector中的字符串的大小,则可以声明它,例如:
  • 改为使用无界_字符串,这也需要更改进一步的代码(在任何地方使用无界_字符串或将其转换为字符串):
  • 使用不定_向量代替向量:
  • 接下来的所有错误(这一个也带有“&”)都是第一个问题(字符串_向量定义错误)的结果


    更新至问题的新版本:

    这里需要注意的事情仍然很少:

  • 追加(第21行和第22行)-当您想将一种类型添加到另一种类型(在您的示例中为字符串和向量游标)时,必须将其中一种类型强制转换为另一种类型。因此,这条线看起来应该是:
  • 首先将向量光标强制转换为Natural,然后将其强制转换为String,以便将它们连接起来

  • Put_Line(第29行)-在Ada中,您不能以这种方式打印向量(如果我猜这是您想要做的吗?),如果您想要打印向量的内容,您必须打印其每个元素:

  • 其他错误也应该如此,这两个问题的影响(至少对我来说,所有的东西都可以编译并工作)。

    (3)几乎肯定是最好的。进行此更改后,您将发现更多有趣的错误!哦,是的,尤其是当你尝试添加不同大小的字符串时:)@thindil,
    Natural'Image…
    这东西并没有达到它应该达到的效果。它将一个看起来像
    (.)
    的字符串转换成一个数字,正如您在结果中所看到的:
    /tree4(0.)(.0)(1.)(.1)(2.)(.2)(3.)(.3)
    @zengod,额外的空间实际上是一个符号(如果numebr是负数,它应该是-)。Natural是Integer的子类型,对于'Image and'Value(以及其他),使用了基类型(即,在本例中,它相当于整数(X)'base'Image)。@Darkstkhan,不,我的错,我读错了问题-这个数字是树中元素的索引,而整个问题是关于递归的-将向量的前一个元素插入向量的下一个元素。因此,第21行和第22行应该是:
    Strings.Append(“&Tree(N-1).Element(String_Vectors.To_Index(T))&”)(3)几乎可以肯定是最好的。进行此更改后,您将发现更多有趣的错误!哦,是的,尤其是当你尝试添加不同大小的字符串时:)@thindil,
    Natural'Image…
    这东西并没有达到它应该达到的效果。它将一个看起来像
    (.)
    的字符串转换成一个数字,正如您在结果中所看到的:
    /tree4(0.)(.0)(1.)(.1)(2.)(.2)(3.)(.3)
    @zengod,额外的空间实际上是一个符号(如果numebr是负数,它应该是-)。Natural是Integer的子类型,对于'Image and'Value(以及其他),使用了基类型(即,在本例中,它相当于整数(X)'base'Image)。@Darkstkhan,不,我的错,我读错了问题-这个数字是树中元素的索引,而整个问题是关于递归的-将向量的前一个元素插入向量的下一个元素。因此,第21行和第22行应该是:
    Strings.Append(“&Tree(N-1).Element(String_Vectors.To_Index(T))&”)
    
        package String_Vectors is new Ada.Containers.Vectors
         (Index_Type   => Natural,
          Element_Type => String(1 .. 20));
    
        package String_Vectors is new Ada.Containers.Vectors
         (Index_Type   => Natural,
          Element_Type => Unbounded_String);
    
        package String_Vectors is new Ada.Containers.Indefinite_Vectors
         (Index_Type   => Natural,
          Element_Type => String);
    
    Strings.Append("(" & Natural'Image(String_Vectors.To_Index(T)) & ".)");
    
    for Item of Tree(X) loop
       Put_Line(Item);
    end loop;