【发布时间】:2016-01-24 17:37:08
【问题描述】:
我有一个使用以下方案保存在类似 CSV 文件中的对象列表:
[value11],...,[value1n],[label1]
[value21],...,[value2n],[label2]
...
[valuen1],...,[valuenn],[labeln]
(每一行都是一个对象,即一个双精度向量和相应的标签)。 我想用特定的自定义标准(即该组所有对象的第 n 和第(n + 1)位置的相同值)将它们收集在组中。我需要以最有效的方式做到这一点,因为文本文件包含数百个对象。我正在使用 C++ 编程语言。
为此,首先我将所有 CSV 行加载到一个简单的自定义容器中(使用 getObject、getLabel 和导入方法)。然后我使用下面的代码来阅读它们并进行分组。 “verifyGroupRequirements”是一个函数,如果满足组条件,则返回 true,否则返回 false。
for (size_t i = 0; i < ObjectsList.getSize(); ++i) {
MyObject currentObj;
currentObj.attributes = ObjectsList.getObject(i);
currentObj.label = ObjectsList.getLabel(i);
if (i == 0) {
// Sequence initialization with the first object
ObjectsGroup currentGroup = ObjectsGroup();
currentGroup.objectsList.push_back(currentObj);
tmpGroupList.push_back(currentGroup);
} else {
// if it is not the first pattern, then we check sequence conditions
list<ObjectsGroup>::iterator it5;
for (it5 = tmpGroupList.begin(); it5 != tmpGroupList.end(); ++it5) {
bool AddObjectToGroupRequirements =
verifyGroupRequirements(it5->objectsList.back(), currentObj) &
( (it5->objectsList.size() < maxNumberOfObjectsPerGroup) |
(maxNumberOfObjectsPerGroup == 0) );
if (AddObjectToGroupRequirements) {
// Object added to the group
it5->objectsList.push_back(currentObj);
break;
} else {
// If we can't find a group which satisfy those conditions and we
// arrived at the end of the list of groups, then we create a new
// group with that object.
size_t gg = std::distance(it5, tmpGroupList.end());
if (gg == 1) {
ObjectsGroup tmp1 = ObjectsGroup();
tmp1.objectsList.push_back(currentObj);
tmpGroupList.push_back(tmp1);
break;
}
}
}
}
if (maxNumberOfObjectsPerGroup > 0) {
// With a for loop we can take all the elements of
// tmpGroupList which have reached the maximum size
list<ObjectsGroup>::iterator it2;
for (it2 = tmpGroupList.begin(); it2 != tmpGroupList.end(); ++it2) {
if (it2->objectsList.size() == maxNumberOfObjectsPerGroup)
finalGroupList.push_back(*it2);
}
// Since tmpGroupList is a list we can use remove_if to remove them
tmpGroupList.remove_if(rmCondition);
}
}
if (maxNumberOfObjectsPerGroup == 0)
finalGroupList = vector<ObjectsGroup> (tmpGroupList.begin(), tmpGroupList.end());
else {
list<ObjectsGroup>::iterator it6;
for (it6 = tmpGroupList.begin(); it6 != tmpGroupList.end(); ++it6)
finalGroupList.push_back(*it6);
}
其中 tmpGroupList 是 list<MyObject>,finalGroupList 是 vector<MyObject>,rmCondition 是一个布尔函数,如果 ObjectsGroup 的大小大于固定值,则返回 true。 MyObject 和 ObjectsGroup 是两个简单的数据结构,写法如下:
// Data structure of the single object
class MyObject {
public:
MyObject(
unsigned short int &spaceToReserve,
double &defaultContent,
string &lab) {
attributes = vector<double>(spaceToReserve, defaultContent);
label = lab;
}
vector<double> attributes;
string label;
};
// Data structure of a group of object
class ObjectsGroup {
public:
list<MyObject> objectsList;
double health;
};
这段代码似乎可以工作,但确实很慢。因为,正如我之前所说,我必须将它应用于大量对象,有没有办法改进它并使其更快?谢谢。
[编辑] 我想要实现的是创建一组对象,其中每个对象都是 vector<double>(从 CSV 文件中获取)。所以我在这里要问的是,有没有比上面代码示例中公开的更有效的方法来分组收集这些对象?
[EDIT2] 我需要使用所有这些向量进行分组。
【问题讨论】:
-
在您的
for ( it5...循环中,您使用的是按位&和|,而不是布尔值&&和||。这真的是你想要的吗? -
@stefan 从理论上的 C++ 角度来看,我认为正确的方法是在这种情况下使用布尔运算符
&&和||(如果我错了,请纠正我),但从从实际的角度来看,我看不出它们之间有任何性能差异(至少在这个例子中)。 -
我的评论不是针对潜在的性能问题,而是针对一般代码质量。在我看来,代码应该始终表达意图。在这种情况下,不应该对布尔值进行按位运算。