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;
}
- 1. So sánh các chuỗi phiên bản trong groovy
- 2. So sánh hai chuỗi phiên bản trong PHP
- 3. So sánh các chuỗi có định dạng "2.0.1", "2.0.09"
- 4. So sánh phiên bản văn bản trong FCKEditor
- 5. so sánh ngày ở định dạng Chuỗi
- 6. Các ngày có thể được lưu trữ dưới dạng chuỗi/văn bản được so sánh trực tiếp?
- 7. Cách so sánh các phiên bản gói Debian
- 8. Thuật toán để so sánh sự giống nhau của ý tưởng (dưới dạng chuỗi)
- 9. Cách xác định phiên bản hệ điều hành iPhone hiện tại khi chạy và so sánh các chuỗi phiên bản?
- 10. so sánh giá trị biến phiên với chuỗi
- 11. So sánh các chuỗi trong Java
- 12. So sánh 2 phiên bản của một assembly .NET?
- 13. So sánh chuỗi PostgreSQL
- 14. Làm cách nào để so sánh hai phiên bản AssemblyName?
- 15. So sánh số phiên bản bên trong makefile
- 16. chuỗi so sánh phần
- 17. so sánh chuỗi bash
- 18. So sánh các chuỗi và mảng C#
- 19. So sánh các chuỗi trong Go
- 20. so sánh các chuỗi trong bash
- 21. so sánh các chuỗi trong vb
- 22. So sánh các chuỗi trong EL
- 23. So sánh chuỗi trong .Net: "+" so với "-"
- 24. Chuỗi liên tục dưới dạng Chuỗi được bản địa hóa
- 25. COLLATE được bản địa hoá trên so sánh chuỗi SQLite
- 26. So sánh các chuỗi ngày tháng trong Java
- 27. So sánh số có nhanh hơn so sánh chuỗi không?
- 28. So sánh chuỗi ID với BSON :: ObjectId
- 29. làm cứng phiên php - lỗi so sánh
- 30. So sánh và so sánh số nguyên chuỗi PHP Weird
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