查找字符串中所有出现的字符

时间:2011-10-11 13:26:35

标签: c++ algorithm stl vector

我有逗号分隔的字符串,我需要从中提取值。问题是这些字符串永远不会是固定大小。所以我决定迭代逗号组并阅读其间的内容。为了做到这一点,我创建了一个函数,它返回样本字符串中每个匹配项的位置。

这是一种聪明的方法吗?这被认为是错误的代码吗?

#include <string>
#include <iostream>
#include <vector>
#include <Windows.h>

using namespace std;

vector<int> findLocation(string sample, char findIt);

int main()
{
    string test = "19,,112456.0,a,34656";
    char findIt = ',';

    vector<int> results = findLocation(test,findIt);
    return 0;
}

vector<int> findLocation(string sample, char findIt)
{
    vector<int> characterLocations;
    for(int i =0; i < sample.size(); i++)
        if(sample[i] == findIt)
            characterLocations.push_back(sample[i]);

    return characterLocations;
}

5 个答案:

答案 0 :(得分:12)

vector<int> findLocation(string sample, char findIt)
{
    vector<int> characterLocations;
    for(int i =0; i < sample.size(); i++)
        if(sample[i] == findIt)
            characterLocations.push_back(sample[i]);

    return characterLocations;
}

如前所述,如果我正确地阅读了你的问题,这将简单地返回一个包含字符本身的int表示的向量,而不是它们的位置,这正是你真正想要的。

替换此行:

characterLocations.push_back(sample[i]);

这一行:

characterLocations.push_back(i);

这应该会给你你想要的矢量。

答案 1 :(得分:6)

如果我正在审查这个问题,我会看到这一点,并假设你真正要做的就是对一个字符串进行标记,并且已经有很好的方法来做到这一点。

我见过这样做的最好方法是使用boost::tokenizer。它允许您指定字符串的分隔方式,然后为您提供一个很好的迭代器接口来迭代每个值。

using namespace boost;
string sample = "Hello,My,Name,Is,Doug";
escaped_list_seperator<char> sep("" /*escape char*/, ","/*seperator*/, "" /*quotes*/)

tokenizer<escaped_list_seperator<char> > myTokens(sample, sep)

//iterate through the contents
for (tokenizer<escaped_list_seperator<char>>::iterator iter = myTokens.begin();
     iter != myTokens.end();
     ++iter)
{
    std::cout << *iter << std::endl;
}

输出:

Hello
My
Name
Is
Doug

修改如果您不希望依赖于提升,您也可以getline使用istringstream,而不是this answer。要从那个答案中略微复制一下:

std::string str = "Hello,My,Name,Is,Doug";
std::istringstream stream(str);
std::string tok1;

while (stream)
{
    std::getline(stream, tok1, ',');
    std::cout << tok1 << std::endl;
}

输出:

 Hello
 My
 Name
 Is
 Doug

这可能不是直接您要问的内容,但我认为它会解决您尝试解决的整体问题。

答案 2 :(得分:0)

对我来说也很好,一个评论是你的变量和类型的命名。当你真正推回角色本身(类型characterLocations)而不是它的位置时,你调用你将要返回int类型为char的向量。我不确定更大的应用程序是什么,但我认为传回位置会更有意义。或者做一个更多的cookie切割器字符串标记。

答案 3 :(得分:0)

如果您的目的是找到出现的索引,则以下代码将更有效,因为在c ++中将对象作为参数导致对象被复制,这是不安全且效率较低的。特别是返回一个向量是这种情况下最糟糕的做法,这就是为什么将它作为参数引用会更好。

#include <string>
#include <iostream>
#include <vector>
#include <Windows.h>

using namespace std;

vector<int> findLocation(string sample, char findIt);

int main()
{

    string test = "19,,112456.0,a,34656";
    char findIt = ',';

    vector<int> results;
    findLocation(test,findIt, results);
    return 0;
}

void findLocation(const string& sample, const char findIt, vector<int>& resultList)
{
    const int sz = sample.size();

    for(int i =0; i < sz; i++)
    {
        if(sample[i] == findIt)
        {
            resultList.push_back(i);
        }
    }
}

答案 4 :(得分:0)

它的智能程度也取决于你用逗号分隔的那些子字符串。在某些情况下,可能更好(例如更快,具有更小的内存要求)以避免搜索和拆分,并且可能同时解析和处理字符串,可能使用状态机。