开始计概A下半学期。
This commit is contained in:
1 parent
0cfdc8499c
commit
38e97654e1
31 files changed
+2144
-110
No files matched your search
+1
-4
@@ -38,10 +38,7 @@ int main() {
|
||||
std::string target, pattern;
|
||||
std::cin >> target >> pattern;
|
||||
for (const auto i : find_substring_pos(target, pattern)) {
|
||||
std::cout << i + 1 << std::endl;
|
||||
}
|
||||
for (const auto val : prefix_function(pattern)) {
|
||||
std::cout << val << " ";
|
||||
std::cout << i << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
std::vector<int> get_next_vector(const std::string& s) {
|
||||
std::vector<int> next(s.size() + 1);
|
||||
next[0] = -1;
|
||||
for (int i = 0; i < next.size() - 1; i++) { // 实际上写入下一位
|
||||
int j = next[i];
|
||||
while (j != -1 && s[i] != s[j]) { // j = -1: 完全不匹配,s[i]==s[j]: 直接能用
|
||||
j = next[j];
|
||||
}
|
||||
if (j == -1 || s[i] == s[j]) { j++; }
|
||||
next[i + 1] = j;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
std::vector<int> get_optimized_next_vector(const std::string& s, const std::vector<int>& next) {
|
||||
std::vector<int> next_optimized(next.size());
|
||||
next_optimized[0] = -1;
|
||||
next_optimized[next.size() - 1] = next[next.size() - 1];
|
||||
for (int i = 1; i < next.size() - 1; i++) {
|
||||
if (s[next[i]] == s[i]) {
|
||||
next_optimized[i] = next_optimized[next[i]];
|
||||
} else {
|
||||
next_optimized[i] = next[i];
|
||||
}
|
||||
}
|
||||
return next_optimized;
|
||||
}
|
||||
|
||||
std::vector<int> find_substring_pos(const std::string& target, const std::string& pattern) {
|
||||
std::vector<int> matched_pos;
|
||||
const std::vector<int> next_vector = get_optimized_next_vector(pattern, get_next_vector(pattern));
|
||||
int j = 0;
|
||||
for (int i = 0; i < target.size(); i++) {
|
||||
while (j > -1 && target[i] != pattern[j]) {
|
||||
j = next_vector[j];
|
||||
}
|
||||
if (j == -1) {
|
||||
j = 0; // 完全失配,直接 i++ j++
|
||||
continue;
|
||||
}
|
||||
if (target[i] == pattern[j]) { j++; }
|
||||
if (j == pattern.size()) {
|
||||
matched_pos.push_back(i - static_cast<int>(pattern.size()) + 1);
|
||||
j = next_vector[j];
|
||||
}
|
||||
}
|
||||
return matched_pos;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, std::vector<int> vec) {
|
||||
for (const auto& elem : vec) {
|
||||
os << elem << " ";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::ios::sync_with_stdio(false);
|
||||
std::cin.tie(nullptr);
|
||||
|
||||
std::string target, pattern;
|
||||
std::cin >> target >> pattern;
|
||||
std::clog << get_next_vector(pattern) << std::endl;
|
||||
std::clog << get_optimized_next_vector(pattern, get_next_vector(pattern)) << std::endl;
|
||||
for (const auto i : find_substring_pos(target, pattern)) {
|
||||
std::cout << i << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user