想象一下,您有一个数字(或字母)列表,例如
1177783777297461145777267337774652113777236237118777
我想在此列表中找到最常见的数字组合:
对于1位长组合 - 它是此列表中最常用的数字
用于2位数长组合 - 可能是'11'
用于3位数长组合 - 可能是'777'等
这样的任务是否有一些特殊的算法?
UPDATE 好吧,我自己编写了以下(Java)。看起来执行时间与数据大小乘以模式大小成正比:
public static void main(String[] args)
{
int DATA_SIZE = 10000;
int[] data = new int[DATA_SIZE];
for (int i = 0; i < DATA_SIZE; i++)
{
data[i] = (int) (10 * Math.random()) % 10;
System.out.print(data[i]);
}
int[] pattern1 = new int[]{1, 2, 3};
int[] pattern2 = new int[]{7, 7, 7};
int[] pattern3 = new int[]{7, 7};
System.out.println();
System.out.println(match(data, pattern1));
System.out.println(match(data, pattern2));
System.out.println(match(data, pattern3));
}
static int match(int[] data, int[] pattern)
{
int matches = 0;
int i = 0;
while (i < data.length)
{
matches = isEqual(data, i, pattern) ? matches + 1 : matches;
i++;
}
return matches;
}
static boolean isEqual(int[] a, int startIndex, int[] a2)
{
if (a == a2)
{
return true;
}
if (a == null || a2 == null)
{
return false;
}
for (int i = 0; i < a2.length; i++)
{
if (a[startIndex + i] != a2[i])
{
return false;
}
}
return true;
}
答案 0 :(得分:1)
这可以在二次时间内完成,但我对更快的方法感到好奇。这个想法是迭代可能的长度值k = 1..N,并在每个迭代循环中通过字符串找到最常见的长度为k的序列。
内部循环可以使用哈希表有效地计算频率。
答案 1 :(得分:0)
只需通过已经找到的最频繁组合的变量数组和辅助哈希表,其中键是搜索模式,值是输入数据中出现的数量。当您找到下一个模式时,请在哈希表中增加该值,并在必要时增加当前最频繁组合的值。
答案 2 :(得分:0)
要在长度为n的字符串中查找长度至少为k的序列的最大重复次数,可以在线性时间内构建后缀树(http://en.wikipedia.org/wiki/Suffix_tree),然后找到最多的节点从根开始描述长度为k(或更长)的序列的儿童。
总的来说,这是输入字符串长度的线性时间。
对于小k,你最好用一个天真的算法:
from collections import Counter
def input(s, k):
c = Counter()
for i in xrange(len(s) - k):
c[s[i : i + k]] += 1
return c.most_common(1)[0][0]
for k in xrange(1, 4):
print input('1177783777297461145777267337774652113777236237118777', k)
答案 3 :(得分:-4)
REGEX - 高效率地解决您的问题
http://www.vogella.com/articles/JavaRegularExpressions/article.html
检查它会对你有所帮助。如果你仍然无法通过lemme知道,生病的帮助