Comparar números de versión como cadenas no es tan fácil ...
"1.0.0.9"> "1.0.0.10", pero no es correcto.
La forma obvia de hacerlo correctamente es analizar estas cadenas, convertir a números y compararlos como números. ¿Hay alguna otra manera de hacerlo más "elegantemente"? Por ejemplo, boost :: string_algo ...Comparar versiones como cadenas
Respuesta
No veo lo que podría ser más elegante que el análisis, pero por favor hacer uso de las instalaciones de biblioteca estándar ya instaladas. Suponiendo que no es necesario la comprobación de errores:
void Parse(int result[4], const std::string& input)
{
std::istringstream parser(input);
parser >> result[0];
for(int idx = 1; idx < 4; idx++)
{
parser.get(); //Skip period
parser >> result[idx];
}
}
bool LessThanVersion(const std::string& a,const std::string& b)
{
int parsedA[4], parsedB[4];
Parse(parsedA, a);
Parse(parsedB, b);
return std::lexicographical_compare(parsedA, parsedA + 4, parsedB, parsedB + 4);
}
algo más complicado va a ser más difícil de mantener y no es digno de su tiempo.
1: Uso STL Neat. Typo en 'std :: lexicographical_compare'. – Johnsyweb
El algoritmo es bueno. Sugiero envolverlo como una 'clase Version {Version (std :: string const &); bool operator <(Version const & rhs) const; }; '. Esto le permite tener un 'std :: set
@Johnsyweb: Gracias por retomar el error tipográfico. @MSalters: estoy de acuerdo. No estaba diciendo usar esto para producción, solo estaba demostrando el algoritmo que creo que debería usar OP. –
me gustaría crear una clase de versión.
Luego es simple definir el operador de comparación para la clase de versión.
#include <iostream>
#include <sstream>
#include <vector>
#include <iterator>
class Version
{
// An internal utility structure just used to make the std::copy in the constructor easy to write.
struct VersionDigit
{
int value;
operator int() const {return value;}
};
friend std::istream& operator>>(std::istream& str, Version::VersionDigit& digit);
public:
Version(std::string const& versionStr)
{
// To Make processing easier in VersionDigit prepend a '.'
std::stringstream versionStream(std::string(".") + versionStr);
// Copy all parts of the version number into the version Info vector.
std::copy( std::istream_iterator<VersionDigit>(versionStream),
std::istream_iterator<VersionDigit>(),
std::back_inserter(versionInfo)
);
}
// Test if two version numbers are the same.
bool operator<(Version const& rhs) const
{
return std::lexicographical_compare(versionInfo.begin(), versionInfo.end(), rhs.versionInfo.begin(), rhs.versionInfo.end());
}
private:
std::vector<int> versionInfo;
};
// Read a single digit from the version.
std::istream& operator>>(std::istream& str, Version::VersionDigit& digit)
{
str.get();
str >> digit.value;
return str;
}
int main()
{
Version v1("10.0.0.9");
Version v2("10.0.0.10");
if (v1 < v2)
{
std::cout << "Version 1 Smaller\n";
}
else
{
std::cout << "Fail\n";
}
}
Debe usar 'std :: vector
Solo una pequeña sugerencia para hacer que la clase sea más completa, en cuanto al operador. Si _boost_ está disponible, uno podría [derivar de 'boost :: less_than_comparable'] (https://theboostcpplibraries.com/boost.operators) para agregar automáticamente' operator> ',' operator <= ', y' operator> = ' que están todos implementados en términos de 'operator <'. También sería útil 'operator ==' y derivar de 'boost :: equality_comparable' para proporcionar' operator! = '. – zett42
@ zett42. No hay necesidad de eso. Para agregar operadores de comparación, todo lo que necesita hacer es agregar 'using namespace std :: rel_ops'. [ver] (http://www.cplusplus.com/reference/utility/rel_ops/) –
int VersionParser(char* version1, char* version2) {
int a1,b1, ret;
int a = strlen(version1);
int b = strlen(version2);
if (b>a) a=b;
for (int i=0;i<a;i++) {
a1 += version1[i];
b1 += version2[i];
}
if (b1>a1) ret = 1 ; // second version is fresher
else if (b1==a1) ret=-1; // versions is equal
else ret = 0; // first version is fresher
return ret;
}
- 1. Comparar cadenas de versiones en groovy
- 2. comparar cadenas como números en SQLite3
- 3. pitón: comparar dos cadenas
- 4. Algoritmo para comparar la similitud de ideas (como cadenas)
- 5. comparar cadenas múltiples en Perl
- 6. Comparar cadenas por envoltorios SSE4
- 7. Cómo comparar las versiones del paquete Debian
- 8. Cómo comparar 2 cadenas alfabéticamente
- 9. ¿Comparar 2 versiones de un ensamblado .NET?
- 10. Comparar dos versiones de un procedimiento almacenado
- 11. ¿Es aconsejable usar strcmp o _tcscmp para comparar cadenas en versiones Unicode?
- 12. ¿Cómo comparar cadenas con Xpath 1.0?
- 13. Rubí comparar dos cadenas porcentaje de similitud
- 14. C# - Mostrar las diferencias al comparar cadenas
- 15. Comparar dos cadenas y obtener la diferencia
- 16. Cómo comparar puntero a cadenas en C
- 17. Comparar 5000 cadenas con PHP Levenshtein
- 18. Cómo comparar cadenas Unicode en Javascript?
- 19. ¿Cómo comparar cadenas encriptadas con semillas aleatorias?
- 20. Smalltalk - Comparar dos cadenas para la igualdad
- 21. ¿Comparar cadenas de dos bytes [] de utf-8 es lo mismo que comparar dos cadenas de unicode?
- 22. ¿Cómo comparar versiones de algunos productos en unix ksh shell?
- 23. ¿Cómo comparar versiones de software usando SQL Server?
- 24. Dos cadenas se comparan igual usando '=' pero fallan en 'como' comparar
- 25. Cómo comparar una cadena con varias otras cadenas
- 26. Javascript para comparar dos fechas, desde cadenas, begin <= end
- 27. ¿Cómo comparar 2 cadenas con <c:if>?
- 28. Cómo comparar cadenas en la consulta de Linq
- 29. ¿La forma óptima de comparar cadenas en Javascript?
- 30. ¿Cómo puedo ignorar los acentos al comparar cadenas en Perl?
http://stackoverflow.com/a/34484221/1318830 respondida allí y luego encontró su pregunta –
Sugiero que crean la clase en lugar de la versión de cadena. es posible que también necesites '1.0.0.9 beta'. eso no es una simple comparación de enteros. –
versión C de esta cuestión para los interesados: [números de versión que comparan en c] (http://stackoverflow.com/questions/15057010) – hippietrail