我最近决定尝试将C ++解决方案用于最近结束的topcoder.com竞赛,作为学习该语言的一种方式(对C ++来说是新手)。但是,当通过std :: set对象的迭代没有成功到达集合中的所有元素(set.count>遍历的#个元素)时,我感到难过。我在StackExchange和其他地方经历过这种情况的其他人都徒劳无功。
细节
我已将代码发布到pastebin:http://pastebin.com/U7xQzDQg。
我试图做的是一个天真的聚类算法。我确信有更好的方法来实现我想做的事情;但是在这个阶段我并不感兴趣(因为我的重点是学习语言及其特性)。我用位置对象表示笛卡尔网格中的方块,属性为“x”和“y”。使用迭代方法,我扫描整个网格,寻找相同颜色的对象,将它们分组到Cluster对象中。当算法完成时,将有一组聚类,每个聚类包括一组间隔不超过设定距离的位置对象。在算法期间的某个时刻,有必要合并彼此接近的集群;这是我开始遇到问题的地方。
如果您编译并运行在pastebin上发布的代码,您将看到如下消息:
TO MERGE:
Cluster of size 1: [1,1],
Cluster of size 2: [0,1], [0,2],
MERGED: 0x7fffb5e9b970Cluster of size 3: [0,1], [1,1],
如果我的代码工作正常,最后一行应该显示的是:
MERGED: <Memory Address of Cluster>Cluster of size 3: [0,1], [1,1], [0,2],
尝试合并时会生成这些行(参见第54行);使用标准集迭代,由运算符强制转换方法生成的Cluster对象的字符串表示形式(参见第97行)。
显而易见的是,尽管该集合声称拥有正确数量的元素,但迭代整个集合并未达到所有元素。我认为对象超出范围并被破坏可能是一个问题;但这似乎并非如此,因为std :: set对象在将元素插入数据结构之前复制元素(并且在Position元素上使用析构函数进行测试)。
我真的很茫然,并且不想破解它...因为我认为这里有一些重要的东西。任何人都可以帮助我吗?
最佳, 马修
答案 0 :(得分:1)
此
return output.c_str();
是未定义的行为,因为您的output
字符串超出了范围,并且在函数返回时删除了基础字符数组。
您的operator const char* () const
函数可能应该是
friend std::ostream& operator<<(std::ostream&, Cluster const&)
直接写入std::cout
。
请记住free
任何你有calloc
编辑的内容,或者更好的是,如果可以避免,最好还是不要在堆上分配内容。
答案 1 :(得分:1)
您的程序显示未定义的行为,因为operator<
不会导致您的Position
个对象strict weak ordering。
bool operator< (Position other) const {
return other.x - x + 100*(other.y - y);
}
您可以改用以下内容:
bool operator< (Position other) const {
if (y < other.y) return true;
if (y > other.y) return false;
return x < other.x;
}