Loading,你用IE,难怪你打不开

给一个字符串数组,输出不同的部分

豆包给出代码
image

/// <summary>
/// 字符串差异提取工具类(仅使用原字符串字符)
/// </summary>
public static class StringDiffExtractor
{
    /// <summary>
    /// 从字符串列表中提取差异部分,差异部分仅包含原字符串已有字符,且长度不小于指定最小值(若原字符串长度允许)
    /// </summary>
    /// <param name="inputStrings">输入的字符串列表</param>
    /// <param name="minLength">差异部分的最小长度(必须大于0)</param>
    /// <returns>各字符串对应的差异部分(完全来自原字符串)</returns>
    /// <exception cref="ArgumentOutOfRangeException">当minLength小于或等于0时抛出</exception>
    public static List<string> ExtractDiffParts(List<string> inputStrings, int minLength)
    {
        List<string> diffResults = new List<string>();

        if (inputStrings == null || inputStrings.Count == 0)
            return diffResults;

        // 单元素场景:差异部分就是字符串本身(长度不足时返回全部,不补位)
        if (inputStrings.Count == 1)
        {
            string singleStr = inputStrings[0];
            diffResults.Add(singleStr); // 直接返回原字符串,不添加任何外部字符
            return diffResults;
        }

        int commonPrefixLength = CalculateCommonPrefixLength(inputStrings);
        int commonSuffixLength = CalculateCommonSuffixLength(inputStrings);

        foreach (string str in inputStrings)
        {
            // 1. 原始差异区域(前缀后、后缀前)
            int originalDiffStart = commonPrefixLength;
            int originalDiffLength = str.Length - commonPrefixLength - commonSuffixLength;

            // 2. 计算需要扩展的长度(但不能超出字符串范围)
            int needExtendLength = Math.Max(0, minLength - originalDiffLength);
            int maxPossibleExtend = originalDiffStart; // 最多能向前扩展的长度(不能超过前缀起始位置)
            int actualExtendLength = Math.Min(needExtendLength, maxPossibleExtend);

            // 3. 调整提取范围(确保所有字符都来自原字符串)
            int adjustedStartIndex = originalDiffStart - actualExtendLength;
            int adjustedDiffLength = originalDiffLength + actualExtendLength;

            // 4. 最终提取(若总长度仍不足minLength,返回能提取的最大长度)
            if (adjustedStartIndex + adjustedDiffLength > str.Length)
            {
                adjustedDiffLength = str.Length - adjustedStartIndex;
            }

            string diffPart = adjustedDiffLength > 0
                ? str.Substring(adjustedStartIndex, adjustedDiffLength)
                : string.Empty;

            diffResults.Add(diffPart);
        }

        return diffResults;
    }

    /// <summary>计算共同前缀长度</summary>
    private static int CalculateCommonPrefixLength(List<string> strings)
    {
        int minStrLength = strings.Min(s => s.Length);
        for (int i = 0; i < minStrLength; i++)
        {
            char currentChar = strings[0][i];
            if (strings.Any(s => s[i] != currentChar))
                return i;
        }
        return minStrLength;
    }

    /// <summary>计算共同后缀长度</summary>
    private static int CalculateCommonSuffixLength(List<string> strings)
    {
        int minStrLength = strings.Min(s => s.Length);
        for (int i = 1; i <= minStrLength; i++)
        {
            char currentChar = strings[0][strings[0].Length - i];
            if (strings.Any(s => s.Length < i || s[s.Length - i] != currentChar))
                return i - 1;
        }
        return minStrLength;
    }

    public static void Test1()
    {
        // 测试数据
        var testData = new List<string>
        {
            "2T1283223072900029D1ZZZ",
            "2T1283223072900028D2ZZZ",
            "2T1283223072900027D3ZZZ",
            "2T1283223072900026D4ZZZ",
            "2T1283223072900025D5ZZZ",
            "2T1283223072900024D6ZZZ"
        };
        var results1 = StringDiffExtractor.ExtractDiffParts(testData, 0);

        testData = new List<string>
        {
            "NL5285A24071300005DEDF",
            "NL5285A24071300004DEDF",
            "NL5285A24071300003DEDF",
            "NL5285A24071300002DEDF"
        };
        var results2 = StringDiffExtractor.ExtractDiffParts(testData, 0);

        testData = new List<string>
        {
            "NL5285A24071300005",
            "NL5285A24071300004",
            "NL5285A24071300003",
            "NL5285A24071300002"
        };
        var results3 = StringDiffExtractor.ExtractDiffParts(testData, 0);

        testData = new List<string>
        {
            "E26U00089",
            "E26U00090",
            "E26U00091"
        };
        var results4 = StringDiffExtractor.ExtractDiffParts(testData, 0);
    }
    public static void Test2()
    {
        // 测试数据
        var testData = new List<string>
        {
            "2T1283223072900029D1ZZZ",
            "2T1283223072900028D2ZZZ",
            "2T1283223072900027D3ZZZ",
            "2T1283223072900026D4ZZZ",
            "2T1283223072900025D5ZZZ",
            "2T1283223072900024D6ZZZ"
        };
        var results1 = StringDiffExtractor.ExtractDiffParts(testData, 4);

        testData = new List<string>
        {
            "NL5285A24071300005DEDF",
            "NL5285A24071300004DEDF",
            "NL5285A24071300003DEDF",
            "NL5285A24071300002DEDF"
        };
        var results2 = StringDiffExtractor.ExtractDiffParts(testData, 4);

        testData = new List<string>
        {
            "NL5285A24071300005",
            "NL5285A24071300004",
            "NL5285A24071300003",
            "NL5285A24071300002"
        };
        var results3 = StringDiffExtractor.ExtractDiffParts(testData, 4);

        testData = new List<string>
        {
            "E26U00089",
            "E26U00090",
            "E26U00091"
        };
        var results4 = StringDiffExtractor.ExtractDiffParts(testData, 4);
    }
}
Imports System
Imports System.Collections.Generic
Imports System.Linq

''' <summary>
''' 字符串差异提取工具类(仅使用原字符串字符)
''' </summary>
Public NotInheritable Class StringDiffExtractor
    ''' <summary>
    ''' 从字符串列表中提取差异部分,差异部分仅包含原字符串已有字符,且长度不小于指定最小值(若原字符串长度允许)
    ''' </summary>
    ''' <param name="inputStrings">输入的字符串列表</param>
    ''' <param name="minLength">差异部分的最小长度(必须大于0)</param>
    ''' <returns>各字符串对应的差异部分(完全来自原字符串)</returns>
    ''' <exception cref="ArgumentOutOfRangeException">当minLength小于或等于0时抛出</exception>
    Public Shared Function ExtractDiffParts(ByVal inputStrings As List(Of String), ByVal minLength As Integer, Optional ByVal paddingStr As String = "") As List(Of String)
        Dim diffResults As New List(Of String)()
        ' 处理空输入
        If inputStrings Is Nothing OrElse inputStrings.Count = 0 Then
            Return diffResults
        ElseIf inputStrings.Count = 1 Then   ' 单元素场景:直接返回原字符串(不补位)
            diffResults.Add(If(minLength = 0, inputStrings(0), If(paddingStr Is Nothing, "", paddingStr) + inputStrings(0).Substring(Math.Max(0, inputStrings(0).Length - minLength))))
            Return diffResults
        End If




        ' 计算共同前缀和后缀长度
        Dim commonPrefixLength As Integer = CalculateCommonPrefixLength(inputStrings)
        Dim commonSuffixLength As Integer = CalculateCommonSuffixLength(inputStrings)

        ' 遍历每个字符串提取差异
        For Each str As String In inputStrings
            ' 1. 计算原始差异区域(前缀后 + 后缀前)
            Dim originalDiffStart As Integer = commonPrefixLength
            Dim originalDiffLength As Integer = str.Length - commonPrefixLength - commonSuffixLength

            ' 2. 计算需要扩展的长度(不超出字符串范围)
            Dim needExtendLength As Integer = Math.Max(0, minLength - originalDiffLength)
            Dim maxPossibleExtend As Integer = originalDiffStart ' 最多向前扩展到字符串起始位置
            Dim actualExtendLength As Integer = Math.Min(needExtendLength, maxPossibleExtend)

            ' 3. 调整提取范围(确保字符均来自原字符串)
            Dim adjustedStartIndex As Integer = originalDiffStart - actualExtendLength
            Dim adjustedDiffLength As Integer = originalDiffLength + actualExtendLength

            ' 4. 防止索引越界,提取最终差异
            If adjustedStartIndex + adjustedDiffLength > str.Length Then
                adjustedDiffLength = str.Length - adjustedStartIndex
            End If

            Dim diffPart As String = If(commonPrefixLength > 0, paddingStr, "") + If(adjustedDiffLength > 0, str.Substring(adjustedStartIndex, adjustedDiffLength), String.Empty) + If(commonSuffixLength > 0, paddingStr, "")
            diffResults.Add(diffPart)
        Next

        Return diffResults
    End Function

    ''' <summary>计算字符串列表的共同前缀长度</summary>
    Private Shared Function CalculateCommonPrefixLength(ByVal strings As List(Of String)) As Integer
        Dim minStrLength As Integer = strings.Min(Function(s) s.Length)
        For i As Integer = 0 To minStrLength - 1
            Dim currentChar As Char = strings(0)(i)
            ' 只要有一个字符串当前位置字符不同,返回当前索引
            If strings.Any(Function(s) s(i) <> currentChar) Then
                Return i
            End If
        Next
        ' 所有字符串完全相同,返回最短长度
        Return minStrLength
    End Function

    ''' <summary>计算字符串列表的共同后缀长度</summary>
    Private Shared Function CalculateCommonSuffixLength(ByVal strings As List(Of String)) As Integer
        Dim minStrLength As Integer = strings.Min(Function(s) s.Length)
        For i As Integer = 1 To minStrLength
            Dim currentChar As Char = strings(0)(strings(0).Length - i)
            ' 只要有一个字符串当前位置字符不同,返回已确认的后缀长度
            If strings.Any(Function(s) s.Length < i OrElse s(s.Length - i) <> currentChar) Then
                Return i - 1
            End If
        Next
        ' 所有字符串完全相同,返回最短长度
        Return minStrLength
    End Function

    ''' <summary>测试方法:minLength=0(直接返回原始差异)</summary>
    Public Shared Sub Test1()
        ' 第一组测试数据
        Dim testData1 As New List(Of String) From {
            "2T1283223072900029D1ZZZ",
            "2T1283223072900028D2ZZZ",
            "2T1283223072900027D3ZZZ",
            "2T1283223072900026D4ZZZ",
            "2T1283223072900025D5ZZZ",
            "2T1283223072900024D6ZZZ"
        }
        Dim results1 As List(Of String) = StringDiffExtractor.ExtractDiffParts(testData1, 0)

        ' 第二组测试数据
        Dim testData2 As New List(Of String) From {
            "NL5285A24071300005DEDF",
            "NL5285A24071300004DEDF",
            "NL5285A24071300003DEDF",
            "NL5285A24071300002DEDF"
        }
        Dim results2 As List(Of String) = StringDiffExtractor.ExtractDiffParts(testData2, 0)

        ' 第三组测试数据
        Dim testData3 As New List(Of String) From {
            "NL5285A24071300005",
            "NL5285A24071300004",
            "NL5285A24071300003",
            "NL5285A24071300002"
        }
        Dim results3 As List(Of String) = StringDiffExtractor.ExtractDiffParts(testData3, 0)

        ' 第四组测试数据
        Dim testData4 As New List(Of String) From {
            "E26U00089",
            "E26U00090",
            "E26U00091"
        }
        Dim results4 As List(Of String) = StringDiffExtractor.ExtractDiffParts(testData4, 0)
    End Sub

    ''' <summary>测试方法:minLength=4(扩展到4位差异)</summary>
    Public Shared Sub Test2()
        ' 第一组测试数据
        Dim testData1 As New List(Of String) From {
            "2T1283223072900029D1ZZZ",
            "2T1283223072900028D2ZZZ",
            "2T1283223072900027D3ZZZ",
            "2T1283223072900026D4ZZZ",
            "2T1283223072900025D5ZZZ",
            "2T1283223072900024D6ZZZ"
        }
        Dim results1 As List(Of String) = StringDiffExtractor.ExtractDiffParts(testData1, 4)

        ' 第二组测试数据
        Dim testData2 As New List(Of String) From {
            "NL5285A24071300005DEDF",
            "NL5285A24071300004DEDF",
            "NL5285A24071300003DEDF",
            "NL5285A24071300002DEDF"
        }
        Dim results2 As List(Of String) = StringDiffExtractor.ExtractDiffParts(testData2, 4)

        ' 第三组测试数据
        Dim testData3 As New List(Of String) From {
            "NL5285A24071300005",
            "NL5285A24071300004",
            "NL5285A24071300003",
            "NL5285A24071300002"
        }
        Dim results3 As List(Of String) = StringDiffExtractor.ExtractDiffParts(testData3, 4)

        ' 第四组测试数据
        Dim testData4 As New List(Of String) From {
            "E26U00089",
            "E26U00090",
            "E26U00091"
        }
        Dim results4 As List(Of String) = StringDiffExtractor.ExtractDiffParts(testData4, 4)
    End Sub
End Class
posted @ 2025-10-13 22:47  老板娘的神秘商店  阅读(10)  评论(0)    收藏  举报