如果未找到键,则返回一个空的字符串向量 [英] Returning an empty vector of strings if key is not found

查看:219
本文介绍了如果未找到键,则返回一个空的字符串向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这是一个非常糟糕的主意,所以关于如何有效地做它的其他建议将是受欢迎的。



这里的东西。我有 map< string,vector< string> > ,我想搜索一个键并返回其对应的值(在这种情况下,字符串的向量)。原因我坚持返回(而不是只是迭代)是我需要搜索一些其他向量中返回的值。



一个例子将使这一点清楚:

 输入:

key1 ---> {2,3,4}
key2 ---> {1}
key3 ---> {2,12,11,9}

对于key1作为输入, 4应返回。现在这些2,3,4值需要在其他字符串向量中搜索。



我尝试过这样的:

 

code> vector< string> returnEdges(string key)
{
for(map< string,vector< string>> :: iterator it = outgoing.begin();
it!= outgoing.end(); ++ it)
{
if(key.compare((* it).first)== 0)
{
return(* it).second;
}
}


// return string< ;; //我应该返回这里????


}

1)



我希望这是最好的方法。问题很清楚。



编辑:当我写这个问题时,我想为什么不返回迭代器?

解决方案

1)返回迭代器是一个好主意。当你这样做,表示未找到情况的自然方式是返回.end()迭代器。这有一个缺点,抽象是有点漏洞:调用者必须能够获得这个.end()值为了比较它的错误检查,返回的迭代器暴露一个更丰富的接口比你(客户端代码不应该真正玩弄迭代器的递增和递减)。



2)返回空向量和创建一个空向量一样简单,返回它。创建一个空向量=构造一个空的向量。这是你从 - 滚筒 - 矢量类的默认构造函数。



3)你不需要,而不应该实现搜索循环自己。标准库已经为您实现了这一点。 (对于 map ,由于键/值的区别,有一个专门的 find $ c> list ,向量 deque ,更喜欢自由功能 std :: find ,它来自< algorithm>



4)你应该更喜欢接受函数参数(当它们是类的实例,如 std :: string )并返回数据(特别是复杂的东西, const引用。按值传递和返回意味着副本;有时编译器可以优化这一点,但它不如我们想要的那么可靠。此外,你首先使用C ++的原因是对事物有一定程度的控制权,对吧?如果没有,那么不要折磨自己。



但是,如果你要返回一个新创建的值,时间。另一种设计接口的方法是在地图中返回一个指针到字符串的向量(注意这些字符串上的指针算法将是无效的),如果没有找到值,则返回NULL指针。这避免了复制和区分未找到结果与数据中的实际空向量,但是这意味着客户端代码必须处理一个原始的指针。



5)在函数名称中有return是无用的,因为返回是什么函数做的。 OTOH,它是一个好主意,以一个明确的方式,使它明白为什么这些参数是什么。



6)对于复杂类型的迭代器,它是



返回迭代器非常简单:

  typedef map< string,vector< string> > :: iterator graph_iterator; 
graph_iterator edges_named(const string& node_name){
return outgoing.find(node_name);
}



返回字符串向量很简单:

  typedef map< string,vector< string> > :: iterator graph_iterator; 
vector< string> edges_named(const string& node_name){
graph_iterator it = outgoing.find(node_name);
return it == outgoing.end()? vector< string>():it-> second;
}

返回指针很简单:

  typedef map< string,vector< string> > :: iterator graph_iterator; 
vector< string> * edges_named(const string& node_name){
graph_iterator it = outgoing.find(node_name);
return it == outgoing.end()? NULL:&(it->秒);
}

选择明智。


I know it is a very bad idea, so other suggestions on how to do it efficiently will be well-received.

Here's the thing. I have map<string,vector<string> > , I want to search for a key and return its corresponding value (vector of strings in this case). Reason I insist on returning (rather than just iterating) is I need to search the values returned in some other vector.

An example will make this clear:

Input:

key1 ---> {2,3,4}
key2 ---> {1}
key3 ---> {2,12,11,9}

For key1 as input, vector with values 2,3,4 should be returned. Now these 2,3,4 values need to be searched in other vector of strings. What is the most efficient way to do this?

I tried something like this:

vector<string> returnEdges(string key)
{
    for (map<string, vector<string> >::iterator it=outgoing.begin();
    it!=outgoing.end();++it)
    {
        if (key.compare((*it).first)==0)
        {
            return (*it).second;
        }
    }


    //return string<;//what should I return here????


}

1) How should I return empty vector in case key is not found?

2) what is the best way to implement this?

I hope the question is clear.

EDIT: As I wrote the question, I thought why not return an iterator? Do the people at SO give their approval for this idea?

解决方案

1) Returning an iterator is a fine idea. When you do this, the natural way to indicate the "not found" case is to return the .end() iterator. This has the down-side that the abstraction is somewhat leaky: the caller has to be able to get at this .end() value in order to compare to it for error checking, and the returned iterator exposes a richer interface than you'd like (the client code shouldn't really play around with incrementing and decrementing the iterator).

2) Returning an empty vector is as simple as creating an empty vector and returning it. Creating an empty vector = constructing a vector which is empty. This is what you get from - drum roll - the default constructor of the vector class.

3) You don't need to, and shouldn't, implement the search loop yourself. The standard library already implements this for you. (There is a specialized find function for map s because of the key/value distinction. For sequences like list, vector and deque, prefer the free function std::find, which comes from <algorithm>.

4) You should prefer to accept function parameters (when they are instances of classes, like std::string) and return data (especially complex things like a vector of strings) by const reference. Passing and returning by value implies a copy; sometimes the compiler can optimize this away, but it's not as reliable as we'd like. Besides, the reason you're using C++ in the first place is to have that level of control over things, right? If not, then don't torture yourself with it.

However, you can't do that if you're going to return a newly-created value some of the time. Yet another way to design the interface is to return a pointer to the vector of strings (note that pointer arithmetic on these will be invalid) within the map, or a NULL pointer if the value is not found. This avoids copying and distinguishes a "not found" result from an actual empty vector within the data, but it means the client code has to deal with an icky raw pointer.

5) Having 'return' in the name of a function is useless, as returning is what functions do. OTOH, it is a good idea to name things in a way that makes it evident why the parameters are what they are.

6) With iterators for complex types, it is often a good idea to set up typedefs.

Returning an iterator is as simple as:

typedef map<string, vector<string> >::iterator graph_iterator;
graph_iterator edges_named(const string& node_name) {
    return outgoing.find(node_name);
}

Returning a vector of strings is as simple as:

typedef map<string, vector<string> >::iterator graph_iterator;
vector<string> edges_named(const string& node_name) {
    graph_iterator it = outgoing.find(node_name);
    return it == outgoing.end() ? vector<string>() : it->second;
}

Returning a pointer is as simple as:

typedef map<string, vector<string> >::iterator graph_iterator;
vector<string>* edges_named(const string& node_name) {
    graph_iterator it = outgoing.find(node_name);
    return it == outgoing.end() ? NULL : &(it->second);
}

Choose wisely.

这篇关于如果未找到键,则返回一个空的字符串向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆