我必须存储可以由任何类型组成的通用树的每个节点。我必须在ADA中执行此操作,但我只需要思考方式。
我必须将每个节点存储在通用元素的数组中。 这样的方式是数组没有诸如Ada中的加法之类的操作, 我的意思是我不能做:
Array3:=Array1+Array2;
例如,“ +”运算符对于递归计数非常有用。
有一种方法可以通过将每个结果存储在数组上而不使用任何运算符来递归地完成它?
还是迭代进行算法更方便?
谢谢。
EDIT我尝试使用数组的串联运算符的ADA中的代码
function Get_all_nodes (Current_Node : in Tree) return Something_Concatenation.Element_Array is
array_of_results:Something_Concatenation.Element_Array(1..50);
begin
if (Tree_is_null(Current_Node)) then
return array_of_results;
else
array_of_results(1):=Get_value_of_node(Current_Node);
array_of_results:= array_of_results & Get_all_nodes(Get_access_to_parent1(Current_Node));
array_of_results:= array_of_results & Get_all_nodes(Get_access_to_parent1(Current_Node));
end if;
return array_of_results;
end Get_all_nodes;
致谢
答案 0 :(得分:1)
在Ada中,concatenation operator是&
符号。数组可以串联在一起。如果愿意,可以使用它进行递归调用,但是由于堆栈使用情况,我不建议这样做。编译器可能会对其进行优化,但是由于您将返回不受约束的类型,因此可能不会。
您没有指定树类型或提供任何代码,因此我无法帮助您如何从树类型中获取元素,但这是使用泛型进行数组连接的示例:
with Ada.Text_IO; use Ada.Text_IO;
procedure Hello is
-- Generic, since you asked about it in a generic context
generic
type Element_Type is limited private;
package Concatenation is
type Element_Array is array(Positive range <>) of Element_Type;
end Concatenation;
-- Integer example
package Integer_Concatenation is new Concatenation(Integer);
use type Integer_Concatenation.Element_Array;
a1 : Integer_Concatenation.Element_Array(1..4) := (others => 1);
a2 : Integer_Concatenation.Element_Array(1..5) := (others => 2);
a3 : Integer_Concatenation.Element_Array := a1 & a2;
a4 : Integer_Concatenation.Element_Array := 1 & 2 & 3 & 4 & 5;
-- Custom record type
type Something is null record;
package Something_Concatenation is new Concatenation(Something);
use type Something_Concatenation.Element_Array;
a5 : Something_Concatenation.Element_Array(1..4) := (others => <>);
a6 : Something_Concatenation.Element_Array(1..5) := (others => <>);
a7 : Something_Concatenation.Element_Array := a5 & a6;
s1,s2,s3,s4,s5 : Something;
a8 : Something_Concatenation.Element_Array := s1 & s2 & s3 & s4 & s5;
begin
-- Show the integer array results
Put_Line("Hello, world!");
for E of a3 loop
Put(Integer'Image(E));
end loop;
New_Line;
for E of a4 loop
Put(Integer'Image(E));
end loop;
New_Line;
end Hello;
编辑:您尝试递归来编辑问题。这是递归的替代示例,因此您可以看到一些语法和设置选项。因为您提供的内容不多,所以我不得不整理一堆东西。另外,之前我通过泛型提供了数组类型,因为您的原始问题是在泛型的上下文中提出的。在现实生活中,我不会只为数组类型创建泛型(可以在任何地方完成)。取而代之的是,您将为树使用通用名称,并且此答案中提到的所有内容都将在该通用名称的上下文中完成。由于您没有提供任何基本的通用代码,因此我不想提出一个完整的示例。我只是想向您展示,串联将适用于通过泛型创建的类型。
function Get_all_nodes (Current_Node : in Tree) return
Something_Concatenation.Element_Array
is
use Something_Concatenation;
use type Element_Array;
Next_Node : Tree;
begin
if (Tree_is_null(Current_Node)) then
return (1..0 => <>); -- returns a null array
else
-- for the next call, get the node after this one
-- or replace this with a call for the previous one
-- or whatever your mechanism for getting a new
-- node is. You can also call Get_Next_Node
-- in the return statement. I Pulled it out
-- here so you would see the step
Next_Node := Get_Next_Node(Current_Node);
-- here you need to figure out the order of nodes
-- and how you want to traverse them. This is
-- just a basic (probably logically wrong) example
-- to show you the syntax you were trying to emulate.
-- you might also have to alter the order of these
-- elements to get the array element order you want
return Element_Array'(1 => Get_Value_of_Node(Current_Node))
& Get_All_Nodes(Next_Node);
-- Alternate with no "Next_Node" variable:
-- return Element_Array'(1 => Get_Value_of_Node(Current_Node))
-- & Get_All_Nodes(Get_Next_Node(Current_Node));
end if;
end Get_all_nodes;
答案 1 :(得分:0)
因此,我尝试了递归和迭代版本。 在迭代版本中,我得到了类似的结果,我使用了在我的情况下允许的堆栈
WordPress
此时我在某些地方出错了
function get_all_nodes(Current_Node:in Tree) return Stack is
--declarations
My_Stack: Stack;
copy:Tree;
finished: Boolean:=False;
begin
--Initialisation
copy:=Current_Node;
My_Stack:=Initialisation;
--beginning by pushing the first node on the stack
push_on_stack(stack,copy.all.elt);
while(copy/=null or finished =False) loop
--check that we can put the first parent on stack
if(copy.all.parent1/=null and not Found_in_Stack(My_Stack,copy.all.parent1.all.elt)) then
copy:=copy.all.parent1;
push_on_stack(stack,copy.all.elt);
end if;
--check that we can put the second parent on stack
if(copy.all.parent2/=null and not Found_in_Stack(My_Stack,copy.all.parent2.all.elt)) then
copy:=copy.all.parent2;
push_on_stack(stack,copy.all.elt);
end if;
--check we are on case where both parents are already on stack or both null
if(copy.all.parent1=null and copy.all.parent2=null) or
(Found_in_Stack(My_Stack,copy.all.parent1.all.elt) and (Found_in_Stack(My_Stack,copy.all.parent2.all.elt))) then
--check we are on case where we are back to first node and then it's finished
if(copy.all.elt=Current_Node.all.elt) then
finished:=True;
else
--go back to previous node thanks to stack
copy:= First_Element_after_top_of_stack(My_Stack);
end if;
end if;
end loop;
return My_Stack;
end get_all_nodes;
似乎在第一个条件之后执行第二个条件,并且我得到了错误,因为copy.all.parent2.all.elt = null而不是堆栈和树上的通用元素。
我通过以下代码尝试了递归版本:
copy.all.parent2/=null and not Found_in_Stack(My_Stack,copy.all.parent2.all.elt)
我有一个CONSTRAINT_ERROR的长度检查失败。
现在,我将通过阅读scrapgod链接来检查如何最小化长度问题,否则我将检查是否可以使用Ada容器。
再次感谢大家的帮助。 问候。