重新排列相关数据的递归

时间:2012-07-23 22:42:16

标签: matlab recursion

我有一个结构,结果如下:

result.me={dad,grandpa,half_sis}
result.step_mom={half_sis}
result.dad={me,grandpa,half_sis}
result.half_sis={mom,me,dad,grandpa}
result.grandpa={me,dad,half_sis}

结果是细胞阵列的结构,并显示每个元素的亲属(通过血液)。我编写了以下函数,它接受各自的class_name(我,妈妈等),它是各自的单元格并返回所有亲属。    例如,recur_getchildren(妈妈,{爷爷,我,姐姐},结果)应该返回妈妈的所有血亲和所有亲戚的亲戚(依此类推,直到没有人离开):

  

ANS = half_sis,我,爸爸,爷爷,

所以即使妈妈与我,爸爸或爷爷无关,他们仍然会被列入名单。上面的例子是一个简化,对于我的问题,将会有更多代来跟踪。我试着做以下事情,但这并不完全正常。我究竟做错了什么?有更简单的方法吗?

 function tot=recur_getchildren(class_name,each_cell,result)
%gets all the children for an element and all its descendants
global gresult


if(~isfield(gresult,class_name))

    gresult.(class_name)=1;

    w=size(each_cell,2);
    tot=struct(char(class_name),1); %include the class_name item as well
    %tot is a struct where all the keys indicate the progeny, and val is 0/1

    for m=1:w


        %the child must not have already been searched previously
        if(~isfield(gresult,each_cell{m}))

            gresult.(char(each_cell{m}))=1;
            tot.(char(each_cell{m}))=1;
            % copy all contents over to parent
            if(sum(~strcmp(each_cell,'')) && sum(isfield(result,char(each_cell{m}))))
                s=size(result.(char(each_cell{m})),2);
                %run iteratively over all the children of each member of
                %each_cell
                for j=1:s

                    %struct of all childs
                    %gresult.(each_cell{m})=1;
                    if(~isfield(gresult,char(result.(char(each_cell{m})){j})))
                        tot.(char(result.(char(each_cell{m})){j}))=1;
                        % tot_records.(char(result.(char(each_cell{m})){j}))=1

                        tot2=recur_getchildren(each_cell{m},result.(char(each_cell{m}))(j),result);


                        %check off this so that we dont search it again
                        gresult.(char(result.(char(each_cell{m})){j}))=1;
                          %keep looping to get all children


                        %loop through result struct
                        if(size(tot2,2)~=0)
                            fn=fieldnames(tot2);
                            for p=1:size(fn)
                                str=fn(p);
                                recur_getchildren(char(str),result.(char(str)),result)
                                gresult.(char(str))=1;
                            end
                        end
                    end

                end
            end


        end
    end
else
    tot=[];
end
end

1 个答案:

答案 0 :(得分:0)

我认为可以使用一些字符串评估和set operations来完成。

如果我们有

result = 

      me: {'dad'  'grandpa'  'half_sis'}
      step_mom: {'half_sis'}
     dad: {'me'  'grandpa'  'half_sis'}
half_sis: {'mom'  'me'  'dad'  'grandpa'}
 grandpa: {'me'  'dad'  'half_sis'}

我们可以选择一个人并找到亲人。

s = result.step_mom

s = 

    'half_sis'

使用一些字符串操作,我们可以找到这样的亲戚的亲戚:

eval(char(strcat('result.',s)))

ans = 

    'mom'    'me'    'dad'    'grandpa'

这给了我们一个函数的想法:

function children=recur_getchildren(result,person)

%Find all relatives of given person
s = eval(strcat('result.',person));

%Go through all relatives found in s
for i=1:size(s,2)
    children = union(s(i),eval(char(strcat('result.',s(i)))));
end

%remove orignal relative from other relatives
children=setdiff(children,person);

让我们测试一下:

relatives=recur_getchildren(result,'mom')

relatives = 

    'dad'    'grandpa'    'half_sis'    'me'

请注意,您需要将step_mom更改为mom(反之亦然),以便在所有情况下都能正常工作。

编辑:只是让它递归。像这样:

function [All_relatives,not_examined]=...
recur_getchildren(result,person,examined,All_relatives)


%Find all relatives of given person
s = eval(strcat('result.',person));

children = '';

%Go through all relatives found in s
for i=1:size(s,2)
    children = union(children,eval(char(strcat('result.',s(i)))));
end

%Save all found relatives
All_relatives = union(All_relatives,children);
All_relatives = union(All_relatives,s);

%Save all examined persons
examined = union(examined,s);
examined = union(examined,person);
not_examined = setdiff(All_relatives,examined);


count=0;
while length(not_examined)>0
    count=count+1;
    examined = union(examined,not_examined(count ));
    [new_relatives,not_examined] = recur_getchildren(result,char(not_examined(count)),examined,All_relatives);
    All_relatives = union(All_relatives,new_relatives);

end

这很快就放在了一起,但应该有效。运行时将检查和* All_relatives *输入为空字符串。

children=recur_getchildren(result,'me','','')