2010-06-10 10 views
5

Tengo tres preguntas con respecto a una tarea asignada para C++. El objetivo era crear un método de palíndromo simple. Aquí está mi plantilla para que:Iteradores de vectores en bucles for, declaraciones de devolución, advertencia, C++

#ifndef PALINDROME_H 
#define PALINDROME_H 

#include <vector> 
#include <iostream> 
#include <cmath> 

template <class T> 
static bool palindrome(const std::vector<T> &input) 
{ 
    std::vector<T>::const_iterator it = input.begin(); 
    std::vector<T>::const_reverse_iterator rit = input.rbegin(); 

    for (int i = 0; i < input.size()/2; i++, it++, rit++) 
    { 
     if (!(*it == *rit)) { 
      return false; 
     } 
    } 
    return true; 
} 

template <class T> 
static void showVector(const std::vector<T> &input) 
{ 

    for (std::vector<T>::const_iterator it = input.begin(); it != input.end(); it++) { 
     std::cout << *it << " "; 
    } 
} 

#endif 

En cuanto al código anterior, se puede tener más de un iterador declara en la primera parte del bucle? Intenté definir tanto el "it" como el "rit" en el método palindrome(), y seguí recibiendo un error sobre la necesidad de un "," antes de rit. Pero cuando corté y pegué fuera del bucle for, no hay errores del compilador. (Estoy usando VS 2008).

La segunda pregunta, me acabo de salir el cerebro me pedí un tizón en esta. Pero, ¿está bien la forma en que tengo mis declaraciones de devolución en el método palindrome()? En mi cabeza, creo que funciona, una vez que * it y * rit no se igualan, la función devuelve false y el método sale en este punto. De lo contrario, si recorre todo el ciclo for, entonces devuelve verdadero al final. Me tiré un tizón al cerebro sobre cómo funcionan las declaraciones de devolución en los bloques y traté de buscar un buen ejemplo en mi libro y no pude encontrar uno.

Por último, me sale esto advertencias:

\palindrome.h(14) : warning C4018: '<' : signed/unsigned mismatch 

ahora es que ya tengo mi bucle hasta que (i < input.size()/2) y el compilador es que me decía que de entrada puede ser negativo ? ¡Gracias!

+1

No es necesario declarar las plantillas de función 'static'. –

Respuesta

5

¿Puede tener más de un iterador declarado en la primera parte del ciclo for?

Sí, pero ambos tienen que ser del mismo tipo, por lo que no pueden declarar tanto un const_iterator y una const_reverse_iterator.

es la forma en que tengo mis declaraciones de devolución en el método palindrome() ¿está bien?

Sí, aunque ¿por qué no comparar *it != *rit?

palindrome.h(14) : warning C4018: '<' : signed/unsigned mismatch 

i está firmado; std::vector::size() devuelve un valor sin signo. Si i no tiene firma, no recibirá esta advertencia.

Como sugerencia, sin embargo: podría ser más simple usar dos iteradores hacia adelante. Inicialice uno al .begin() y el otro al .end() - 1. A continuación, puede incrementar el primero y disminuir el segundo y su prueba de bucle simplemente se convierte en it1 < it2. Algo así como lo siguiente (no está comprobado) de bucle:

for (iterator it1(v.begin()), it2(v.end() - 1); it1 < it2; ++it1, --it2) 

De esta manera ya no es necesario el i mostrador y comparaciones por separado; todo se hace con iteradores.

+0

Su última sugerencia solo funcionará para los iteradores de acceso aleatorio, ya que solo admiten la resta. – Tomek

+0

@Tomek: cierto. El OP está usando 'std :: vector', que utiliza iteradores de acceso aleatorio. También puede usar 'std :: prev()' (C++ 0x además, pero trivial para implementar) para obtener un iterador para el último elemento; entonces el requisito se reduce a iteradores bidireccionales. –

+1

no se pueden comparar iteradores bidireccionales con nada más que igualdad ('==' y '! =' Están bien, pero no '<'), por lo que el requisito seguiría siendo un iterador de acceso aleatorio. Podría reescribirse para usar solo comparaciones de igualdad, pero eso requeriría mover los incrementos/decrementos (al menos uno) dentro del cuerpo del bucle y verificar que ambos iteradores crucen en contenedores con un número par de elementos. –

0

El bucle for funciona para mí cuando iteradores son del mismo tipo, no me he dado cuenta de otra manera todavía - aparte de la inicialización de ellos fuera como lo que hizo:

typedef vector<char>::const_iterator IT; 

for (IT it(vchars.begin()), end(vchars.end()); it != end; ++it) 
{ 
    cout << *it << endl; 
} 

En cuanto a la instrucción de retorno, su razonamiento es correcto, pero usted comienza con esos 2 iteradores que no son lo mismo, uno comienza desde el frente al otro desde el final. Entonces, en la primera iteración no son iguales y usted devuelve falso - Creo.

Y por último, los puntos de alerta al hecho de que los rendimientos size() tipo sin signo (tamaño no puede ser negativa), sino que se compara con el valor con signo i, que en la mayoría de los casos no es un problema real - pero para ser ordenada que puede declarar su i como sin firmar.

Esto solucionará eso:

for (unsigned int i = 0; i < input.size()/2; ...) 
8

son iteradores una exigencia de la tarea? Esta tarea se puede reducir a una llamada a std::equal:

template <class T> 
bool palindrome(const std::vector<T> &input) 
{ 
     return equal(input.begin(), input.begin()+input.size()/2, input.rbegin()); 
} 
+0

Cheater ;-) (y +1 ... muy buena solución) –

Cuestiones relacionadas