这个问题仅仅是算法。 在伪代码中是这样的:
A = Array of strings; //let's say count(A) = N
S = String to find; //let's say length(S) = M
for (Index=0; Index<count(A); Index++)
if (A[Index]==S) {
print "First occurrence at index\x20"+Index;
break;
}
此for循环需要N次字符串比较(或字节比较N * M次,O(N * M))。当数组A包含大量项目或字符串S太长时,这很糟糕。
找出第一次出现的更好方法? O(K * logK)处的某些算法是正常的,但最好是O(K)或最好是O(logK),其中K是N或M.
我不介意在比较循环之前添加一些其他结构或进行一些数据处理。
答案 0 :(得分:4)
将字符串放入基于散列的集合中,并测试以查看集合中是否包含给定字符串应该在构建集合后提供或多或少的常量性能。
答案 1 :(得分:4)
您可以将整个字符串数组转换为有限状态机,其中转换是字符串的字符,并将生成状态的字符串的最小索引放入状态。这需要花费很多时间,可能会被视为索引。
答案 2 :(得分:3)
您可以先对字符串数组进行排序,这将花费O(m * nlogn)时间。在对A进行排序后,您可以进行二分搜索而不是线性搜索,这可以将总运行时间减少到O(m * logn)。
这种方法的优点是它很容易实现。例如,在Java中,只需2行代码即可完成此操作:
Arrays.sort(A);
int index = Arrays.binarySearch(A, "S");
答案 3 :(得分:3)
您可以使用Self-balancing binary search tree。大多数实现都要插入O(log(n)),要搜索O(log(n))。
如果您的集合不是很大,并且您的值具有良好的散列函数,则基于散列的集合是更好的解决方案,因为在这种情况下,您将有O(1)插入和O(1)到搜索。但是如果您的哈希函数不好或者您的集合太大,则插入O(n)和搜索O(n)。
答案 4 :(得分:1)
尽可能快地搜索的最佳方法是对数组进行排序 正如您所描述的那样,似乎没有先验可能的信息可以允许搜索中的一些启发式或约束
首先对数组进行排序(例如Quicksort,O(NlogN)), 然后二进制搜索O(log(N))