Найти первое вхождение строки из вектора

у меня есть vector<string> vectorStrings со значениями: ta, bc, ac, st, cer, cda. Я хочу найти первое вхождение любой из строк в вектора в строке ввода.

например

InputStr = "this certainly helps";

данной строки в вектор, я хочу сказать "cer" первое появление на должность 5.


int min = 9999999;
string first;

for(int i = 0; i < vectorStrings.size(); i++)
{
    int pos = InputStr.find(vectorStrings[i]);

    if(pos == string::npos)
        continue;

    if(pos < min)
    {
        min = pos;
        first = vectorStrings[i];
    }
}

// values of min and first gives which string occurred first
// and at the position of it in the input string

эта реализация работает, но я хотел бы знать, существует ли более элегантный способ сделать это с помощью библиотек boost или std библиотека.

Я работаю над Windows и использую Visual Studio 2010.

3 ответов


это проблема MapReduce.

во-первых, вы хотите пойти от vector<string> to vector<int>, их позиций, что является картой, а затем вы хотите уменьшить значения до одного значения на их минимум, что является уменьшением. Во-первых, на карте. Это std::transform.

std::vector<std::string> stuff;
std::string input;
// fill stuff and input
std::vector<int> positions;
std::transform(
    stuff.begin(), 
    stuff.end(), 
    std::back_inserter(positions), 
    [&](std::string& stuff) {
        return input.find(stuff);
    }
);

теперь мы просто использовать std::min_element чтобы получить наименьший элемент, уменьшить.

auto iterator = std::min_element(positions.begin(), positions.end());
int index = *iterator;

чтобы найти строку, которая была найдена там, это простой бит арифметики итератора:

string found = stuff[iterator - positions.begin()];

Я не знаю общих алгоритмов повышения для этой задачи. Ваш алгоритм верен и должен отлично работать на малых размерах. Если у вас большой вектор строк, вы можете использовать для этой задачи более сложные древовидные структуры. Например, вы можете организовать вектор строк в дерево, чтобы ускорить поиск. Вы также можете использовать суффикс-дерево.


class Find
{
public:
    std::vector<std::string> vectorStrings;
    std::map<size_t, std::string> positions;

    size_t find(std::string str)
    {
        for(std::vector<std::string>::iterator i = vectorStrings.begin();
            i != vectorStrings.end();
            ++i)
        {
            positions[str.find(*i)] = *i;
        }

        return (*(positions.begin())).first;
    }
};