2013-03-01 9 views
21

Il mio codice è il seguente:Ottenere indice dell'elemento corrente in C++ gamma-based per-loop

std::cin >> str; 
for (char c : str) 
    if (c == 'b') vector.push_back(i) //while i is the index of c in str 

È questo fattibile? O dovrò andare con il ciclo di vecchia scuola?

+0

@MarkGarcia Significato? Penso che funzioni, ma mi manca il metodo per ottenere 'i' nel ciclo. –

+0

@ chris Ho modificato il codice per far sì che significhi qualcosa. È stupido semplicemente spingere '0 ... n' per il vettore. Ho un'espressione condizionale. –

+1

Quasi lo stesso: http://stackoverflow.com/questions/10962290/find-position-of-element-in-c11-range-based-for-loop – jogojapan

risposta

15

Assumendo str è un std::string o un altro oggetto con lo storage contigue:

std::cin >> str; 
for (char& c : str) 
    if (c == 'b') v.push_back(&c - &str[0]); 
+0

Bello! Stavo pensando che i vettori possono usare qualcosa come 'it - vector.begin()', e hai risolto il mio problema! Grazie! –

+0

Grazie! Ho ottenuto '& it - & vector [0]' per la compilazione. Ma c'è un bel modo come il commento di @ShaneHsu? Ho capito, ho dovuto usare '& it - vector.begin()' usando iteratori come 'const initializer_list & it'. Tuttavia, in un ciclo come 'for (const pair & it: vector_of_pairs)' questo produce un errore: _no match per 'operator-' (i tipi di operando sono 'const pair *' e vector > :: const_iterator_ Come posso ottenere l'indirizzo dell'iteratore? (Si noti che il primo è in un ctor, mentre il secondo è in un metodo const) – gr4nt3d

+0

Nota se lo storage sottostante non cambia più un tipo di vettore, si romperà.Probabilmente anche la vostra semantica basata su interi si spezzerebbe ... quindi questo non è un punto forte contro questo. Ma sembra che tu stia rafforzando il tuo impegno per lo storage contiguo facendo questo. –

4

Quello che stai descrivendo è noto come un'operazione "ognuno con indice" in altre lingue. Facendo un po 'di ricerca su Google, sembra che al di là del "ciclo di vecchia scuola", ci siano alcune soluzioni piuttosto complicate che riguardano le lambas C++ 0x o forse alcune gemme fornite da Boost.

EDIT: Per fare un esempio, si veda questo question

5

Il ciclo gamma non vi darà l'indice. Ha lo scopo di astrarre questi concetti e di farli scorrere attraverso la collezione.

23

Forse è sufficiente avere una variabile i?

unsigned i = 0; 
for (char c : str) { 
    if (c == 'b') vector.push_back(i); 
    ++i; 
} 

In questo modo non è necessario modificare il ciclo basato su intervalli.

+1

È una soluzione, ma non è elegante. Inoltre, penso che sarà inutile in quanto implementa il ciclo tradizionale per un ciclo in una gamma. –

+9

Forse non è elegante, ma è la base della complessità, della leggibilità, del sovraccarico, ecc. Per tutte le altre soluzioni/work-around in arrivo. –

+8

Sicuro. Ma penso davvero che ci dovrebbe essere un costante 'indice' in C++ Range-Based for loop. –

4

È possibile utilizzare lambda in C++ 11:

#include <iostream> 
#include <vector> 
#include <string> 
#include <algorithm> 
#include <iterator> 

using namespace std; 


int main() { 
    std::string str; 
    std::vector<char> v; 
    auto inserter = std::back_insert_iterator<decltype(v)>(v); 

    std::cin >> str; 
    //If you don't want to read from input 
    //str = "aaaaabcdecccccddddbb"; 

    std::copy_if(str.begin(), str.end(), inserter, [](const char c){return c == 'b';}); 

    std::copy(v.begin(),v.end(),std::ostream_iterator<char>(std::cout,",")); 

    std::cout << "Done" << std::endl; 

} 
+0

Sicuramente sembra complicato, ma vale sicuramente la pena di imparare! Grazie! Lo esaminerò. –

+0

Questo non risponde alla domanda. L'OP voleva l'indice numerico delle istanze di "b", non le istanze stesse. – mskfisher

Problemi correlati