- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我用 C# 实现最长公共(public)子序列问题。我需要检测两个字符串之间的所有常见的最大子序列。
为此,我使用 Needleman-Wunsch algorithm 创建了一个表为计算的每一步存储 LCS 序列。
是否有机会确定找到了多少最大子序列(使用表格)?
据此我想选择一种方法来收集每个子序列。重点是,一个子序列不需要递归,因此它会提供更好的性能。这对我的任务至关重要。
这是一个代码片段,其中实现了项目的基本功能:
private static int[][] GetMatrixLCS(string x, string y)
{
var lenX = x.Length;
var lenY = y.Length;
matrixLCS = new int[lenX + 1][];
for (var i = 0; i < matrixLCS.Length; i++)
{
matrixLCS[i] = new int[lenY + 1];
}
for (int i = 0; i <= lenX; i++)
{
for (int j = 0; j <= lenY; j++)
{
if (i == 0 || j == 0)
matrixLCS[i][j] = 0;
else
if (x[i - 1] == y[j - 1])
matrixLCS[i][j] = matrixLCS[i - 1][j - 1] + 1;
else
matrixLCS[i][j] = Math.Max(matrixLCS[i - 1][j], matrixLCS[i][j - 1]);
}
}
return matrixLCS;
}
static HashSet<string> FindAllLcs(string X, string Y, int lenX, int lenY)
{
var set = new HashSet<string>();
if (lenX == 0 || lenY == 0)
return emptySet;
if (X[lenX - 1] == Y[lenY - 1])
{
var tempResult = FindAllLcs(X, Y, lenX - 1, lenY - 1);
foreach (var temp in tempResult)
set.Add(temp + X[lenX - 1]);
return set;
}
if (matrixLCS[lenX - 1][lenY] >= matrixLCS[lenX][lenY - 1])
set = FindAllLcs(X, Y, lenX - 1, lenY);
if (matrixLCS[lenX][lenY - 1] >= matrixLCS[lenX - 1][lenY])
set.UnionWith(FindAllLcs(X, Y, lenX, lenY - 1));
return set;
}
以及具有两种类型的输入和预期输出的示例:
public void SingleOutput()
{
var sequence = LCS.FindLCS("ABC", "AB");
Assert.AreEqual(1, sequence.Length);
Assert.AreEqual("AB", sequence[0]);
}
public void MultipleOutput()
{
var sequence = LCS.FindLCS("BCAB", "ABC");
Assert.AreEqual(2, sequence.Length);
Assert.AreEqual("AB", sequence [0]);
Assert.AreEqual("BC", sequence [1]);
}
如有任何帮助,我们将不胜感激。
最佳答案
我认为可以稍微不同地考虑动态规划。也许它可以工作:
#include <bits/stdc++.h>
using namespace std;
struct TLSTValue {
int len;
int cnt;
};
void update(TLSTValue& v, const TLSTValue& u) {
if (u.cnt == 0) {
return;
}
if (u.len > v.len) {
v.len = u.len;
v.cnt = u.cnt;
} else if (u.len == v.len) {
v.cnt += u.cnt;
}
}
int main(int /* argc */, char** /* argv */)
{
string a, b;
while (cin >> a >> b) {
int n = a.size();
int m = b.size();
vector<vector<int>> nxt(n, vector<int>(m));
for (int j = 0; j < m; ++j) {
int lst = n;
for (int i = n - 1; i >= 0; --i) {
if (a[i] == b[j]) {
lst = i;
}
nxt[i][j] = lst;
}
}
vector<vector<TLSTValue>> f(n + 1, vector<TLSTValue>(m + 1, {0, 0}));
f[0][0]= {0, 1};
TLSTValue ans = {0, 0};
for (int i = 0; i <= n; ++i) {
unordered_set<char> st;
for (int j = 0; j <= m; ++j) {
update(ans, f[i][j]);
if (j) {
update(f[i][j], f[i][j - 1]);
}
if (st.count(b[j])) {
continue;
}
st.insert(b[j]);
if (i < n && j < m && f[i][j].cnt && nxt[i][j] < n) {
update(f[nxt[i][j] + 1][j + 1], {f[i][j].len + 1, f[i][j].cnt});
}
}
}
cout << a << " and " << b << ": length = " << ans.len << ", count = " << ans.cnt << endl;
}
cerr << "Time execute: " << clock() / (double)CLOCKS_PER_SEC << " sec" << endl;
return 0;
}
nxt[i][j]
是第一个开始的位置 i
在字符串中的位置 a
位置为 j
的字符在字符串中 b
. f[i][j]
是长度和计数 LCS,以字符 i - 1
结尾在字符串中 a
在位置 j
之前在字符串中 b
.
您可以试试代码 here .
一些测试的输出:
ABC and AB: length = 2, count = 1
BCAB and ABC: length = 2, count = 2
A and AAA: length = 1, count = 1
AAA and A: length = 1, count = 1
AAAB and ABBB: length = 2, count = 1
ABBB and AAAB: length = 2, count = 1
关于c# - LCS 算法 : How to find out from a Table, 找到多少个最长公共(public)子序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56518854/
我想问一下“ionic run android -lcs”中的标志“lcs”是什么意思?(我的 ionic 框架有一个错误,即我的应用程序仅在使用此标志时以正确的方式构建,但我不知道它们代表什么。)
我已经编写了解决最长公共(public)子序列问题的代码。只需要定义 m X w 维度的二维表。我已将其定义为全局变量,但它引发了超出容量的错误。 #define FOR(i,n) for( i =
我正在尝试执行一个 LCS 函数,该函数利用递归为我提供 LCS 有效的位置数,以及此处描述的 LCS 位置: input: LCS("smile", "tile") output: [3, "##i
我正在开发一个程序来查找多个字符串之间的最长公共(public)子字符串。我已经将我的方法降低到使用后缀数组或后缀树。我想看看哪种方法更好(如果有的话)以及原因。同样对于后缀数组,我已经看到了一些用于
我在考虑使用动态规划的最长公共(public)子序列问题。 无法找出打印所有 lcs 的方法。 我能想到的一种方法是从表格中创建一个图表并在该图表中找到所有可能的路径,但该解决方案似乎非常慢。 最佳答
本文实例讲述了java算法之最长公共子序列问题(lcs)。分享给大家供大家参考,具体如下: 问题描述:一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列x= { x1,
我想打印 LCS 问题的所有可能的解决方案。 两个字符串 abcbdab 和 bdcaba 应打印以下 3 个字符串:bdab、bcba、bcab。 C为全局矩阵表,根据算法取值,m、n为序列a、b的
我即将完成我的程序,但我遇到了一个小问题。 I/O 应该看起来像这样: I: fanlc2("human", "chimpanzee") O: [4, 'h#man', '#h#m#an###'] 但
我正在尝试进行动态规划以查找 LCS 的长度。我为此使用了二维数组。但是对于大字符串,它会由于内存溢出而产生运行时错误。请告诉我我应该如何在一维数组中执行此操作以避免内存限制。 #include #
我正在使用动态规划解决 LCS 问题。我在不查看解决方案的情况下自己推导出 DP 解决方案时遇到了问题。 我目前的推理是给定两个字符串,P 和 Q: 我们可以枚举 P 的所有子序列,其大小为 2^n。
两棵 Root过的、有序的、有标签的树的 LCS 是最大的森林的大小 通过删除节点从两棵树中获得。删除节点 v 意味着删除 v 和所有边 v 的事件。v 的 child 成为 v 的父级(如果存在)而
有一个动态规划算法可以找到两个序列的最长公共(public)子序列。如何找到两个序列X和Y的LCS算法。(正确性测试) (a) X = ABEDFEESTYH Y=ABEDFEESTYHABC
我在 C# 中编写了以下代码,用于获取 use 给定的两个文本的最长公共(public)子序列的长度,但它不适用于大字符串。请你帮助我好吗。我真的很困惑。 public Form1() { I
请帮助我尝试找到我实现最大公共(public)子串问题的运行时间 int main(){ string a; string b; cin>>a>>b; string::
这是一个经典的编程问题https://en.wikipedia.org/wiki/Longest_common_subsequence_problem JS 实现通过了所有测试,但 Haskell 实
我们可以通过这种方式将下面文档中的两个字符串的 LCS 算法扩展到三个字符串吗? http://www.columbia.edu/~cs2035/courses/csor4231.F13/lcs.pd
我正在使用 diff-lcs gem 来输出两个 html 内容主体之间的差异。这是示例内容。 版本一: Paragraph one. Sentence one. Paragraph two. Ano
我读过几本算法书籍,其中被告知最长公共(public)子序列的蛮力方法需要 2^n,这在时间复杂度上是指数级的。然而,我注意到,当我应用我的蛮力技术时,它需要 O(mn)(根据我个人的观察)。我想请您
假设我们有两个字符流: S = 1,2,3,5,7,4,4,10,11,12 T = 3,1,2,9,6,4,10,5,9 我想找到这个流的最大子序列,以便通过某种重新排列使它们相同,例如在这种情况下
我知道 LCS 问题需要时间 ~ O(mn) 其中 m 和 n 分别是两个序列 X 和 Y 的长度。但我的问题有点简单,所以我希望算法比 ~O(mn) 更快。 这是我的问题: 输入: 一个正整数Q,两
我是一名优秀的程序员,十分优秀!