带边属性的闭合多边形反转优化咨询:如何避免完整复制多边形
带边属性的闭合多边形反转优化咨询:如何避免完整复制多边形
你遇到的问题很典型——在处理带边属性的闭合多边形反转时,完整复制整个多边形确实会带来不必要的内存开销,尤其是当Point结构体包含大量数据的时候。我们可以通过分析属性的映射关系,用更高效的方式来调整属性,完全避免复制整个多边形。
问题分析
先明确核心逻辑:
- 原多边形中,边
point[i] → point[i+1]的属性存储在point[i].att(闭合多边形中i+1取模n) - 反转多边形后,点顺序变为
point[n-1], point[n-2], ..., point[0],新的边P'[j] → P'[j+1]对应原多边形的边point[n-2-j] → point[n-1-j](同样取模n),因此这条新边的属性应该是原point[n-2-j].att,需要赋值给P'[j].att
优化方案1:用临时数组存储属性(空间O(n),适合属性体积小的场景)
如果Point的属性只有少量数据(比如你的例子里的int),可以先把所有属性提取到临时数组,反转点列表后再重新分配属性:
void reverseMyPoly() { if (m_PList.size() <= 1) return; const size_t n = m_PList.size(); // 先保存所有原始边属性 std::vector<int> temp_att(n); for (size_t i = 0; i < n; ++i) { temp_att[i] = m_PList[i].attribute(); } // 反转点列表 std::reverse(m_PList.begin(), m_PList.end()); // 重新分配属性:新的P'[j]的属性对应原边point[n-2-j]的属性 for (size_t j = 0; j < n; ++j) { size_t original_att_index = (n - 2 - j + n) % n; // +n避免负数 m_PList[j].setAttribute(temp_att[original_att_index]); } }
优化方案2:仅用单个临时变量(空间O(1),最优解)
通过观察属性的传递关系,我们发现反转点列表后,属性可以通过环形移位的方式调整,只需要一个临时变量保存初始值即可:
void reverseMyPoly() { const size_t n = m_PList.size(); if (n <= 1) return; // 第一步:反转点列表 std::reverse(m_PList.begin(), m_PList.end()); // 第二步:环形调整属性,仅需一个临时变量 int temp_att = m_PList[0].attribute(); // 保存第一个点的原始属性(反转后的) for (size_t j = 0; j < n - 1; ++j) { // 当前点的属性替换为下一个点的属性 m_PList[j].setAttribute(m_PList[j+1].attribute()); } // 最后一个点的属性设置为最初保存的临时值 m_PList[n-1].setAttribute(temp_att); }
验证示例
用你提供的测试数据:
原m_PList = {{0,0,0}, {1,0,1}, {2,2,2}, {0,3,3}}
反转点列表后变为:{{0,3,3}, {2,2,2}, {1,0,1}, {0,0,0}}
执行属性调整后:
P'[0].att变为2(原point[2].att)P'[1].att变为1(原point[1].att)P'[2].att变为0(原point[0].att)P'[3].att变为3(原point[3].att)
和你原代码的输出完全一致,但没有任何多边形复制操作,内存开销几乎为零。
为什么这个环形调整有效?
反转点列表后,每个点P'[j]对应的原属性所在的点,恰好是反转后列表中的P'[j+1](环形)。通过一次环形移位,就能把所有属性调整到正确的位置,完美匹配需求。
内容来源于stack exchange
相关产品推荐
相关产品推荐

