2015-11-11 7 views
5

È simile a this question ma non è un duplicato. Sto cercando di scorrere una mappa e stampare i valori di ogni elemento, ma con un output leggermente diverso sull'ultimo elemento. In questa domanda, si consiglia di utilizzare map.rbegin().base(), ma non funziona per me.Rileva se iteratore è l'ultimo elemento di std :: map

Ecco il mio codice:

#include <iostream> 
#include <map> 

int main() 
{ 
    std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} }; 
    for (auto iter = charMap.begin(); iter != charMap.end(); iter++) 
    { 
     std::cout << iter->first << ":\t" << iter->second; 
     if (iter == charMap.rbegin().base()) 
      std::cout << "\t//This is the last element.\n"; 
     else 
      std::cout << "\n"; 
    } 
} 

mi aspetto la mia uscita a guardare come questo:

a: 1 
b: 2 
c: 3 
d: 4 //This is the last element. 

Ma invece, sto ottenendo questo output:

a: 1 
b: 2 
c: 3 
d: 4  

Ora capisco che c'è un modo migliore per farlo, ma mi aspetto che funzioni anche. Perché non riesco a confrontare iter e charMap.rbegin().base()?

+0

noti che in tali situazioni è spesso facile riscrivere corpo del ciclo tale che la gestione speciale avviene per la prima piuttosto che l'ultimo elemento. –

+1

@ChristianHackl Nota, ovviamente questo non è il caso qui :) – BartoszKP

+1

@BartoszKP: Perché no? Avvia ogni riga ma la prima con un'interruzione di riga, metti il ​​"Questo è l'ultimo elemento" dopo il ciclo. –

risposta

4

Il metodo base() restituisce l'iteratore a un elemento che segue l'elemento a cui punta un iteratore inverso. Ciò significa che rbegin().base() equivale a end()

Per compiere il proprio compito, si può fare questo:

#include <iostream> 
#include <map> 

int main() 
{ 
    std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} }; 
    for (auto iter = charMap.begin(); iter != charMap.end();) 
    { 
     std::cout << iter->first << ":\t" << iter->second; 
     if (++iter == charMap.end()) 
      std::cout << "\t//This is the last element.\n"; 
     else 
      std::cout << "\n"; 
    } 
} 
0

Brutto. . . ma . . . risposta

auto iterCpy = iter; 
    if (++iterCpy == charMap.end()) 
     std::cout << "\t//This is the last element.\n"; 

utilizzo vsoftco :)

10

Usa std::next da <iterator> come

if (std::next(iter) == charMap.end()) 
    std::cout << "\t//This is the last element.\n"; 

invece.

+0

Oh, stavo usando un iteratore separato quindi incrementando quello. Bello sapere di std :: next(); – DJMcMayhem

2

base() non restituisce lo stesso elemento:

L'iteratore di base si riferisce alla elemento successivo (dallo std::reverse_iterator::iterator_type perspective) all'elemento al quale lo reverse_iterator sta attualmente puntando. Questo è &*(rit.base() - 1) == &*rit.

Questo funziona come previsto:

#include <iostream> 
#include <map> 

int main() 
{ 
    std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} }; 
    auto last = charMap.rbegin(); 
    ++last; 

    for (auto iter = charMap.begin(); iter != charMap.end(); iter++) 
    { 
     std::cout << iter->first << ":\t" << iter->second; 
     if (iter == last.base()) 
      std::cout << "\t//This is the last element.\n"; 
     else 
      std::cout << "\n"; 
    } 
} 
3

perché std::reverse_iterator negozi iteratore con offset 1, in modo che charMap.rbegin().base() == charMap.end(). Grafico oltre here illustra questo.

Si dovrebbe invece usare std::prev o std::next da <iterator>:

iter == std::prev(charMap.end()) 

o

std::next(iter) == charMap.end() 

Qualunque sia a trovare più significativo.

0

In realtà, non ci si aspetta che funzioni come iter è effettivamente diverso da charMap.rbegin().base().

La logica è corretta, l'unico problema è che charMap.rbegin().base() iteratore è pari a charMap.end(), ma si lascia la tua per economico al momento iter raggiunge il valore charMap.end(), in modo che non ha mai avuto la possibilità di provarlo in if all'interno il ciclo for.

per farlo funzionare si potrebbe riscrivere l'istruzione if nel modo seguente:

if (iter->first == charMap.rbegin()->first) 
    std::cout << "\t//This is the last element.\n"; 
else 
    std::cout << "\n"; 

in modo da essere confrontando la chiave della mappa al posto del iteratore stesso.

0

Questo funziona:

#include <iostream> 
#include <map> 

int main() 
{ 
    std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} }; 
    for (auto iter = charMap.begin(); ;) 
    { 
     std::cout << iter->first << ":\t" << iter->second;   
     if (++iter== charMap.end()){ 
      std::cout << "\t//This is the last element.\n"; break; 
     } 
     else 
      std::cout << "\n"; 
    } 

} 
Problemi correlati