我的目标是使用括号表示法来打印带有N个节点的所有形式的树,可以根据上下文无关的语法定义如下:
?树是空的
?(TT)具有左右子节点的节点
例如,所有具有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
什么是定型子类型,为什么String不是一个子类型?我认为&用于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_Line可以接受一个参数,那么为什么缺少参数?而且我也不理解私有类型“ Indefinite_Vectors.Vector”错误。
确定子类型是其大小在编译时已知的子类型。有关它的更多信息,请参见Ada Wikibooks。您的String没有声明的长度,因此是不确定的类型。
解决方案:
如果您知道将存储在Vector中的String的大小,则可以对其进行声明,例如:
package String_Vectors is new Ada.Containers.Vectors (Index_Type => Natural, Element_Type => String(1 .. 20));
请改用Unbounded_String,这也将需要更改您的其他代码(在各处使用Unbounded_String或将其强制转换为String):
package String_Vectors is new Ada.Containers.Vectors (Index_Type => Natural, Element_Type => Unbounded_String);
使用Indefinite_Vector而不是Vector:
package String_Vectors is new Ada.Containers.Indefinite_Vectors (Index_Type => Natural, Element_Type => String);
所有下一个错误(也是带有“&”的错误)都是第一个问题的错误定义,该错误定义了String_Vectors。
更新到新版本的问题:
这里仍然需要注意的几件事:
追加(第21和22行)-当您想将一种类型添加到另一种类型(在您的示例中是字符串和矢量光标)时,必须将其中一种强制转换为另一种。因此,此行应如下所示:
Strings.Append("(" & Natural'Image(String_Vectors.To_Index(T)) & ".)");
首先,将向量Cursor转换为Natural,然后将其转换为String,以便可以将它们连接起来。
Put_Line(第29行)-在Ada中,您不能以这种方式打印Vectors(如果我很好猜,这就是您想要做的吗?)如果要打印vector的内容,则必须打印其每个元素:
for Item of Tree(X) loop Put_Line(Item); end loop;
其他错误应该再次受到这两个问题的影响(至少所有内容对我来说都是编译正常的)。