返回字符串之间第一个差异的索引

时间:2018-03-02 00:52:25

标签: c#

我想知道是否有一种奇特的方法来找到索引,字符串a中的第一个字符与字符串b的相同位置中的字符不匹配,除了使用强力。

这是蛮力企图:

bool OnlyDiffersByCarotsAndSpaces(string a, string b)
{
    if( a.Count() != b.Count() )
    {
        return false;
    }

    for(int index = 0; index < a.Count(); ++index)
    {
        if( a[index] != b[index] )
        {
            string validCharacters = " ^";

            if( !validCharacters.Contains(a[index]) ||
                !validCharacters.Contains(b[index]) )
            {
                return false;
            }
        }
    }

    return true;
}

4 个答案:

答案 0 :(得分:1)

我认为您可以使用string.Split的组合将字符串拆分为数组,拆分&#34;有效字符&#34;,然后返回IEnumerable.SequenceEqual的结果,如果两个IEnumerables包含相同顺序的相同元素,则返回true:

private static bool OnlyDiffersByCarotsAndSpaces(string a, string b)
{
    // A few "exit quick" checks...
    if (a == null) return b == null;
    if (b == null) return false;

    var validChars = new[] {' ', '^'};
    var first = a.Split(validChars);
    var second = b.Split(validChars);

    return first.SequenceEqual(second);
}

答案 1 :(得分:0)

int DifferenceIndex(string str1, string str2)
{
    int position = 0;
    int min = Math.Min(str1.Length, str2.Length);
    while (position < min && str1[position] == str2[position]) 
        position ++;

    return (position == min && str1.Length == str2.Length) ? -1 : position;
}

如果字符串相同,则返回-1。

答案 2 :(得分:0)

有人说好看吗? :)对于高流量和大字符串,这个版本的性能肯定比你的版本差,所以根据性能要求你可能不想使用它。

if (a.Length != b.Length) return -1;   
string allowed = " ^";
a = a.Replace(' ', '^');
b = b.Replace(' ', '^');
//at this point you can do string.Equals(a,b) and it will work correctly
var equalCharCount = a.Zip(b, (c1, c2) => c1 == c2).TakeWhile(c => c).Count();
//or even
//var idx = 0;
//var equalCharCont = a.TakeWhile(c => c == b[idx++]).Count() + 1;

稍微更漂亮,表现更差,未完成且最可能错误的想法是:

var idx = a.Zip(b, (i1, i2) => Tuple.Create(i1, i2))
           .Select((value, index) => new { value, index })
           .SkipWhile(it => it.value.Item1 == it.value.Item2 || 
                                (allowed.Contains(it.value.Item1) && 
                                 allowed.Contains(it.value.Item2)))
           .Select(it => it.index)
           .First() + 1;

答案 3 :(得分:0)

那么,这取决于你对“幻想”的意思,以及这是否真的是你想要的。对于像这样的小实用程序,通常更好的是尽可能快地做出一点点的忙乱。涉及IEnumerable的解决方案几乎肯定会更具可读性和“优雅”,但在幕后,他们将完成同样的事情,但可能会有更多的开销。

这种方法比原来的方法略显“粗暴”和“更加强大”。

bool OnlyDiffersByCarotsAndSpaces(string a, string b)
{
  int len = a.Length; // eliminate Count() function call
  if (len != b.Length)
  {
    return false;
  }

  for (int index = 0; index < len; ++index)
  {
    if ((a[index] != b[index]) &&
        (((a[index] != ' ') && (a[index] != '^')) ||  // eliminate Contains() method calls
         ((b[index] != ' ') && (b[index] != '^'))))   //
    {
      return false;
    }
  }

  return true;
}