2015-06-23 3 views
0

Я думаю, что у меня есть легкая проблема, но я не могу найти решение нигде.C++ доступ к определенному диапазону индексов вектора

У меня есть вектор строки, содержащий много слов. говорят 1-й элемент писем, но я хочу только получить доступ к первым писем. Как мне это сделать?!

std::string test_word = "hou"; 
std::vector<std::string> words = {"house", "apple", "dog", "tree", ...} 

if (test_word == /*(words[0].begin(), words[0].begin()+3)*/) { 
... 
} 

Каков правильный грамматический способ его написания?

EDIT: решение

std::string test_word = "hou"; 
std::vector<std::string> words = {"house", "apple", "dog", "tree", ...} 

for (int i = 0; i < words.size(); i++) { 
    for (int j = 1; j <= words[i].size(); j++) { 
     if (words[i].compare(0,j, test_word) == 0) { 
     ... 
     } 
    } 
} 
+0

Ваше решение неэффективно. Сравнение строк за пределами длины test_word не требуется. Обратите внимание, что когда j> test_word.size(), оператор if всегда будет false. Например, когда i = 0 и j = 4, слова [0] .compare (0, 4, test_word) никогда не вернут 0, потому что «дом» не равен «hou». Вы пытаетесь найти все строки в словах, которые имеют один и тот же префикс (т. Е. Test_word)? – putnampp

+0

@putnampp - да, вы правы, это небольшая проблема. но я не знаю, как это проверить. это как-то возвращается к моему первоначальному вопросу о том, как выбрать определенный диапазон вектора. (Я прихожу из _Matlab_, и там это очень просто). ** Я мог бы сделать это: ** 'if (words [i] .substr (0, j) .size() <= test_word.size())' перед другим _if_, но код даже работает в 5 раз дольше, чем :( –

+0

@putnampp - а также да, я проверяю каждый возможный префикс слов в векторе, если он равен test_word.и test_word всегда различается по длине (в зависимости от ввода), поэтому мне нужен второй цикл, чтобы действительно проверить на 'ho ==', затем 'hou ==', затем 'hous ==', затем 'house ==' , затем 'ap ==' ​​... и так далее. –

ответ

1

Если вы специально заинтересованы в std::string вы можете использовать substr

if (test_word == words[0].substr(0, 3)) 

Как @DanielJour упоминалось в комментариях, вы можете также использовать std::equal

if (std::equal(begin(test_word), begin(test_word) + 3, begin(words[0])) 
+1

Обратите внимание, что 'substr' может привести к распределению кучи. Возможно, вам лучше использовать 'std :: equal', если он находится внутри жесткого цикла. –

+1

@ DanielJour Хорошая мысль, почему вы не публикуете ответ, демонстрирующий, как он работает? –

+0

благодарю вас за быстрый ответ! что вполне может это сделать. это, вероятно, также будет работать с моим правильным кодом, где я запускаю for-loop, проверяя как «_test_word == h_», затем «_test_word == ho_», затем «_test_word == hou_» .. так что просто 'if (test_word == words [0] .substr (0, j)) 'с' j' является параметром цикла. :) –

1

«говорят, что 1-й элемент имеет 5 букв, но я хочу получить только первые 3 буквы. как я это делаю ?!»

Вы можете применить функцию std::string::substr() сослаться на первые 3 буквы:.

if (test_word == words[0].substr(0,3)) { 
+0

спасибо! кажется идеальным решением :) –

3
if(words[0].compare(0,3, test_word) == 0) 

должны избегать делать ненужные выделения памяти

+0

Хмм, я собирался спросить об этом. Я просто ударил _compare() _, читая о новом узнаваемом _substr() _. вы можете подумать, что это более эффективно? –

+1

Короткий ответ: ожидалось бы, что сравнение будет более эффективным. Длинный ответ: сравнение должно быть оптимизировано для позиционного сравнения двух строк до первого несоответствия или, самое большее, конца длины совпадения (в данном случае 3). И наоборот, substr может возвращать копию первых трех символов слов [0]. Хотя, поскольку длина сравнения мала и вы ищете точное значение, оптимизирующий компилятор может выполнить некоторые трюки для сравнения с памятью, делая любые различия в производительности незаметными. – putnampp

+0

большое спасибо! Я выдвинул свой первоначальный вопрос по вашему предложению. он работает так, как я хотел :) –

2

Я хочу получить доступ к первым ..

Использование std::string::substr - удобный способ сделать это, но это может привести к распределению кучи. Так что если вам нужна производительность или хотите придерживаться точно к своей цели, и только доступ эти элементы, то вы должны использовать std::equal из algorithm:

std::equal(words[0].begin(), words[0].begin()+3, 
    "text which is not shorter than 3 elements") 

И есть также функция compare член, как показал putnampp ,

+0

спасибо, что указал на недостаток с 'substr'! –

Смежные вопросы