我试图编写一个算法来删除background-size: cover;
background-position: center center;
中的重复项。
vector<struct xxxx*>
当你看到我的结构时,它就像一棵树,但指针却没有按顺序排列。指针可以指向任何其他(实际上不是大多数)其他指针。并且向量不包含结构但是指针,因此我无法使用std算法来帮助我。
我试图删除具有完全相同的值和相同的两个指针的重复项,但同时如果我有两个相似的结构(让我们说struct xxxx{
int value; // This is just to make you understand
xxxx* one;
xxxx* two;
}
和{{1} })和A
或B
指向C.one
。然后我需要将其更改为C.two
而反之亦然。
换句话说:如果B
,则移除A
并将A == B
更改为指向B
。
我想我可以写蛮力,所以如果没有更好的算法我会自己写。
答案 0 :(得分:0)
昨天,我试图向一位使用N平方解决方案解决N log N问题的同事解释一个非常类似问题的合理方法。
首先创建一个辅助结构,它基本上是一个围绕xxxx *的包装器,其中一个比较运算符检查内容(不是指针值),可能还有一些其他实用程序函数。这个包装器结构并不是严格需要的,而只是使用xxxx *,但从经验来看,我认为它使任务更清晰。
创建一个这样的帮助器结构的std :: set,你只能在其中插入唯一的元素,并且可能是另一个集合,你将在其中插入递归的未解析的元素。
循环遍历原始向量,并在每个位置通过其子项进行递归。如果您已经在唯一集中触及了一个子节点,那么这是该子指针的最终值。如果你击中一个与唯一元素匹配的子元素而不是它匹配的元素,那么修复那个让你在那里的指针。如果还有可能是空指针应该在递归的底部,并且如果循环是可能的,你需要检测它们(使用递归未解析的集合)和一些关于如何处理循环的决定。在某些时候,您点击已解析的唯一元素并将其添加到唯一集。
这个想法的性能甚至可靠性取决于循环的深度和复杂性以及您想要对循环做什么。有一些混乱的情况,循环会映射到另一个循环,但检测到这可能是非常棘手的。如果你的阶段“像一棵树”意味着“没有循环”那么递归就会干净而有效,而没有明确管理递归未解析元素的额外复杂性。
显然,当你退出递归并且检测到“在早期的递归过程中已经做过”时,我忽略了检测唯一/非唯一的一些咕噜咕噜的工作细节,因为你在上面的主循环中点击了一个项目递归。但是当你编写代码的相关部分时,所有这些细节都应该非常明显。
编辑:要了解尽管在顺序循环中嵌套递归,但有多少节点访问,请从指针的角度进行思考。我们最多跟踪每个指针一次(预先检测到一些重复项,而不遵循它们的指针)。对于N个节点,有N个顶级指针(如果我理解你的描述正确)和明显少于2N的内部指针(它越像树,它就越接近N-1个内部指针,而不是2N) 。因此,每个节点的访问次数平均少于3次,其中少数访问需要预查找和后递归查找,每次查找都是log U,其中U是到目前为止找到的唯一项目数。因此,我们可以轻而易举地看到6 N log N
的界限。