Question

En comparant les numéros de version sous forme de chaînes n'est pas si facile ...
"1.0.0.9"> "1.0.0.10", mais ce n'est pas correct.
La façon évidente de le faire est d'analyser correctement ces chaînes, le convertir en nombre et comparer les numéros. Y at-il une autre façon de le faire plus « élégance »? Par exemple, boost :: string_algo ...

Était-ce utile?

La solution

Je ne vois pas ce qui pourrait être plus élégant que l'analyse syntaxique juste - mais s'il vous plaît utiliser des installations de la bibliothèque standard déjà en place. En supposant que vous ne le contrôle d'erreur pas besoin:

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);
}

Rien de plus compliqué va être plus difficile à maintenir et ne vaut pas votre temps.

Autres conseils

Je voudrais créer une classe de version.
Ensuite, il est simple de définir l'opérateur de comparaison pour la classe de version.

#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";
    }
}
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;
}

D'abord le code de test:

int main()
{
    std::cout << ! ( Version("1.2")   >  Version("1.3") );
    std::cout <<   ( Version("1.2")   <  Version("1.2.3") );
    std::cout <<   ( Version("1.2")   >= Version("1") );
    std::cout << ! ( Version("1")     <= Version("0.9") );
    std::cout << ! ( Version("1.2.3") == Version("1.2.4") );
    std::cout <<   ( Version("1.2.3") == Version("1.2.3") );
}
// output is 111111

Mise en œuvre:

#include <string>
#include <iostream>

// Method to compare two version strings
//   v1 <  v2  -> -1
//   v1 == v2  ->  0
//   v1 >  v2  -> +1
int version_compare(std::string v1, std::string v2)
{
    size_t i=0, j=0;
    while( i < v1.length() || j < v2.length() )
    {
        int acc1=0, acc2=0;

        while (i < v1.length() && v1[i] != '.') {  acc1 = acc1 * 10 + (v1[i] - '0');  i++;  }
        while (j < v2.length() && v2[j] != '.') {  acc2 = acc2 * 10 + (v2[j] - '0');  j++;  }

        if (acc1 < acc2)  return -1;
        if (acc1 > acc2)  return +1;

        ++i;
        ++j;
    }
    return 0;
}

struct Version
{
    std::string version_string;
    Version( std::string v ) : version_string(v)
    { }
};

bool operator <  (Version u, Version v) {  return version_compare(u.version_string, v.version_string) == -1;  }
bool operator >  (Version u, Version v) {  return version_compare(u.version_string, v.version_string) == +1;  }
bool operator <= (Version u, Version v) {  return version_compare(u.version_string, v.version_string) != +1;  }
bool operator >= (Version u, Version v) {  return version_compare(u.version_string, v.version_string) != -1;  }
bool operator == (Version u, Version v) {  return version_compare(u.version_string, v.version_string) ==  0;  }

https://coliru.stacked-crooked.com/a/7c74ad2cc4dca888

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top