如何使用迭代器访问特定的集合元素?

问题描述 投票:0回答:1

需要一个简单的双向词典。我知道可能有更好的解决方案,但我想了解我的问题在哪里。该算法基于三件事:

  • 它需要是对称的(无论平移方向如何,工作原理都完全相同)
  • 将每个单词存储一次
  • 或多或少快/最优。

我决定使用集合来存储单词,以及两个指向该集合的映射,如下所示:

map <ptr:word_to_translate_from, ptr:word_to_translate_to>

我使用 set 假设没有插入将使之前获取的迭代器无效。

初始化似乎按我的预期进行,但是找到需要翻译的单词的迭代器后,我无法访问字典集(单词)。我的想法是这样的:

  • 我有两个映射,存储 std::setstd::string 类型的迭代器,指向我需要的单词;
  • 我正在找到请求的单词并将相应的迭代器分配给类型为
    std::set<std::string>::iterator
    ;
  • 的 fw
  • 我希望通过这样做来获得翻译:
    *(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;
}
c++ dictionary stl
1个回答
0
投票

有几个问题。

  1. 您将视图返回到本地
    string
    变量,或者更糟糕的是,临时 字符串值。
    • auto ret
      更改为
      auto& ret
      (但见下文)。
    • std::string_view(""s)
      更改为
      std::string_view("")
      (或仅
      ""
      {""}
      )。
  2. TranslateBackward
    什么都不做,所以第二个断言永远不会起作用。
    • 实施
      TranslateBackward
  3. at
    失败时会抛出异常,因此第三个断言永远不会起作用。
    • 您想要
      find
      ,而不是
      at
      ,并且您想像往常一样将结果与容器的
      end()
      进行比较。
  4. 不是致命问题,但是
    std::string("fenster"s)
    ???
© www.soinside.com 2019 - 2024. All rights reserved.