2014-09-13 5 views
-4

Застрял в очень интересной проблеме.Вложенный цикл с использованием итератора C++

Вы могли бы сделать это раньше в C/C++

map<string, string> dict; 
dsz = dict.size(); 

vector<string> words; 
int sz = words.size(); 

for(int i = 0; i < sz; ++i) 
{ 
    for(int j = i + 1; j < dsz; ++j) 
    { 
    } 
} 

Как достичь того же эффекта, используя итератор.

Просьба предложить.

+2

Это зависит от того, что вы собираетесь делать с 'i' и' j'. И какая связь между 'dict' и' words'. –

+1

Вам нужно 'i' или' j'? Итератор указывает на них? Только текущий элемент? Просьба уточнить.ATM, ваш код эквивалентен '{}'. – Deduplicator

ответ

0

Ваше окончательное намерение не совсем ясно, потому что вы запускаете j-цикл на i + 1 (см. Комментарии в конце). До тех пор пока вы не даете ясности в этой связи, я предлагаю вам два промежуточного решение

Подход 1: легких и элегантное:

использовать новый диапазон C++ 11, основанный на(). Это делает использование итератора, начиная с начать() и идти до конца(), без необходимости возиться с этим итератора:

for (auto x : words) { // loop on word (size sz) 
    for (auto y : dict) { // loop on dict (size dsz) 
     // do something with x and y, for example: 
     if (x==y.first) 
      cout << "word " << x << " matches dictionary entry " << y.second << endl; 
    } 
} 

Подход 2: традиционное использование итераторов

Вы Cas также укажите явно итераторы, которые будут использоваться. Это немного более многословие, как в предыдущем примере, но оно позволяет вам выбрать наилучший подходящий итератор, например, если вы хотите использовать постоянный итератор, например cbegin() вместо begin(), если вы хотите пропустить некоторые элементы или использовать adaptator на итератора, SUC как, например, reverse_iterator и т.д .:

for (auto itw = words.begin(); itw != words.end(); itw++) { 
    for (auto itd = dict.begin(); itd != dict.end(); itd++) { 
     // do simething with *itw and *itd, for example: 
     if (*itw == itd->first) 
      cout << "word " << *itw << " matches dictionary entry " << itd->second << endl; 
    } 
} 

Примечания:

отправной петли intter с J = I + 1 имеет смысл только тогда, когда элементы вектора word связаны к элементам в dict map (ok, они также являются знатными словами), И если порядок элементов, к которым вы обращаетесь на карте, связан с порядком в векторе , Поскольку карта упорядочена в соответствии с ключом, это будет иметь смысл только при заказе одного слова, следующего за одним и тем же ключом. Это так?

Если вы все же хотите пропустить элементы или сделать расчет на основе расстояния между элементами, лучше рассмотреть второй подход, предложенный выше. Это облегчает использование distance(itw, words.begin()), что было бы эквивалентно i.

Тем не менее, лучше использовать контейнеры, использующие их дизайн. Таким образом, вместо того, чтобы итерация корыта dictionaly карты, чтобы найти запись слова, то лучше сделать использовать карту следующим образом:

for (auto x : words) { // loop on word (size sz) 
    if (dict.count(x)) // if x is in dictionary 
     cout << "word " << x << " matches dictionary entry " << dict[x] << endl; 
} 
0

Ok. Я выясняю это. Точнее, я хотел и i, и j во внутреннем цикле.

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

vector<string>::iterator vit; 
multimap<string, string>::iterator top = dict.begin(); 
multimap<string, string>::iterator mit; 
for(vit = words.begin(); vit != words.end(); ++vit) 
{ 
    string s = *vit; 
    ++top; 
    mit = top; 
    for(; mit != dict.end(); ++mit) 
    { 
    /* compare the value with other val in dictionary, if found, print their keys */ 
    if(dict.find(s)->second == mit->second) 
     cout << s <<" = "<< mit->first << endl; 
    } 
} 

Любой другой эффективный способ сделать это будет благодарен.

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