两个字符串之间的所有公共子字符串

2023-11-25

我正在使用 C# 来查找两个字符串之间的所有公共子字符串。例如,如果输入是: S1=“需要电子邮件方面的帮助” S2=“需要电子邮件帮助”

输出应该是-“需要帮助电子邮件”

下面的代码返回最长的公共子字符串,但我希望我的代码返回所有公共子字符串。任何帮助深表感谢!

static void commonsubstrings()
    {
        input1 = "need asssitance with email";
        input2 = "email assistance needed"

        if (input2.Length > input1.Length)
        {
            swap = input1;
            input1 = input2;
            input2 = swap;
        }

        int k = 1;
        String temp;
        String longTemp = "";
        for (int i = 0; (i <= input1.Length); i++)
        {
            if ((i == input1.Length))
            {
                if (longest != null)
                {
                    k = longest.Length + 1;
                }
                else
                {
                    k = 1;
                }
                temp = input1.Substring(1, input1.Length - 1);
                if (temp.Equals(""))
                {
                    break;
                }
                if (k <= temp.Length)
                {
                    i = k - 1;
                    input1 = temp;
                    if ((longest != null) && (longest.Length > longTemp.Length))
                    {
                        longTemp = longest;
                    }
                }
            }
            holder1 = input1.Substring(0, k);

            for (int j = 0; (j < input2.Length) && (j + k <= input2.Length); j++)
            {
                check1 = input2.Substring(j, k);
                if (holder1.Equals(check1))
                {
                    longest = holder1;
                    break;
                }
            }
            k++;
        }

        Console.WriteLine(longest);
        Console.ReadLine(); 

}


另一种方法:您可以使用编辑距离找出两个词的相似度。如果距离小于指定值,您可以认为两个字符串相等。然后你可以使用levenshtein比较器Enumerable.Intersect.

那么就简单了:

string S1= "need asssitance with email" ;
string S2 = "email assistance needed";
string[] words1 = S1.Split();
string[] words2 = S2.Split();
var wordsIntersecting = words1.Intersect(words2, new LevenshteinComparer());
string output = string.Join(" ", wordsIntersecting);

output: need asssitance email

这是自定义比较器:

class LevenshteinComparer : IEqualityComparer<string>
{
    public int MaxDistance { get; set; }
    private Levenshtein _Levenshtein = new Levenshtein();

    public LevenshteinComparer() : this(50) { }

    public LevenshteinComparer(int maxDistance)
    {
        this.MaxDistance = maxDistance;
    }

    public bool Equals(string x, string y)
    {
        int distance = _Levenshtein.iLD(x, y);
        return distance <= MaxDistance;
    }

    public int GetHashCode(string obj)
    {
        return 0; 
    }
}

这是 levenshtein 算法的实现:

public class Levenshtein
{
    ///*****************************
    /// Compute Levenshtein distance 
    /// Memory efficient version
    ///*****************************
    public int iLD(String sRow, String sCol)
    {
        int RowLen = sRow.Length;  // length of sRow
        int ColLen = sCol.Length;  // length of sCol
        int RowIdx;                // iterates through sRow
        int ColIdx;                // iterates through sCol
        char Row_i;                // ith character of sRow
        char Col_j;                // jth character of sCol
        int cost;                   // cost

        /// Test string length
        if (Math.Max(sRow.Length, sCol.Length) > Math.Pow(2, 31))
            throw (new Exception("\nMaximum string length in Levenshtein.iLD is " + Math.Pow(2, 31) + ".\nYours is " + Math.Max(sRow.Length, sCol.Length) + "."));

        // Step 1

        if (RowLen == 0)
        {
            return ColLen;
        }

        if (ColLen == 0)
        {
            return RowLen;
        }

        /// Create the two vectors
        int[] v0 = new int[RowLen + 1];
        int[] v1 = new int[RowLen + 1];
        int[] vTmp;



        /// Step 2
        /// Initialize the first vector
        for (RowIdx = 1; RowIdx <= RowLen; RowIdx++)
        {
            v0[RowIdx] = RowIdx;
        }

        // Step 3

        /// Fore each column
        for (ColIdx = 1; ColIdx <= ColLen; ColIdx++)
        {
            /// Set the 0'th element to the column number
            v1[0] = ColIdx;

            Col_j = sCol[ColIdx - 1];


            // Step 4

            /// Fore each row
            for (RowIdx = 1; RowIdx <= RowLen; RowIdx++)
            {
                Row_i = sRow[RowIdx - 1];


                // Step 5

                if (Row_i == Col_j)
                {
                    cost = 0;
                }
                else
                {
                    cost = 1;
                }

                // Step 6

                /// Find minimum
                int m_min = v0[RowIdx] + 1;
                int b = v1[RowIdx - 1] + 1;
                int c = v0[RowIdx - 1] + cost;

                if (b < m_min)
                {
                    m_min = b;
                }
                if (c < m_min)
                {
                    m_min = c;
                }

                v1[RowIdx] = m_min;
            }

            /// Swap the vectors
            vTmp = v0;
            v0 = v1;
            v1 = vTmp;

        }


        // Step 7

        /// Value between 0 - 100
        /// 0==perfect match 100==totaly different
        /// 
        /// The vectors where swaped one last time at the end of the last loop,
        /// that is why the result is now in v0 rather than in v1
        //System.Console.WriteLine("iDist=" + v0[RowLen]);
        int max = System.Math.Max(RowLen, ColLen);
        return ((100 * v0[RowLen]) / max);
    }





    ///*****************************
    /// Compute the min
    ///*****************************

    private int Minimum(int a, int b, int c)
    {
        int mi = a;

        if (b < mi)
        {
            mi = b;
        }
        if (c < mi)
        {
            mi = c;
        }

        return mi;
    }

    ///*****************************
    /// Compute Levenshtein distance         
    ///*****************************

    public int LD(String sNew, String sOld)
    {
        int[,] matrix;              // matrix
        int sNewLen = sNew.Length;  // length of sNew
        int sOldLen = sOld.Length;  // length of sOld
        int sNewIdx; // iterates through sNew
        int sOldIdx; // iterates through sOld
        char sNew_i; // ith character of sNew
        char sOld_j; // jth character of sOld
        int cost; // cost

        /// Test string length
        if (Math.Max(sNew.Length, sOld.Length) > Math.Pow(2, 31))
            throw (new Exception("\nMaximum string length in Levenshtein.LD is " + Math.Pow(2, 31) + ".\nYours is " + Math.Max(sNew.Length, sOld.Length) + "."));

        // Step 1

        if (sNewLen == 0)
        {
            return sOldLen;
        }

        if (sOldLen == 0)
        {
            return sNewLen;
        }

        matrix = new int[sNewLen + 1, sOldLen + 1];

        // Step 2

        for (sNewIdx = 0; sNewIdx <= sNewLen; sNewIdx++)
        {
            matrix[sNewIdx, 0] = sNewIdx;
        }

        for (sOldIdx = 0; sOldIdx <= sOldLen; sOldIdx++)
        {
            matrix[0, sOldIdx] = sOldIdx;
        }

        // Step 3

        for (sNewIdx = 1; sNewIdx <= sNewLen; sNewIdx++)
        {
            sNew_i = sNew[sNewIdx - 1];

            // Step 4

            for (sOldIdx = 1; sOldIdx <= sOldLen; sOldIdx++)
            {
                sOld_j = sOld[sOldIdx - 1];

                // Step 5

                if (sNew_i == sOld_j)
                {
                    cost = 0;
                }
                else
                {
                    cost = 1;
                }

                // Step 6

                matrix[sNewIdx, sOldIdx] = Minimum(matrix[sNewIdx - 1, sOldIdx] + 1, matrix[sNewIdx, sOldIdx - 1] + 1, matrix[sNewIdx - 1, sOldIdx - 1] + cost);

            }
        }

        // Step 7

        /// Value between 0 - 100
        /// 0==perfect match 100==totaly different
        System.Console.WriteLine("Dist=" + matrix[sNewLen, sOldLen]);
        int max = System.Math.Max(sNewLen, sOldLen);
        return (100 * matrix[sNewLen, sOldLen]) / max;
    }
}

Levenshtein 类的功劳是:http://www.codeproject.com/Articles/13525/Fast-memory-efficient-Levenshtein-algorithm

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

两个字符串之间的所有公共子字符串 的相关文章

随机推荐

  • 转换为 ARC - LLVM 编译器 3.0 错误

    我打开了我的一个旧项目并选择Convert to Objective C ARC从编辑 重构菜单 我收到以下错误 Apple LLVM compiler 3 0 Error Error in format of file Users myU
  • XPath:从子节点获取父节点

    我需要获取子节点的父节点title 50 目前我只使用 title 50 我怎样才能得到它的父母 结果应该是store node
  • 如何使用 Webpack 和 Angular2 包含外部 css 文件?

    我正在尝试使用 Webpack 添加对 Angular2 中 CSS 文件的外部引用 我的CSS定义为 test css loader style loader css loader 在我的 webpack config js 文件中 在打
  • Ruby:将转义字符串写入 YAML

    下列 require yaml test I m a b d string File open test yaml w do out out write test to yaml end 输出 this is a b d string 我怎
  • Lucene.Net 写/读同步

    我可以写 与IndexWriter 在打开阅读时将新文档放入索引 使用IndexReader 或者我必须在写作之前关闭阅读 我可以阅读 搜索文档吗 使用IndexReader 在索引中 当它打开用于写入时 与IndexWriter 或者我必
  • 扭曲应用程序的 Web 界面

    我有一个用 Twisted 编写的应用程序 我想添加一个 Web 界面来控制和监视它 我需要大量的动态页面来显示当前状态和配置 因此我希望有一个框架至少提供一种具有继承和一些基本路由的模板语言 因为我正在使用 Twisted 无论如何我想使
  • Firebase 更改显示在谷歌登录警报上的应用程序名称?

    我有一个 firebase 项目 但不知何故我输错了应用程序名称 有没有办法更改谷歌登录警报上显示的应用程序名称 您应该更改项目中的产品名称
  • 如何在 ASP.NET Core 中的自定义 TagHelper 中渲染 Razor 模板?

    我正在创建一个自定义 HTML 标记帮助程序 public class CustomTagHelper TagHelper HtmlAttributeName asp for public ModelExpression DataModel
  • 如何删除名称以“-”开头的文件[重复]

    这个问题在这里已经有答案了 在脚本中出现错误后 我最终得到了一个名称以破折号开头的文件 myfile txt 到目前为止我尝试过 rm myfile txt rm illegal option m usage rm f i dPRrvW f
  • 使用 this-> 访问成员是否有任何开销?

    当访问某个类的成员时 我可以使用例如 this gt myVar 10 或者我可以写 myVar 10 我喜欢用this gt 因为它显式声明该变量是此类的成员 但是与仅使用变量名本身相比 它是否会导致任何开销 作为替代方案 我可以向变量添
  • 从 data.frame 或 data.table 构建方形邻接矩阵

    我正在尝试建立一个方形邻接matrix from a data table 这是我已经拥有的可重现的示例 require data table require plyr require reshape2 Build a mock data
  • Locale.ITALY 和 Locale.ITALIAN 有什么不同

    和有什么区别Locale国家和语言 例如Locale ITALY and Locale ITALIAN 我在哪里可以找到其他语言环境的所有这些差异 我应该什么时候使用每一个 是否可以开发我们所需的语言环境 如何 Locale ITALIAN
  • Laravel 4 Illuminate \ Database \ Eloquent \ MassAssignmentException 错误

    嘿 我已经在那里搜索了很多答案 但无法解决这个问题 这是我的迁移代码
  • 在 ASP.NET c# 中查找日期 10 月的最后一个星期日

    嗨 有没有办法找出 ASP NET C 中十月最后一个星期日的日期 我正在使用 net 2 0 不需要为此运行循环 private static DateTime GetLastWeekdayOfMonth DateTime date Da
  • 在 .NET 中创建和部署 ActiveX 控件

    由于显然没有可以接受位图粘贴的 Flash 控件 我想考虑自己写一个 但我不想使用 Flash 所以我考虑使用 NET 现在我相信可以在浏览器中下载并运行的本机代码控件的正确术语是 ActiveX 控件 所以我的问题是 我可以用 NET 创
  • FBSDK 空登录视图

    自从升级到最新的 Xcode 后 我在尝试通过 FBSDK 登录时遇到了一些问题FBSDKLoginManager Safari 中的登录窗口会弹出 但它保持白色 空视图 没有导航项或内容 控制台返回以下内容 ViewService 无法获
  • 将分组 zscore 列添加到 pandas 数据框中

    我可以将一列插入到数据框中 对另一列进行 z 评分 如下所示 1 df insert
  • Rails:从控制器调用另一个控制器操作

    我需要从控制器 B 调用控制器 A 中的创建操作 原因是当我从控制器 B 调用时 我需要以不同的方式重定向 可以在 Rails 中完成吗 要使用另一个控制器 请执行以下操作 def action that calls one from an
  • 点击按钮时忽略 UIGestureRecognizer

    我设置了一个手势识别器 以便在点击屏幕时我的工具栏会向下滑动 当我点击栏上的按钮时 即算作一次点击 在这些情况下如何取消手势 Thanks 您可以查看 Simple GestureRecognizers 示例项目 http develope
  • 两个字符串之间的所有公共子字符串

    我正在使用 C 来查找两个字符串之间的所有公共子字符串 例如 如果输入是 S1 需要电子邮件方面的帮助 S2 需要电子邮件帮助 输出应该是 需要帮助电子邮件 下面的代码返回最长的公共子字符串 但我希望我的代码返回所有公共子字符串 任何帮助深