leetcode 28 Implement strStr() 練習使用字尾陣列
阿新 • • 發佈:2018-11-11
- 這次主要是利用一道字串匹配的簡單題,自己實現一遍字尾陣列
實現
class Solution {
public:
vector<int> sa, rank, tmp;
void getSa(const string& s){
int n = s.length();
for (int i = 0; i < n; i++){
rank.push_back(s[i]);
sa.push_back(i);
tmp.push_back (0);
}
rank.push_back(-1);
tmp.push_back(0);
sa.push_back(n);
for (int k = 1; k <= n; k *= 2){
auto cmp = [&](int x, int y){
if (rank[x] != rank[y])
return rank[x] < rank[y];
int t1 = x + k <= n ? rank[x + k] : -1;
int t2 = y + k <= n ? rank[y + k] : -1;
return t1 < t2;
};
sort(sa.begin(), sa.end(), cmp);
tmp[sa[0]] = 0;
for (int i = 1; i <= n; i++){
if (cmp(sa[i-1], sa[i])){
tmp[ sa[i]] = tmp[sa[i-1]] + 1;
}
else {
tmp[sa[i]] = tmp[sa[i-1]];
}
}
for (int i = 0; i <= n; i++)
rank[i] = tmp[i];
}
}
int strStr(string haystack, string needle) {
getSa(haystack);
int l = 0, r = haystack.length();
int low = -1, high = -1;
while (l <= r){
int mid = (l + r) >> 1;
int f = haystack.compare(sa[mid], needle.length(), needle);
if (f < 0){
l = mid + 1;
}
else if (f == 0){
r = mid - 1;
low = mid;
}
else {
r = mid - 1;
}
}
l = 0, r = haystack.length();
while (l <= r){
int mid = (l + r) >> 1;
int f = haystack.compare(sa[mid], needle.length(), needle);
if (f < 0){
l = mid + 1;
}
else if (f == 0){
l = mid + 1;
high = mid;
}
else {
r = mid - 1;
}
}
int ans = INT_MAX;
for (int i = max(low, 0); i <= high; i++){
ans = min(sa[i], ans);
}
if (ans != INT_MAX && haystack.compare(ans, needle.length(), needle) == 0)
return ans;
else
return -1;
}
};