我在matlab中有一个树形结构,如下所示:
node =
sub: [1x4 struct]
其中每个子节点也是一个节点。
node.sub(1) =
sub: [1x4 struct]
等。叶子节点有空子。假设我有一个节点,我正在遍历树。有没有办法检查节点'对象'是否与树中的任何对象相同?我不是在说价值是一样的。我希望'对象'是一样的。
例如:
mynode = tree.sub(1).sub(1);
isobjectequal(mynode, tree.sub(1).sub(1))
答案 0 :(得分:2)
MATLAB中的struct
在技术上并不是你谈论它的意义上的“对象”。如果我创建一个结构然后将其指定为另一个结构中的字段,那么这两个现在是解耦的。对第一个结构所做的任何更改都不会反映在我们刚刚制作的副本中。
a = struct('a', 2);
b = struct('b', a);
a.a = 3
% b.b.a == 2
您实际上只能可靠地检查两个struct
的值是否相等。
如果您确实想要验证您所比较的两个struct
是否以相同方式创建,那么可以 以递归方式通过struct
并确定两个结构中每个元素的memory location是否相同。这意味着结构是相同的和它们是用相同的底层数据创建的。
对于一个非常简单的非深层嵌套结构,这可能看起来像这样。
function bool = isSameStruct(A, B)
fmt = get(0, 'Format');
format debug;
memoryLocation = @(x)regexp(evalc('disp(x)'), '(?<=pr\s*=\s*)[a-z0-9]*', 'match');
if isequaln(A, B)
bool = true;
elseif ~isequal(sort(fieldnames(A)), sort(fieldnames(B)))
bool = false;
else
fields = fieldnames(A);
bool = true;
for k = 1:numel(fields)
if ~isequal(memoryLocation(A.(fields{k})), memoryLocation(B.(fields{k})))
bool = false;
break;
end
end
end
format(fmt);
end
<强>更新强>
另一种方法是为节点使用实际的handle
个对象。基本类看起来像这样。
classdef Node < handle
properties
Value
Children
end
methods
function self = Node(value)
self.Value = value;
end
function addChild(self, node)
self.Children = cat(2, self.Children, node)
end
end
end
答案 1 :(得分:1)
如果您正在搜索&#34;参考相等&#34;我想你应该使用handle个对象:
如果要确定是否有不同的句柄对象,请使用isequal 在所有对象属性中具有相同的数据。如果您愿意,请使用== 确定句柄变量是否引用同一个对象。
treeTest.m
function treeTest()
root = TreeItem('Root');
child = TreeItem('Child');
grandChild = TreeItem('GrandChild');
grandGrandChild = TreeItem('GrandGrandChild');
grandGrandChild2 = TreeItem('GrandGrandChild');
root.Children{end+1} = child;
child.Children{end+1} = grandChild;
grandChild.Children{end+1} = grandGrandChild;
grandChild.Children{end+1} = grandGrandChild2;
findItem(root, grandGrandChild2)
function findItem(tree, childToFind)
if ~numel(tree.Children)
return;
end
disp(['Traversing in ', tree.Name]);
for i=1:numel(tree.Children)
disp(['Iteration step: ', num2str(i)])
if tree.Children{i} == childToFind
disp(['Found! Name is ', tree.Children{i}.Name]);
return;
end
findItem(tree.Children{i}, childToFind);
end
end
end
TreeItem.m
classdef TreeItem < handle
properties
Name;
Children;
end
methods
function obj = TreeItem(name)
obj.Name = name;
obj.Children = {};
end
end
end
输出
Traversing in Root
Iteration step: 1
Traversing in Child
Iteration step: 1
Traversing in GrandChild
Iteration step: 1
Iteration step: 2
Found! Name is GrandGrandChild
正如您所看到的那样,两个grand-grand-child对象在属性方面是相同的,但输出上的Iteration step: 2
条目证明,第一个曾祖父的子项被跳过,因为函数是寻找第二个。
isequal
和==
之间的差异:
>> grandGrandChild = TreeItem('GrandGrandChild');
grandGrandChild2 = TreeItem('GrandGrandChild');
>> isequal(grandGrandChild, grandGrandChild2)
ans = 1
>> grandGrandChild == grandGrandChild2
ans = 0