有没有人知道通过查找某个组合来浏览一系列数字的有效算法,例如:
有这个给定的序列,我想找到21~73的特定组合的索引,例如
... 1243 21 94 73 6286 21 88 73 4738 ......
所以我有一个模式21 ?? 94,需要找出索引的位置:
21 94的 73
21 88的 73
我认为有办法不触及每一个数字。
编辑: “Lasse V. Karlsen”提出了一个我忘记的重要观点。 没有重叠允许,例如
21 21的 73 73的 21 55的 73
21 21 73 没问题,接下来就是 21 55 73
答案 0 :(得分:2)
好像您正在寻找regular expression 21..73
- .
代表"任何字符" 1
接下来你需要迭代这个正则表达式的所有匹配。
大多数高级语言已经内置了一个简单易用的正则表达式库。
请注意,许多正则表达式库已经处理了#34;没有重叠"为你,包括java:
String s = "21217373215573";
Matcher m = Pattern.compile("21..73").matcher(s);
while (m.find()) System.out.println(m.group());
将产生所需的输出:
212173
215573
(1)这假设您的序列首先是数字,正如您的问题所暗示的那样。
答案 1 :(得分:1)
根据您使用的语言,您可以使用排序21\d{2}73
的正则表达式,它将查找21
,后跟两位数字,然后是73
。 C#等语言允许您获取匹配的索引,如here所示。
或者,您可以构建自己的Final State Machine,这可能是那种类型:
string input = ...
int index = 0
while(index < input.length - 5)
if(input[index] == 2) && (input[index + 1] == 1) && (input[index + 4] == 7) && (input[index + 5] == 3)
print(index);
index += 6;
else index++
答案 2 :(得分:0)
由于你不知道这些组合的起点在哪里,你不是只看第一个,所以没有办法不触及每个数字(也许只是最后的n-1个数字,其中n是组合的长度,因为如果有的话数字较少,空间不足。
我只是不知道更好的方法然后只读完整个序列,因为你可以有
... 8445 21217373 38494684 ...
然后你有两个组合重叠。如果您不是在寻找重叠的组合,那么它只是更简单的版本,但在您的示例中它是可能的。
一些非重叠算法伪代码:
start := -1; i := 0
for each digit in sequence
if sequence[digit] = combination[i]
if start = -1
start := digit
endif
i++
if i >= length(combination)
possibleCombinations.add(start)
start := -1
i := 0
endif
else
start := -1
endif
end
这应该是O(n)。与在未排序数组中查找一个值相同的复杂性。如果你正在寻找像我的例子中那样的重叠组合,那么复杂性要高一些,你必须检查每个可能的开始,它在检查每个找到的起始值时添加一个循环。检查组合是否继续的东西,然后保留起始值或在组合被破坏时丢弃它。那么复杂性就像O(n * length(组合)),因为没有更多的开始,那么组合的长度是什么。