【发布时间】:2014-01-07 18:42:32
【问题描述】:
我想在一个主题(另一个字符串)中搜索一个查询(一个字符串)。
查询可能全部或部分出现,但不会重新排列。例如,如果查询是'da',主题是'dura',它仍然是一个匹配项。
我不允许使用像strfind 或find 这样的字符串函数。
【问题讨论】:
我想在一个主题(另一个字符串)中搜索一个查询(一个字符串)。
查询可能全部或部分出现,但不会重新排列。例如,如果查询是'da',主题是'dura',它仍然是一个匹配项。
我不允许使用像strfind 或find 这样的字符串函数。
【问题讨论】:
约束使这实际上非常简单,只需一个循环。想象一下,您有两个索引最初指向两个字符串的第一个字符,现在比较它们 - 如果它们不匹配,请增加主题索引并重试。如果他们这样做,则增加两者。如果此时您已经到达查询的末尾,那么您已经找到了它。实际的实现应该足够简单,我不想为你做所有的工作;)
【讨论】:
如果这是家庭作业,我建议您先查看代码前面的说明,然后自己尝试,然后再查看实际代码。
下面的代码在subject 字符串(变量m;以及相关的ii、jj)中查找所有出现的query 字符串的字符。然后它会测试这些事件的所有可能顺序(变量test)。如果订单在增加位置 (cond2) 中包含所有需要的字符 (cond1),则它是“可接受的”。如果至少有一个可接受的订单,则结果(变量result)是肯定的。
subject = 'this is a test string';
query = 'ten';
m = bsxfun(@eq, subject.', query);
%'// m: test if each char of query equals each char of subject
[ii jj] = find(m);
jj = jj.'; %'// ii: which char of query is found within subject...
ii = ii.'; %'// jj: ... and at which position
test = nchoosek(1:numel(jj),numel(query)).'; %'// test all possible orders
cond1 = all(jj(test) == repmat((1:numel(query)).',1,size(test,2)));
%'// cond1: for each order, are all chars of query found in subject?
cond2 = all(diff(ii(test))>0);
%// cond2: for each order, are the found chars in increasing positions?
result = any(cond1 & cond2); %// final result: 1 or 0
可以通过对test 使用更好的方法来改进代码,即不测试nchoosek 给出的所有可能命令。
【讨论】:
Matlab 允许您查看内置函数的来源,因此您可以随时尝试阅读代码以了解 Matlab 开发人员是如何做到的(尽管它可能会非常复杂)。 (感谢 Luis 的更正)
在另一个字符串中查找一个字符串是一个基本的计算机科学问题。您可以在任意数量的资源中阅读它,例如 Wikipedia。
您对非重排部分匹配的要求让人想起将剪接变体映射到基因组序列的生物信息学问题。
您可以通过使用序列比对算法(例如 Smith-Waterman)来解决您的问题,该算法已修改为适用于所有英文字符,而不仅仅是 DNA 碱基。
这个问题真的来自生物信息学吗?如果是这样,你应该这样标记它。
【讨论】:
type strfind,它只会打印'strfind' is a built-in function,所以没有可用的源代码。