diff --git a/src/analyse/analyse.h b/src/analyse/analyse.h index 2cb1fb5..f8a330d 100644 --- a/src/analyse/analyse.h +++ b/src/analyse/analyse.h @@ -43,6 +43,7 @@ private: void new_case(uint64_t code, uint64_t mask); +/// backtrack definitions public: struct backtrack_t { uint64_t code; @@ -50,20 +51,9 @@ public: std::list last; std::list next; }; + typedef std::vector> backtrack_data_t; - void backtrack_demo(const std::vector &codes); - - /// backtrack definitions - -// struct backtrack_t { -// uint64_t code; -// uint32_t layer_num; -// uint32_t layer_index; -// std::list next; -// }; - - // TODO: backtrack for multi-codes -// void backtrack(uint64_t code); -// void backtrack(const std::vector &raw_code_list); + // TODO: try using unordered_set + backtrack_data_t backtrack_demo(const std::vector &codes); }; diff --git a/src/analyse/backtrack.cc b/src/analyse/backtrack.cc index 5b7422a..1e88fd7 100644 --- a/src/analyse/backtrack.cc +++ b/src/analyse/backtrack.cc @@ -1,104 +1,52 @@ +#include #include "analyse.h" #include -#include -#include - -#include - -#include "common_code.h" - -// TODO: using const RawCode& instead of uint64_t - -//namespace std { -// template<> -// struct hash { -// std::size_t operator()(const Analyse::backtrack_t &b) const { -// std::cout << "get hash: " << b.code << std::endl; -// return std::hash()(b.code); -// } -// }; -// -// template<> -// struct equal_to { -// bool operator()(const Analyse::backtrack_t &b1, const Analyse::backtrack_t &b2) const { -// std::cout << "get eq: " << b1.code << " ? " << b2.code << std::endl; -// return b1.code == b2.code; -// } -// }; -//} - -void Analyse::backtrack_demo(const std::vector &codes) { - - +Analyse::backtrack_data_t Analyse::backtrack_demo(const std::vector &codes) { + /// codes pre-check and sort by steps std::vector> todos; - for (const auto &code : codes) { - auto c = cases.find(code); - - if (c == cases.end()) { - // TODO: invalid input - return; + if (c == cases.end()) { // invalid input + return backtrack_data_t{}; // return empty data } - if (c->second.step >= todos.size()) { - todos.resize(c->second.step + 1); + todos.resize(c->second.step + 1); // enlarge schedule list } - todos[c->second.step].emplace_back(&c->second); - } - - std::reverse(todos.begin(), todos.end()); - + std::reverse(todos.begin(), todos.end()); // backtrack start from further layer struct cache_t { analyse_t *a; backtrack_t *b; }; - std::queue track_cache; - std::vector> track_data; - -// track_data.resize(82); // TODO: setting as (max steps + 1) - - track_data.resize(todos.size()); - - // TODO: for diff layer cases, layer_num from big to small -> if found then skip search - + Analyse::backtrack_data_t track_data(todos.size()); + /// start backtrack process for (const auto &todo : todos) { - if (todo.empty()) { - continue; + continue; // without scheduled cases } - - /// clear track cache - std::queue{}.swap(track_cache); - + std::queue{}.swap(track_cache); // clear track cache for (const auto c : todo) { - - // TODO: if c already exist -> skip + /// case already exist -> skip its backtrack if (track_data[c->step].find(c->code) == track_data[c->step].end()) { - track_cache.emplace(cache_t{ .a = c, .b = &track_data[c->step].emplace(c->code, backtrack_t{ .code = c->code, .layer_num = c->step, - .last = std::list{}, - .next = std::list{}, + .last = std::list{}, // without parent node + .next = std::list{}, // without sub node }).first->second, }); } - } - - + /// backtrack until root case while (!track_cache.empty()) { - /// handle first element and pop it - auto curr = track_cache.front(); + auto curr = track_cache.front(); // handle first element for (auto src : curr.a->src) { // traverse src cases of current node auto t_src = track_data[src->step].find(src->code); if (t_src != track_data[src->step].end()) { // match src case @@ -123,8 +71,6 @@ void Analyse::backtrack_demo(const std::vector &codes) { } track_cache.pop(); } - - } @@ -152,4 +98,6 @@ void Analyse::backtrack_demo(const std::vector &codes) { } + return track_data; + }