분할 함수를 사용하지 않고 버전 번호 비교
버전 번호를 비교하려면 어떻게 해야 합니까?
예를 들어:
x = 1.23.56.1487.5
y = 1.24.55.487.2
사용할 수 있습니까?Version
수업?
https://learn.microsoft.com/en-us/dotnet/api/system.version
그것은 있습니다.IComparable
인터페이스표시한 것처럼 5-part 버전 문자열에서는 작동하지 않습니다(실제 버전 문자열입니까?).입력이 문자열이라고 가정할 때, 여기 정상적인 작업 샘플이 있습니다.NET 4부 버전 문자열:
static class Program
{
static void Main()
{
string v1 = "1.23.56.1487";
string v2 = "1.24.55.487";
var version1 = new Version(v1);
var version2 = new Version(v2);
var result = version1.CompareTo(version2);
if (result > 0)
Console.WriteLine("version1 is greater");
else if (result < 0)
Console.WriteLine("version2 is greater");
else
Console.WriteLine("versions are equal");
return;
}
}
소령.단조와 함께 살 수 있다면요.사용할 수 있는 build.build scheme.Net Version 클래스입니다.그렇지 않으면 왼쪽에서 오른쪽으로 어떤 종류의 구문 분석을 구현하고 차이점이 있거나 두 버전이 동일하다는 것을 반환할 때까지 계속해야 합니다.
@JohnD의 답변 외에도 분할('.') 또는 다른 문자열 <-> 변환 블롯을 사용하지 않고 부분 버전 번호만 비교해야 할 수 있습니다.나는 방금 1개의 추가 인수와 함께 확장 방법 CompareTo를 작성했습니다 - 비교할 버전 번호의 중요한 부분의 수(1과 4 사이).
public static class VersionExtensions
{
public static int CompareTo(this Version version, Version otherVersion, int significantParts)
{
if(version == null)
{
throw new ArgumentNullException("version");
}
if(otherVersion == null)
{
return 1;
}
if(version.Major != otherVersion.Major && significantParts >= 1)
if(version.Major > otherVersion.Major)
return 1;
else
return -1;
if(version.Minor != otherVersion.Minor && significantParts >= 2)
if(version.Minor > otherVersion.Minor)
return 1;
else
return -1;
if(version.Build != otherVersion.Build && significantParts >= 3)
if(version.Build > otherVersion.Build)
return 1;
else
return -1;
if(version.Revision != otherVersion.Revision && significantParts >= 4)
if(version.Revision > otherVersion.Revision)
return 1;
else
return -1;
return 0;
}
}
public int compareVersion(string Version1,string Version2)
{
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"([\d]+)");
System.Text.RegularExpressions.MatchCollection m1 = regex.Matches(Version1);
System.Text.RegularExpressions.MatchCollection m2 = regex.Matches(Version2);
int min = Math.Min(m1.Count,m2.Count);
for(int i=0; i<min;i++)
{
if(Convert.ToInt32(m1[i].Value)>Convert.ToInt32(m2[i].Value))
{
return 1;
}
if(Convert.ToInt32(m1[i].Value)<Convert.ToInt32(m2[i].Value))
{
return -1;
}
}
return 0;
}
제 것은 여기 있어요."3.2.1.7650.b40"과 "3.10.1"과 같은 이상한 버전 문자열을 비교해야 했기 때문에 버전을 사용할 수 없었습니다.위에서 제안한 대로 정보 개체입니다.이것은 나에게 스타일을 주문하는 빠르고 더러운 것입니다.테스트할 수 있는 짧은 기능도 제공했습니다.
using System;
public class Program
{
public static void Main()
{
Test_CompareVersionStrings();
}
/// <summary>
/// Compare two version strings, e.g. "3.2.1.0.b40" and "3.10.1.a".
/// V1 and V2 can have different number of components.
/// Components must be delimited by dot.
/// </summary>
/// <remarks>
/// This doesn't do any null/empty checks so please don't pass dumb parameters
/// </remarks>
/// <param name="v1"></param>
/// <param name="v2"></param>
/// <returns>
/// -1 if v1 is lower version number than v2,
/// 0 if v1 == v2,
/// 1 if v1 is higher version number than v2,
/// -1000 if we couldn't figure it out (something went wrong)
/// </returns>
private static int CompareVersionStrings(string v1, string v2)
{
int rc = -1000;
v1 = v1.ToLower();
v2 = v2.ToLower();
if (v1 == v2)
return 0;
string[] v1parts = v1.Split('.');
string[] v2parts = v2.Split('.');
for (int i = 0; i < v1parts.Length; i++)
{
if (v2parts.Length < i+1)
break; // we're done here
string v1Token = v1parts[i];
string v2Token = v2parts[i];
int x;
bool v1Numeric = int.TryParse(v1Token, out x);
bool v2Numeric = int.TryParse(v2Token, out x);
// handle scenario {"2" versus "20"} by prepending zeroes, e.g. it would become {"02" versus "20"}
if (v1Numeric && v2Numeric) {
while (v1Token.Length < v2Token.Length)
v1Token = "0" + v1Token;
while (v2Token.Length < v1Token.Length)
v2Token = "0" + v2Token;
}
rc = String.Compare(v1Token, v2Token, StringComparison.Ordinal);
//Console.WriteLine("v1Token=" + v1Token + " v2Token=" + v2Token + " rc=" + rc);
if (rc != 0)
break;
}
if (rc == 0)
{
// catch this scenario: v1="1.0.1" v2="1.0"
if (v1parts.Length > v2parts.Length)
rc = 1; // v1 is higher version than v2
// catch this scenario: v1="1.0" v2="1.0.1"
else if (v2parts.Length > v1parts.Length)
rc = -1; // v1 is lower version than v2
}
if (rc == 0 || rc == -1000)
return rc;
else
return rc < 0 ? -1 : 1;
}
private static int _CompareVersionStrings(string v1, string v2)
{
int rc = CompareVersionStrings(v1, v2);
Console.WriteLine("Compare v1: " + v1 + " v2: " + v2 + " result: " + rc);
return rc;
}
// for debugging
private static void Test_CompareVersionStrings()
{
bool allPass = true;
// should be equal
allPass &= (0 == _CompareVersionStrings("1", "1"));
allPass &= (0 == _CompareVersionStrings("1.1", "1.1"));
allPass &= (0 == _CompareVersionStrings("3.3.a20", "3.3.A20"));
// v1 should be lower
allPass &= (-1 == _CompareVersionStrings("1", "2"));
allPass &= (-1 == _CompareVersionStrings("1.0", "1.0.1"));
allPass &= (-1 == _CompareVersionStrings("1.0", "1.1"));
allPass &= (-1 == _CompareVersionStrings("1.0.0.3", "1.1"));
allPass &= (-1 == _CompareVersionStrings("1.2.3.4", "1.2.3.4b"));
allPass &= (-1 == _CompareVersionStrings("1.2.3.4", "1.2.3.4.b"));
allPass &= (-1 == _CompareVersionStrings("1.8.0", "20.0.0.0"));
allPass &= (-1 == _CompareVersionStrings("5.6.0.788.2", "20.0.0.0"));
// v1 should be higher
allPass &= (1 == _CompareVersionStrings("2", "1"));
allPass &= (1 == _CompareVersionStrings("1.0.1", "1.0"));
allPass &= (1 == _CompareVersionStrings("1.1", "1.0"));
allPass &= (1 == _CompareVersionStrings("1.1", "1.0.0.3"));
allPass &= (1 == _CompareVersionStrings("1.2.3.4b", "1.2.3.4"));
allPass &= (1 == _CompareVersionStrings("1.2.3.4.b", "1.2.3.4"));
allPass &= (1 == _CompareVersionStrings("20.0.0.0", "5.6.0.788.2"));
Console.WriteLine("allPass = " + allPass.ToString());
}
}
어떤 이유로 버전의 비교 방법을 직접 사용할 수 없는 경우(예: 클라이언트-서버 시나리오) 다른 방법은 버전에서 긴 숫자를 추출한 다음 서로 비교하는 것입니다.그러나 번호 형식은 다음과 같아야 합니다.메이저, 마이너 및 리비전의 경우 두 자리, 빌드의 경우 네 자리입니다.
버전 번호를 추출하는 방법:
var version = Assembly.GetExecutingAssembly().GetName().Version;
long newVersion = version.Major * 1000000000L +
version.Minor * 1000000L +
version.Build * 1000L +
version.Revision;
그리고 다른 곳에서 비교할 수 있습니다.
if(newVersion > installedVersion)
{
//update code
}
참고: installedVersion은 이전에 추출된 긴 숫자입니다.
인터넷에서 이 알고리즘이 잘 작동하는 것 같습니다.
//https://www.geeksforgeeks.org/compare-two-version-numbers/amp/
static int versionCompare(string v1, string v2)
{
// vnum stores each numeric
// part of version
int vnum1 = 0, vnum2 = 0;
// loop until both string are
// processed
for (int i = 0, j = 0; (i < v1.Length || j < v2.Length);)
{
// storing numeric part of
// version 1 in vnum1
while (i < v1.Length && v1[i] != '.')
{
vnum1 = vnum1 * 10 + (v1[i] - '0');
i++;
}
// storing numeric part of
// version 2 in vnum2
while (j < v2.Length && v2[j] != '.')
{
vnum2 = vnum2 * 10 + (v2[j] - '0');
j++;
}
if (vnum1 > vnum2)
return 1;
if (vnum2 > vnum1)
return -1;
// if equal, reset variables and
// go for next numeric part
vnum1 = vnum2 = 0;
i++;
j++;
}
return 0;
}
언급URL : https://stackoverflow.com/questions/7568147/compare-version-numbers-without-using-split-function
'programing' 카테고리의 다른 글
jQuery에서 모든 확인란 찾기 (0) | 2023.08.22 |
---|---|
Angular CLI 이미 존재하는 구성 요소에 대한 .spec 파일 생성 (0) | 2023.08.22 |
Angular2에서 구독을 취소하는 방법 (0) | 2023.08.22 |
AJAX 요청 후 Javascript 파일 다시 로드 (0) | 2023.08.22 |
크롬 브라우저에서 XHR 디버깅 (0) | 2023.08.22 |