So sánh các số phiên bản dưới dạng chuỗi không phải là dễ dàng ...
"1.0.0.9"> "1.0.0.10", nhưng không chính xác.
Cách rõ ràng để làm điều đó đúng là phân tích các chuỗi này, chuyển đổi thành các số và so sánh dưới dạng số. Có cách nào khác để làm điều đó "thanh lịch" hơn không? Ví dụ: boost :: string_algo ...So sánh các phiên bản dưới dạng chuỗi
Trả lời
Tôi không thấy những gì có thể thanh lịch hơn là chỉ phân tích cú pháp - nhưng hãy tận dụng tiện nghi thư viện chuẩn đã có sẵn. Giả sử bạn không cần kiểm tra lỗi:
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);
}
Mọi thứ phức tạp hơn sẽ khó duy trì và không đáng để bạn dành thời gian.
+1: Sử dụng gọn gàng STL. Typo trong 'std :: lexicographical_compare'. – Johnsyweb
Thuật toán là tốt. Tôi muốn đề nghị gói nó như là một 'phiên bản lớp {Phiên bản (std :: string const &); toán tử bool <(Phiên bản const & rhs) const; }; '. Điều này cho phép bạn có một 'std :: set
@Johnsyweb: Cảm ơn bạn đã chọn lỗi đánh máy. @MSalters: Tôi đồng ý. Tôi đã không nói sử dụng này cho sản xuất - Tôi đã chỉ chứng minh các thuật toán tôi nghĩ rằng OP nên sử dụng. –
Tôi sẽ tạo lớp phiên bản.
Sau đó, đơn giản để xác định toán tử so sánh cho lớp phiên bả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";
}
}
Bạn nên sử dụng 'std :: vector
Chỉ cần một gợi ý nhỏ để làm cho lớp học hoàn thiện hơn, điều hành khôn ngoan. Nếu _boost_ có sẵn, người ta có thể [lấy từ 'boost :: less_than_comparable'] (https://theboostcpplibraries.com/boost.operators) để tự động thêm' toán tử> ',' toán tử <= 'và' toán tử> = ' tất cả được thực hiện dưới dạng 'toán tử <'. Cũng hữu ích sẽ là 'operator ==' và lấy được từ 'boost :: equality_comparable' để cung cấp' toán tử! = '. – zett42
@ zett42. Không cần điều đó. Để thêm các toán tử so sánh, tất cả những gì bạn cần làm là thêm 'using namespace std :: rel_ops'. [xem] (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;
}
http://stackoverflow.com/a/34484221/1318830 trả lời đó và sau đó tìm thấy câu hỏi của bạn –
tôi đề nghị tạo lớp phiên bản thay vì chuỗi. bạn có thể cần '1.0.0.9 beta'. đó không phải là một số nguyên đơn giản so sánh. –
Phiên bản C của câu hỏi này cho những người quan tâm: [so sánh số phiên bản trong c] (http://stackoverflow.com/questions/15057010) – hippietrail