После прочтения вашего вопроса и уже приведенных ответов я думаю, что отсутствуют некоторые ограничения, которые могут быть очевидны для вас, но не для сообщества. Но, может быть, мы можем сделать небольшую догадку:
- У вас будет несколько пар строк, которые нужно сравнить.
- Две строки в каждой паре имеют одинаковую длину или вас интересует только сравнение символов, читаемых одновременно слева направо.
- Получите какое-нибудь перечисление, которое говорит мне, где начинается каждый блок и как долго это продолжается.
В связи с тем, что строка является только перечислением символов, вы можете использовать LINQ здесь, чтобы получить представление о соответствующих символах, например:
private IEnumerable<bool> CommonChars(string first, string second)
{
if (first == null)
throw new ArgumentNullException("first");
if (second == null)
throw new ArgumentNullException("second");
var charsToCompare = first.Zip(second, (LeftChar, RightChar) => new { LeftChar, RightChar });
var matchingChars = charsToCompare.Select(pair => pair.LeftChar == pair.RightChar);
return matchingChars;
}
С этим мы можем продолжить и теперь выяснить, как долго каждый блок последовательных флагов истины и ложи имеет этот метод:
private IEnumerable<Tuple<int, int>> Pack(IEnumerable<bool> source)
{
if (source == null)
throw new ArgumentNullException("source");
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
yield break;
}
bool current = iterator.Current;
int index = 0;
int length = 1;
while (iterator.MoveNext())
{
if(current != iterator.Current)
{
yield return Tuple.Create(index, length);
index += length;
length = 0;
}
current = iterator.Current;
length++;
}
yield return Tuple.Create(index, length);
}
}
В настоящее время я не знаю, существует ли уже существующая функция LINQ, которая обеспечивает такую же функциональность. Насколько я уже читал, это возможно с помощью SelectMany()
(потому что теоретически вы можете выполнить любую задачу LINQ с помощью этого метода), но как временная реализация вышеописанное было проще (для меня).
Эти функции затем можно использовать примерно так:
var firstString = "bc3231dsc";
var secondString = "bc3462dsc";
var commonChars = CommonChars(firstString, secondString);
var packs = Pack(commonChars);
foreach (var item in packs)
{
Console.WriteLine("Left side: " + firstString.Substring(item.Item1, item.Item2));
Console.WriteLine("Right side: " + secondString.Substring(item.Item1, item.Item2));
Console.WriteLine();
}
Что бы вы тогда выдали:
Левая сторона: bc3
Правая сторона: bc3
Левая сторона: 231
Правая сторона: 462
Левая сторона: DSC
Правая сторона: дск
Самым большим недостатком является использование Tuple
, поскольку оно приводит к появлению уродливых имен свойств Item1
и Item2
, которые далеки от мгновенного чтения. Но если это действительно необходимо, вы можете представить свой собственный простой класс, содержащий два целых числа и обладающий некоторыми качественными именами свойств. Также в настоящее время теряется информация о том, является ли каждый блок общим для обеих строк или они различны. Но, опять же, должно быть довольно просто получить эту информацию также в кортеж или в ваш собственный класс.