Как получить доступ к определенному элементу в std :: list <string> - PullRequest
3 голосов
/ 05 декабря 2011
   list<string>&  whichList = theLists[ myhash( x, theLists.size( ) ) ];

Мне было интересно, как получить доступ к определенной позиции, скажите «i» и посмотреть, не было ли в этой позиции пусто.

Я делал это так:

if(whichList[i] == 0)

но, похоже, это не работает.

Я понимаю, что это неправильно.Есть предложения?

Ответы [ 4 ]

4 голосов
/ 05 декабря 2011

Вы можете попробовать что-то вроде:

list<string> iterator it = whichList.begin();
std::advance(it, i);
if(*it == "") { /* ... */ }

Но я думаю, что вам нужно четко определить, что вы подразумеваете под "пустым" - вы не можете сравнить строки с 0.

Ключевым моментом является то, что list не поддерживает произвольный доступ - из-за его реализации (двусвязный список) поддержка произвольного доступа будет O(n) операцией, то есть линейной по длине списка в худший случай. Это неэффективно, поэтому сознательно не поддерживается в интерфейсе.

Как уже отмечали другие, если вам нужен произвольный доступ, вам лучше использовать что-то вроде vector или deque. Вообще говоря, вы должны использовать vector, если вам нужна только быстрая вставка / удаление в конце контейнера, deque, если вам также требуется быстрая вставка / удаление в передней части контейнера, и только list если вам нужно быстрое введение / удаление в середине контейнера. Чтобы поддержать последний тип операции, list заканчивает тем, что жертвует произвольным доступом к элементам.

См. Здесь определение advance, между прочим:

http://www.sgi.com/tech/stl/advance.html

РЕДАКТИРОВАТЬ: Как указал Альф, вы можете в некоторой степени получить быстрое вставление / удаление в середине вектора, используя технику буфера зазора (см. http://en.wikipedia.org/wiki/Gap_buffer),, хотя отдельная операция может быть дорогостоящей, если вы заполните разрыв (идея состоит в том, чтобы амортизировать стоимость по многим операциям, делая последовательность операций сравнительно дешевой).

2 голосов
/ 05 декабря 2011

В C ++ std::list не поддерживает поиск с произвольным доступом через operator [].Если вы собираетесь продолжать использовать список, вам следует обратиться к функции std::advance.

list<string>::iterator itr = whichList.begin();
std::advance(itr, i);
if (itr->empty())
{
 /* ... assuming that you're testing for an empty string */
}

Если возможно, вы можете рассмотреть другие стандартные контейнеры, такие как std::vector или * 1008.*, оба из которых обеспечивают поиск произвольного доступа через operator [].

1 голос
/ 05 декабря 2011

Стандартный способ найти первый элемент списка, значением которого является пустая строка, заключается в использовании std::find:

std::list<std::string>::iterator it = std::find(whichList.begin(), whichlist.end(), "");

Его положение может быть вычислено (дорого) как std::distance(whichList.begin(), it), но маловероятно, что вам понадобится фактический числовой индекс, если вы приняли осознанное решение о том, что std::list был правильный тип контейнера для вашего приложения.

0 голосов
/ 05 декабря 2011

Я думаю, вы должны использовать вектор для этой проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...