需要一个简单的双向词典。我知道可能有更好的解决方案,但我想了解我的问题在哪里。该算法基于三件事:
我决定使用集合来存储单词,以及两个指向该集合的映射,如下所示:
map <ptr:word_to_translate_from, ptr:word_to_translate_to>
我使用 set 假设没有插入将使之前获取的迭代器无效。
初始化似乎按我的预期进行,但是找到需要翻译的单词的迭代器后,我无法访问字典集(单词)。我的想法是这样的:
std::set<std::string>::iterator
;*(forward.at(it))
,其中at(it)
将为我提供转发所需元素的关键,forward.at(it)
将为我提供翻译的迭代器,*
将显示单词本身。但这行破坏了执行。我哪里错了?
struct comparator {
bool operator() (const std::set<std::string>::iterator& lhs, const std::set<std::string>::iterator& rhs) const {
return *lhs < *rhs;
}
};
class Translator {
public:
Translator() = default;
void Add(std::string_view source, std::string_view target) {
auto [fw, fw_ok] = words.insert(std::string(source));
auto [bw, bw_ok] = words.insert(std::string(target));
forward.insert({fw, bw}); // inserting a pair of std::set<std::string>::iterator
backward.insert({bw, fw});
}
std::string_view TranslateForward(std::string_view source) const {
std::set<std::string>::iterator it = words.find(std::string(source));
if (it == words.end()) return std::string_view{};
auto ret = *(forward.at(it));
return ret;
}
std::string_view TranslateBackward(std::string_view target) const {
return std::string_view{};
}
private:
std::set<std::string> words;
std::map<std::set<std::string>::iterator, std::set<std::string>::iterator, comparator> forward;
std::map<std::set<std::string>::iterator, std::set<std::string>::iterator, comparator> backward;
int index = 0;
};
void TestSimple() {
Translator translator;
translator.Add(std::string("fenster"s), std::string("window"s));
translator.Add(std::string("tisch"s), std::string("table"s));
assert(translator.TranslateForward("fenster"s) == "window"s);
assert(translator.TranslateBackward("table"s) == "tisch"s);
assert(translator.TranslateForward("table"s) == ""s);
}
int main() {
TestSimple();
return 0;
}
有几个问题。
string
变量,或者更糟糕的是,临时 字符串值。
auto ret
更改为 auto& ret
(但见下文)。std::string_view(""s)
更改为 std::string_view("")
(或仅 ""
或 {""}
)。TranslateBackward
什么都不做,所以第二个断言永远不会起作用。
TranslateBackward
。at
失败时会抛出异常,因此第三个断言永远不会起作用。
find
,而不是 at
,并且您想像往常一样将结果与容器的 end()
进行比较。std::string("fenster"s)
???