Подтвердить что ты не робот

С# метод сравнения строк, возвращающий индекс первого несоответствия

Есть ли метод сравнения exsting string, который будет возвращать значение, основанное на первом возникновении несоответствующего символа между двумя строками?

то есть.

string A = "1234567890"

string B = "1234567880"

Я хотел бы получить значение обратно, которое позволило бы мне увидеть, что первое появление совпадающего разрыва - A [8]

4b9b3361

Ответ 1

/// <summary>
/// Gets a first different char occurence index
/// </summary>
/// <param name="a">First string</param>
/// <param name="b">Second string</param>
/// <param name="handleLengthDifference">
/// If true will return index of first occurence even strings are of different length
/// and same-length parts are equals otherwise -1
/// </param>
/// <returns>
/// Returns first difference index or -1 if no difference is found
/// </returns>
public int GetFirstBreakIndex(string a, string b, bool handleLengthDifference)
{
    int equalsReturnCode = -1;
    if (String.IsNullOrEmpty(a) || String.IsNullOrEmpty(b))
    {
        return handleLengthDifference ? 0 : equalsReturnCode;
    }

    string longest = b.Length > a.Length ? b : a;
    string shorten = b.Length > a.Length ? a : b;    
    for (int i = 0; i < shorten.Length; i++)
    {
        if (shorten[i] != longest[i])
        {
            return i;
        }
    }

    // Handles cases when length is different (a="1234", b="123")
    // index=3 would be returned for this case
    // If you do not need such behaviour - just remove this
    if (handleLengthDifference && a.Length != b.Length)
    {
        return shorten.Length;
    }

    return equalsReturnCode;
}

Ответ 2

Метод расширения по строкам ниже выполнит задание:

public static int Your_Name_Here(this string s, string other) 
{
    string first = s.Length < other.Length ? s : other;
    string second = s.Length > other.Length ? s : other;

    for (int counter = 0; counter < first.Length; counter++)
    {
        if (first[counter] != second[counter])
        {
            return counter;
        }
    }
    return -1;
}

Ответ 3

Не то, чтобы я знал, но это довольно тривиально:

public static int FirstUnmatchedIndex(this string x, string y)
{
  if(x == null || y == null)
    throw new ArgumentNullException();
  int count = x.Length;
  if(count > y.Length)
    return FirstUnmatchedIndex(y, x);
  if(ReferenceEquals(x, y))
    return -1;
  for(idx = 0; idx != count; ++idx)
    if(x[idx] != y[idx])
      return idx;
  return count == y.Length? -1 : count;
}

Это простое порядковое сравнение. Ориентированное без учета регистра сравнение - это легкое изменение, но основа культуры сложно определить; "Weißbier" не соответствует "WEISSBIERS" на финале S во второй строке, но делает ли это как позицию 8 или позицию 9?

Ответ 4

Если у вас установлен .net 4.0, это может быть способом:

    string A = "1234567890";
    string B = "1234567880";

    char? firstocurrence = A.Zip(B, (p, q) => new { A = p, B = q })
        .Where(p => p.A != p.B)
        .Select(p => p.A)
        .FirstOrDefault();

редактировать:

Хотя, если вам нужна должность:

    int? firstocurrence = A.Zip(B, (p, q) => new { A = p, B = q })
            .Select((p, i) => new { A = p.A, B = p.B, idx = i })
            .Where(p => p.A != p.B)
            .Select(p => p.idx)
            .FirstOrDefault();

Ответ 5

Можно написать расширение строки, например

public static class MyExtensions
{
    public static IList<char> Mismatch(this string str1, string str2)
    {
        var char1 = str1.ToCharArray();
        var char2 = str2.ToCharArray();
        IList<Char> Resultchar= new List<char>();
        for (int i = 0; i < char2.Length;i++ )
        {
            if (i >= char1.Length || char1[i] != char2[i])
                Resultchar.Add(char2[i]);
        }
        return Resultchar;
    }
}

Используйте его как

var r = "1234567890".Mismatch("1234567880");

Это не оптимизированный алгоритм поиска несоответствия.

Если вам интересно только найти первое несоответствие,

public static Char FirstMismatch(this string str1, string str2)
        {
            var char1 = str1.ToCharArray();
            var char2 = str2.ToCharArray();             
            for (int i = 0; i < char2.Length;i++ )
            {
                if (i >= char1.Length || char1[i] != char2[i])
                    return char2[i];
            }
            return ''c;
        }

Ответ 7

var indexOfFirstMismatch = Enumerable.Range(0, strA.Length).FirstOrDefault(i => strB.StartsWith(strA.Substring(0, i)) == false);