早上好,
我很惭愧发布这个问题,因为我应该能够独自解决这个问题,但目前我想不出更好的解决方案......
假设我有一个L
个字符列表和一个字符串S
。我想知道S
中的每个角色是否属于L
,而目前唯一无法想到的解决方案是琐碎的
boolean Result = true
boolean Temp = false
for i from 1 to S.Length
Temp <- false
for j from 1 to A.Count
if (S[i] == A[j]) Temp <- true
Result = Result && Temp
return Result
请注意,我并不关心此算法的优化,这可以很容易地完成,而是用于更好的算法。有人可以帮我解决一下吗?另请注意,S.Length
的大部分时间都比A.Count
大得多。最后,我不想使用正则表达式。
非常感谢。
答案 0 :(得分:2)
这里迭代字符列表的成本为O(A.Count)。您可以将字符存储在hash table中,这样您就可以确定S [i]是否在恒定时间内属于A,前提是正确选择了散列函数。
因此,通过良好的散列函数,您可以将O(S.Length * A.Count)的全局成本降低到O(S.Length)。
如果你正在处理ASCII字符,那么你的哈希表可以简单地简化为128个元素的数组,其身份为“哈希函数”。如果您正在处理Unicode字符,但您的文本包含大多数ASCII字符,那么您可能会想到这一点的变体。
答案 1 :(得分:0)
您可以按字母顺序排序L
和S
,例如使用quicksort。
现在,您可以按字符L
和S
进行比较,因此您的时间将是O(n1 log n1) (for sort of L) + O(n2 log n2) (for sort of S) + Max(n1, n2) (for comparing the two sorted strings character by character)
n1 = L.Length
和n2 = S.Length
所以给定n = Max(n1, n2)
,您应该有时间O(n log n)
(我希望): - )
确切的实现取决于您希望如何处理多个相等的字母。如果L = "A"
和S = "AA"
,S
是否与L
匹配?
答案 2 :(得分:0)
你能算出S和L中的字符,然后只是比较计数吗?这避免了嵌套循环结构,因此我认为这是O(N + M)而不是O(MN)(其中M和N是字符串的长度)。
int[] Lcount = new int[256];
int[] Scount = new int[256];
for (int i=0;i<L.length;++i) {
Lcount[L.charAt(i)]++;
}
for (int i=0;i<S.length;++i) {
Scount[S.charAt(i)]++;
}
for (int i=0;i<256;i++) {
// S doesn't have the characters in L so can't be a subset
if (Scount[i] < Lcount[i]) {
return false;
}
}
return true;
上面的示例假定字符的ASCII表示,如果字符数大于ASCII(例如Unicode),则可以使用哈希表应用相同类型的想法。