2015-11-28 38 views
1

我有一个方法获取两个字符串。这些字符串可以同时包含数字,ASCII字符或两者。比较数值作为字符串

的算法是这样的:

  1. 拆分两个字符串转换成char数组A和B.
  2. 尝试解析元素A 和B 为int
  3. 比较元素A i带元素B i,在整数使用直接比较的情况下,在字符使用序数字符串比较的情况下。
  4. 根据结果

现在做的工作,我想知道:我真的需要解析的元素为int?我只是可以比较序号字符串比较中的每个元素,并得到相同的结果,对吧? 这里的性能影响是什么?解析和正常比较比序列字符串比较更快吗?它慢吗?

是我的假设(使用序数字符串比较而不是解析和比较)是否正确?

这里是有问题的方法:

internal static int CompareComponentString(this string componentString, string other) 
{ 
    bool componentEmpty = string.IsNullOrWhiteSpace(componentString); 
    bool otherEmtpy = string.IsNullOrWhiteSpace(other); 

    if (componentEmpty && otherEmtpy) 
    { 
     return 0; 
    } 

    if (componentEmpty) 
    { 
     return -1; 
    } 

    if (otherEmtpy) 
    { 
     return 1; 
    } 

    string[] componentParts = componentString.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); 
    string[] otherParts = other.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); 

    for (int i = 0; i < Math.Min(componentParts.Length, otherParts.Length); i++) 
    { 
     string componentChar = componentParts[i]; 
     string otherChar = otherParts[i]; 
     int componentNumVal, otherNumVal; 
     bool componentIsNum = int.TryParse(componentChar, out componentNumVal); 
     bool otherIsNum = int.TryParse(otherChar, out otherNumVal); 

     if (componentIsNum && otherIsNum) 
     { 
      if (componentNumVal.CompareTo(otherNumVal) == 0) 
      { 
       continue; 
      } 

      return componentNumVal.CompareTo(otherNumVal); 
     } 
     else 
     { 
      if (componentIsNum) 
      { 
       return -1; 
      } 

      if (otherIsNum) 
      { 
       return 1; 
      } 

      int comp = string.Compare(componentChar, otherChar, StringComparison.OrdinalIgnoreCase); 

      if (comp != 0) 
      { 
       return comp; 
      } 
     } 
    } 

    return componentParts.Length.CompareTo(otherParts.Length); 
} 

这是可能被使用的字符串。在使用减号后,我可能只添加部分。

  • 1.0.0-α
  • 1.0.0-alpha.1
  • 1.0.0-alpha.beta
  • 1.0.0-beta.2
+0

如果你能给出一些你的字符串的例子,对我们来说会更容易。 – wimh

+1

如果您只比较一个数字,则字符串比较会给出与解析和执行整数比较相同的结果。但是,您还应该考虑是否有可能将数字与ASCII进行比较的情况,如果是,应该发生什么情况。 –

+0

我添加了我目前使用的代码 – Ruhrpottpatriot

回答

0

使用此方法,您可以为每个字符串创建一个比较字符串。这些字符串可以通过简单的字母数字比较进行比较。

假设:

  • 有字符串中减去分离公共部分和所述逐张部分
  • 之前减号是总是 3个整数值的一个子用圆点
  • 划分
  • 这些整数值不高于999(看变量“MaxWidth1”)
  • 后面 mi nus是由多个部分组成的另一个子字符串,也被点分开
  • 第二个子字符串的部分可能是数字或字母数字,宽度7(看“MaxWidth2”)
  • 第二个子字符串由最大值组成。 5份(MaxIndivParts)

将这个方法不管你想要的:

public string VersionNumberCompareString(string versionNumber, int MaxWidth1=3, int MaxWidth2=7,int MaxIndivParts=5){ 
    string result = null; 

    int posMinus = versionNumber.IndexOf('-'); 
    string part1 = versionNumber.Substring(0, posMinus); 
    string part2 = versionNumber.Substring(posMinus+1); 

    var integerValues=part1.Split('.'); 
    result = integerValues[0].PadLeft(MaxWidth1, '0'); 
    result += integerValues[1].PadLeft(MaxWidth1, '0'); 
    result += integerValues[2].PadLeft(MaxWidth1, '0'); 

    var alphaValues = part2.Split('.'); 
    for (int i = 0; i < MaxIndivParts;i++) { 
     if (i <= alphaValues.GetUpperBound(0)) { 
      var s = alphaValues[i]; 
      int casted; 
      if (int.TryParse(s, out casted)) //if int: treat as number 
       result += casted.ToString().PadLeft(MaxWidth2, '0'); 
      else //treat as string 
       result += s.PadRight(MaxWidth2, ' '); 
    } 
    else 
     result += new string(' ', MaxWidth2); 
} 
return result; } 

你这样称呼它:

var s1 = VersionNumberCompareString("1.3.0-alpha.1.12"); 
//"001003000alpha 00000010000012    " 
var s2 = VersionNumberCompareString("0.11.4-beta");  
//"000011004beta        " 
var s3 = VersionNumberCompareString("2.10.11-beta.2"); 
//"002010011beta 0000002      "       

注意最后"标志。所有的字符串都是相同的长度!

希望这会有所帮助...

0

这是.NET话说回来

private unsafe static int CompareOrdinalIgnoreCaseHelper(String strA, String strB) 
    { 
     Contract.Requires(strA != null); 
     Contract.Requires(strB != null); 
     Contract.EndContractBlock(); 
     int length = Math.Min(strA.Length, strB.Length); 

     fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar) 
     { 
      char* a = ap; 
      char* b = bp; 

      while (length != 0) 
      { 
       int charA = *a; 
       int charB = *b; 

       Contract.Assert((charA | charB) <= 0x7F, "strings have to be ASCII"); 

       // uppercase both chars - notice that we need just one compare per char 
       if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20; 
       if ((uint)(charB - 'a') <= (uint)('z' - 'a')) charB -= 0x20; 

       //Return the (case-insensitive) difference between them. 
       if (charA != charB) 
        return charA - charB; 

       // Next char 
       a++; b++; 
       length--; 
      } 

      return strA.Length - strB.Length; 
     } 
    } 

,除非你有一个严格的性能constaint,IW - 为ASCII字符串比较逻辑应该说如果你从已经实现的测试函数中得到了相同的结果,那么它更好地重用它,而不是重新发明轮子。 它节省了很多时间在执行,单元测试,调试&错误修复时间。 &有助于保持软件简单。