Найти первое вхождение строки из вектора
у меня есть 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;
}
};