抱歉,如果这很明显,我是 C++ 的新手。 stackoverflow 上似乎有相关的答案,只是我所理解的不足以适用于我的情况。
我有一个代表视觉补丁的类实例列表。 当特征之间的距离低于阈值时,我想合并这些项目,用合并后的输出替换 parent 。
像这样:
使用嵌套 for 循环遍历所有项目(将每个项目与其他所有项目进行比较)
当找到匹配项时(不是同一个实例):
从匹配对构造一个新的(子)实例,附加到新列表。
从列表中删除两个(父)项
继续遍历列表以查找其他匹配项
将新列表附加到原始列表。
我知道如何使用迭代器在单个 for 循环中从列表中删除项目,但我不清楚它如何在嵌套循环中工作,因为 erase() 递增到下一个项目。
我可能还需要使这个函数递归,因为最终合并应该通过合并将列表减少为一组代表性实例。
建议将不胜感激。
以下是我的尝试,它不起作用(嵌套循环相互干扰)。对列表中的元素进行这种成对比较的正确方法是什么?
#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> mylist;
list<int>::iterator mylistiterOutter;
list<int>::iterator mylistiterInner;
for(int i=0; i<10; i++) {
mylist.push_back(i);
cout << i << endl;
}
for(int i=0; i<10; i++) {
mylist.push_back(i);
cout << i << endl;
}
int counter =0;
for(mylistiterOutter = mylist.begin(); mylistiterOutter != mylist.end();) {
cout << "Size of mylist: " << mylist.size() << endl;
for(mylistiterInner = mylist.begin(); mylistiterInner != mylist.end();) {
cout << "mylistiterInner: " << *mylistiterInner << endl;
cout << "mylistiterOutter: " << *mylistiterOutter << endl;
//if (mylistiterOutter == mylistiterInner) {// match!
if (false) {
//mylistiterOutter = mylist.erase(mylistiterOutter);
//mylistiterInner = mylist.erase(mylistiterInner);
} else {
mylistiterOutter++;
mylistiterInner++;
}
counter++;
}
}
cout << endl << "Size of mylist: " << mylist.size() << endl << "NumIterations: " << counter << endl;
return(0);
}
感谢@lalitm。我首先尝试了你的方法,因为它更接近我最初的设想,但 J.N. 的提议更优雅,所以我也会尝试。不幸的是,我无法使@lalitm 的方法起作用。 (导致段错误)。以下是使用@lalitm 方法的稍微复杂一些的代码,其中包括示例类和合并代码:
#include <iostream>
#include <list>
#include <cmath>
using namespace std;
class percepUnit {
public:
int cx, cy; // location of percept in frame
bool remove; // used to delete percepts
// constructor method
percepUnit(int ix, int iy) {
cx = ix;
cy = iy;
remove = false;
}
};
bool canMerge(percepUnit unitA, percepUnit unitB) {
double dist = sqrt(pow(abs(unitA.cx-unitB.cx),2)+ pow(abs(unitA.cy-unitB.cy),2));
return (dist < 3);
}
percepUnit merge(percepUnit unitA, percepUnit unitB) {
int x,y;
x = unitA.cx+unitB.cx/2;
y = unitA.cy+unitB.cy/2;
return (percepUnit(x,y));
}
int main() {
list<percepUnit> mylist;
list<percepUnit> mergedlist;
list<percepUnit>::iterator mylistiterOutter;
list<percepUnit>::iterator mylistiterInner;
bool mylistiterOutterChanged;
mylist.push_back(percepUnit(0,0));
mylist.push_back(percepUnit(2,2));
mylist.push_back(percepUnit(5,5));
mylist.push_back(percepUnit(7,7));
//cout << "merge front/back? " << canMerge(mylist.front(),mylist.back()) << endl;
//percepUnit test = merge(mylist.front(),mylist.back());
//cout << "merged front/back (x,y): " << test.cx << "," << test.cy << endl;
for(mylistiterOutter = mylist.begin(); mylistiterOutter != mylist.end();) {
cout << "Size of mylist: " << mylist.size() << endl;
mylistiterInner = mylistiterOutter;
mylistiterOutterChanged = false;
for (++mylistiterInner; mylistiterInner != mylist.end();) {
if (canMerge(*mylistiterOutter, *mylistiterInner )) {
mergedlist.push_back(merge(*mylistiterOutter, *mylistiterInner));
mylistiterOutter = mylist.erase(mylistiterOutter);
mylistiterInner = mylist.erase(mylistiterInner);
mylistiterOutterChanged = true;
} else {
++mylistiterInner;
}
}
if (!mylistiterOutterChanged) {
++mylistiterOutter;
}
}
mylist.splice(mylist.end(), mergedlist);
return(0);
}
这是我的 gdb 信息:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b31d97 in std::_List_node_base::unhook() ()
from /usr/lib/libstdc++.so.6
(gdb) bt
#0 0x00007ffff7b31d97 in std::_List_node_base::unhook() ()
from /usr/lib/libstdc++.so.6
#1 0x0000000000401786 in std::list<percepUnit, std::allocator<percepUnit> >::_M_erase (this=0x7fffffffe4d0, __position=...)
at /usr/include/c++/4.4/bits/stl_list.h:1424
#2 0x000000000040153d in std::list<percepUnit, std::allocator<percepUnit> >::erase (this=0x7fffffffe4d0, __position=...)
at /usr/include/c++/4.4/bits/list.tcc:111
#3 0x0000000000401130 in main () at debug.cpp:61
仍然没有运气。我认为问题可能是上面的代码没有测试两个迭代器是否指向列表中的同一个项目,因此弄乱了迭代器(在不应该递增或不递增时)。
我如何测试两个迭代器是否指向同一个项目?(没有比较所有类成员的蛮力?,但同一个实例的两个拷贝不是同一个实例。 )
最佳答案
void mergeObjects(std::list<T>& list)
{
std::list<T> new_list;
typedef std::list<T>::iterator Itr;
for (Itr i=list.begin(); i != list.end();)
{
Itr j=i;
bool is_merged = false;
for (++j; j != list.end();)
{
if (isMergeable(*i, *j))
{
T merged = mergeObj(*i, *j);
new_list.push_back(merged);
list.erase(j);
is_merged = true;
break;
}
else
{
++j;
}
}
if (is_merged)
{
i = list.erase(i);
}
else
{
++i;
}
}
list.splice(list.end(), new_list);
}
这应该可行,因为插入和删除元素不会使指向任何其他元素的任何指针、引用和迭代器失效。 [引用:C++ STL 教程和引用,Nikolai Josuttis]
关于c++ - 在 std::list 中合并(将两个项目融合在一起,用融合替换它们)项目的算法(即破坏性聚类),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9541961/
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
如果我使用ruby版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是: