stl como - ¿Hay una manera estándar de comparar dos rangos en C++?




sin java (5)

Por rango me refiero a un par de iteradores. En pseudo C ++:

std::vector<int> v1 = { 1, 2, 3, 4, 5 };
std::vector<int> v2 = { 2, 3, 4 };
if( std::compare_range( v1.begin() + 1, v1.end() - 1, v2.begin(), v2.end() ) {
    std::cout << "Alright\n";
}

compare_range es, por supuesto, la función que estoy buscando.

Descargo de responsabilidad: Esta es una función bastante trivial para escribir, lo sé. Pero como todos los programadores, trato de ser perezoso ;-)


Answers

Parece que no hay un método estándar de "una función". El estándar std :: equal asume que el segundo rango no es más corto que el primero. Por ejemplo, esto puede provocar daños en la memoria, cuando el segundo intervalo está vacío. Tampoco da respuesta, cuando el segundo rango es mayor.

Se requiere la combinación de std :: equal y std :: distance, o función auto-escrita:

template <class InputIterator1, class InputIterator2>
bool safe_equal( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2 )
{
  return ( std::distance( first1, last1 ) == std::distance( first2, last2 ) )
     && std::equal( first1, last1, first2 );
}

La función anterior puede atravesar el contenedor dos veces para los iteradores de acceso no aleatorio, pero utiliza funciones estándar. Puede ser razonable escribir una implementación propia, si esto no es aceptable.


std::equal es la plantilla de función que está buscando.

if (std::equal(v1.begin() + 1, v1.end() - 1, v2.begin())
{
    std::cout << "Alright\n";
}

Tenga en cuenta que std::equal solo toma tres argumentos, no cuatro.



Si tiene un medio para determinar que los dos rangos tienen exactamente el mismo número de elementos, std::equal será suficiente. En la práctica, este no parece ser el caso a menudo para mí, y la mayoría de los usos que tengo de std::equal son, de hecho, determinantes si un rango es un prefijo del otro.

Para las comparaciones reales, he encontrado que std::lexicographical_compare es más útil, aunque la relación que promete es de orden, no de equivalencia. Para equivalencia, puedes aplicarlo dos veces, por ejemplo

   !lexicographical_compare(a.begin(), a.end(), b.begin(), b.end())
&& !lexicographical_compare(b.begin(), b.end(), a.begin(), a.end())

pero esto prácticamente significa comparar elementos dos veces (a menos que haya una diferencia desde el principio).


Usualmente uso el siguiente método:

#include <sstream>

template <typename T>
  std::string NumberToString ( T Number )
  {
     std::ostringstream ss;
     ss << Number;
     return ss.str();
  }

Se describe en detalle here .





c++ stl iterator