c++ - 在 C++ 中将 MapB 同步到 MapA

标签 c++ algorithm dictionary stdmap

我有一个从 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
}

最佳答案

  1. 不加注释的方式效率更高。当 n 和 m 是 json 和 SQLite 映射的大小时,复杂度将是 O(n+m)。
  2. 您将需要最后一个循环,因为当您退出第一个循环时,您不知道您先到达了 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/

相关文章:

c++ - 模板<int v>类Foo的父类(super class)

c++ - 在没有 std::stod 的情况下从 vector<string> 转换为 vector<double>

algorithm - 查找两个字符串的相似程度

algorithm - 如何轻松知道迷宫是否有从起点到终点的道路?

javascript - javascript中通过对象引用进行哈希

python - 从字典列表中获取平均值

c++ - 二加二扑克手评估器 : How are the cards mapped to the integers?

c++ - 为什么我的 scanf() 没有在数组上迭代 for 循环?

javascript - 为什么这种埃拉托色尼筛法的实现不正确?

python - cpython:何时调用 PyDict_GetItem 以及何时调用 dict_subscript?