使用 string_view (c++) 进行翻译练习

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

我有以下任务

开发一个名为 Translator 的类,它允许保存双语单词对,然后使用已添加的单词对将单词从一种语言翻译为另一种语言:

class Translator {
public:
  void Add(string_view source, string_view target);
  string_view TranslateForward(string_view source) const;
  string_view TranslateBackward(string_view target) const;;

private:
//
};

更具体地说,类型为

t
的对象
Translator
应支持以下操作:

  1. 使用默认构造函数创建。在这种情况下,翻译库是空的。

  2. 添加双语对:

    t.Add(source, target)
    。在此调用之后,假设语言 1 中的单词
    source
    对应于语言 2 中的单词
    target
    。传递给
    Add
    方法的字符串可能会在
    t
    对象之前被销毁。

  3. 从语言 1 到语言 2 的翻译:

    t.TranslateForward(source)
    。如果之前对某个字符串
    t.Add(source_copy, target)
    进行过调用
    target
    并且字符串
    source_copy
    等于
    source
    (或相同),则应返回
    target
    。如果没有这样的调用,它应该返回一个空字符串。如果有多个此类调用,则最后一个调用应返回
    target

  4. 从语言 2 到语言 1 的翻译:

    t.TranslateBackward(target)
    。如果之前对某个字符串
    t.Add(source, target_copy)
    进行过调用
    source
    并且字符串
    target_copy
    等于
    target
    (或相同),则应返回
    source
    。如果没有这样的调用,它应该返回一个空字符串。如果有多个此类调用,则最后一个调用应返回
    source

限制:

  • 每个字符串在
    Translator
    类实例中的存储次数不得超过一次。如果违反此限制,您将收到“超出内存限制”错误。

基本上我尝试了以下简单的想法:

#include <string_view>
#include <string>
#include <map>

using namespace std;

class Translator {
public:
    void Add(string_view source, string_view target){
        forward[source] = target;
        backward[target] = source;
    };

    string_view TranslateForward(string_view source) const{
        if(forward.count(source) == 0){
            return string_view("");
        }
        return forward.at(source);
    };

    string_view TranslateBackward(string_view target) const{
        if(backward.count(target) == 0){
            return string_view("");
        }
        return backward.at(target);

    };

private:
    map<string_view,string_view> forward;
    map<string_view,string_view> backward;
};

我用简单的案例进行了测试:

int main(){
    Translator translator;
    translator.Add(string("okno"), string("window"));
    translator.Add(string("stol"), string("table"));
}

而且效果很好。但在隐藏测试中我得到了

TranslateForward() returned wrong data for temporary string (Time used: 1.78/5.00, preprocess time used: 0/None, memory used: 155656192/268435456.)
。看来我错过了一些边缘情况。

我想念什么(一般来说)?

c++
1个回答
0
投票

错误的关键是“临时字符串”。为什么要在地图中存储 string_views ?实际的字符串存储在哪里?调用者字符串结束其生命周期是什么?

std::string_view
只是一个视图。它不拥有数据。它可以让您查看其他对象的数据。如果该其他对象不再存在,您将无法再查看它。

即使在您的示例中,实际字符串也是临时字符串,在完整表达式之后不再存在:

int main(){
    Translator translator;
    translator.Add(string("okno"), string("window"));
    translator.Add(string("stol"), string("table"));
    // already here the string_views in the map point to 
    // strings that no longer exist
}

将字符串存储在地图中,而不仅仅是视图中。

© www.soinside.com 2019 - 2024. All rights reserved.