我有一个从 json 生成的 std::map 和一个从 sqlite 生成的 map 。
我想比较两个 map 并对 sqlite 进行更改,使其与 json 匹配。我最初通过两个 map 使用 map.find(key) 方法来确定要添加什么和删除什么,但我的 friend 告诉我 map 是从最小到最大键排序的,所以我可以只运行一次。
我想到了两种方法。对于首选哪种算法以及为什么,您有什么建议吗?我认为我未注释的那个更快,因为(如果我错了请纠正我)我相信未注释的是 O(n) 最坏情况,而后者是 O(n^2) 最坏情况。
此外,我的 friend 曾提到我不需要第二个“清理”while 循环来协调剩余的 sqlMap 项,但我真的认为我需要它。他是对的吗?
这是我的代码:
void SqlSync::syncEvents() {
int added = 0;
int replaced = 0;
int deleted = 0;
int skipped = 0;
// get categories from Apsiva
std::map<int, Event> jsonMap = _apsivaRest->getEvents();
// get categories from sqlite
std::map<int, Event> sqlMap = _sqliteConnection->getEventMap(true);
// COMPARE
map<int, Event>::iterator jsonIter = jsonMap.begin();
map<int, Event>::iterator sqlIter = sqlMap.begin();
while (jsonIter != jsonMap.end() && sqlIter != sqlMap.end()) {
int jsonId = jsonIter->first;
Event jsonObj = jsonIter->second;
int sqlId = sqlIter->first;
if (jsonId < sqlId) {
// add
_sqliteConnection->addEvent(jsonObj);
++added;
++jsonIter;
} else if (jsonId > sqlId) {
// remove
_sqliteConnection->deleteEvent(sqlId);
++deleted;
++sqlIter;
} else {
if (jsonObj.isNewerThan(sqlIter->second)) {
_sqliteConnection->updateEvent(jsonObj);
++replaced;
} else {
// ignore
cout << "Skipped event b/c not newer" << endl; // delete when verified
++skipped;
}
++jsonIter;
++sqlIter;
}
}
// int jRemaining = std::distance(jsonIter, jsonMap.end());
// int sRemaining = std::distance(sqlIter, sqlMap.end());
// add remaining jsonMap Objects
while (jsonIter != jsonMap.end()) {
Event jsonObj = jsonIter->second;
_sqliteConnection->addEvent(jsonIter->second);
++added;
++jsonIter;
}
// delete remaining sqlMap Objects
while (sqlIter != sqlMap.end()) {
_sqliteConnection->deleteEvent(sqlIter->first);
++deleted;
++sqlIter;
}
// OLD WAY TO COMPARE.
// // add/replace keys found in json
// for (map<int, Event>::const_iterator jsonIter = jsonMap.begin(); jsonIter != jsonMap.end(); ++jsonIter) {
// map<int,Event>::const_iterator it = sqlMap.find(jsonIter->first);
// Event jsonObj = jsonIter->second;
// if (it != sqlMap.end()) {
// Event sqlObj = it->second;
// if (jsonObj.isNewerThan(sqlObj)) {
//// _sqliteConnection->updateEvent(jsonObj);
// ++replaced;
// } else {
// // ignore
// cout << "Skipped category b/c not newer" << endl; // delete when verified
// ++skipped;
// }
// } else {
//// _sqliteConnection->addEvent(jsonObj);
// ++added;
// }
// }
//
// // delete sqlmap CategoryRows not in jsonMap
// for (map<int, Event>::const_iterator sqlObj = sqlMap.begin(); sqlObj != sqlMap.end(); ++sqlObj) {
// if (jsonMap.find(sqlObj->first) == jsonMap.end()) {
//// _sqliteConnection->deleteEvent(sqlObj->first);
// ++deleted;
// }
// }
#ifdef DEBUG
cout << "CATEGORIES SYNC:" << endl;
cout << "---------------" << endl;
cout << "Added: " << added << " | Replaced: " << replaced
<< " | Deleted: " << deleted << " | Skipped: " << skipped << endl;
#endif //DEBUG
}
最佳答案
- 不加注释的方式效率更高。当 n 和 m 是 json 和 SQLite 映射的大小时,复杂度将是 O(n+m)。
- 您将需要最后一个循环,因为当您退出第一个循环时,您不知道您先到达了 map 的哪一端。考虑下一种情况——json 映射的 ID 为 1、2、4、5,SQLite 的 ID 为 1、2、6、7。 您将需要最后一个循环才能删除项目 6 和 7。
关于c++ - 在 C++ 中将 MapB 同步到 MapA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22488452/