teamnote history merge
This commit is contained in:
49
2025fall/source/String/AhoCorasick.cpp
Normal file
49
2025fall/source/String/AhoCorasick.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
struct Node {
|
||||
int next[26]; int par, int fail; bool isfin = false;
|
||||
Node(){fail = 0; fors(i, 0, 25) next[i] = -1;}
|
||||
};
|
||||
Node trie[N]; int c;
|
||||
void insert(char s[], int i, int node) {
|
||||
if(s[i] == '\0') {
|
||||
trie[node].isfin = true; return;
|
||||
}
|
||||
if(trie[node].next[s[i]-'a'] == -1) {
|
||||
trie[node].next[s[i]-'a'] = ++c;
|
||||
trie[c].par = node;
|
||||
}
|
||||
insert(s, i+1, trie[node].next[s[i]-'a']);
|
||||
}
|
||||
void bfs() {
|
||||
queue<pii> q; q.push({0, -1});
|
||||
while(!q.empty()) {
|
||||
auto [node, x] = q.front(); q.pop();
|
||||
if(x != -1) {
|
||||
int pf = trie[trie[node].par].fail;
|
||||
while(pf != 0 and trie[pf].next[x] == -1) pf = trie[pf].fail;
|
||||
|
||||
if(trie[node].par != 0 and trie[pf].next[x] != -1)
|
||||
{
|
||||
trie[node].fail = trie[pf].next[x];
|
||||
trie[node].isfin |= trie[trie[pf].next[x]].isfin;
|
||||
}
|
||||
else trie[node].fail = 0;
|
||||
}
|
||||
fors(i, 0, 25) {
|
||||
if(trie[node].next[i] == -1) continue;
|
||||
q.push({trie[node].next[s[i]-'a'], i});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For char* s, insert(s+1, 0, 0);
|
||||
// trie[0].fail = 0; bfs();
|
||||
// find trie from s:
|
||||
int now = 0, ok = false;
|
||||
for(int i = 0; s[i]; i++) {
|
||||
while(now != 0 and trie[now].next[s[i]-'a'] == -1) now = trie[now].fail;
|
||||
|
||||
if(trie[now].next[s[i]-'a'] != -1) {
|
||||
now = trie[now].next[s[i]-'a'];
|
||||
if(trie[now].isfin) ok = true;
|
||||
}
|
||||
}
|
||||
38
2025fall/source/String/Eertree.cpp
Normal file
38
2025fall/source/String/Eertree.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
struct Eertree {
|
||||
int len[N], link[N], nxt[N][26], r[N];
|
||||
long long cnt[N]; int sz, last, n;
|
||||
char s[N];
|
||||
Eertree() {
|
||||
memset(nxt, 0, sizeof(nxt));
|
||||
memset(cnt, 0, sizeof(cnt));
|
||||
s[0] = -1;
|
||||
n = 0; sz = 2; last = 1;
|
||||
len[0] = -1; link[0] = 0;
|
||||
len[1] = 0; link[1] = 0;
|
||||
}
|
||||
int get_link(int v) {
|
||||
while (s[n-len[v]-1] != s[n]) v = link[v];
|
||||
return v;
|
||||
}
|
||||
void insert(char c) {
|
||||
s[++n] = c;
|
||||
int cur = get_link(last);
|
||||
if (!nxt[cur][c-'a']) {
|
||||
int now = sz++;
|
||||
r[now] = n;
|
||||
len[now] = len[cur] + 2;
|
||||
if (len[now] == 1) link[now] = 1;
|
||||
else link[now] = nxt[get_link(link[cur])][c-'a'];
|
||||
nxt[cur][c-'a'] = now;
|
||||
}
|
||||
last = nxt[cur][c-'a'];
|
||||
cnt[last]++;
|
||||
}
|
||||
void propagate() { fore(i, sz-1, 2) cnt[link[i]] += cnt[i]; }
|
||||
};
|
||||
|
||||
Eertree et; forr(i, n) et.insert(s[i]);
|
||||
int m = et.sz; et.propagate();
|
||||
fors(i, 2, m-1) ans = max(ans, et.cnt[i] * et.len[i]);
|
||||
// node i : s[(et.r[i]-et.len[i]+1)~(et.r[i])]
|
||||
// distinct count of pal : m-2; count of node i : et.cnt[i];
|
||||
92
2025fall/source/String/F_Z_M_SA_LCP.cpp
Normal file
92
2025fall/source/String/F_Z_M_SA_LCP.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
const int N = 1e5+7;
|
||||
char s[N];
|
||||
int F[N], Z[N], M[N];
|
||||
int sa[N]; int ord[N], tmp[N], cnt[N];
|
||||
int lcp[N];
|
||||
int main() {
|
||||
scanf("%s", s+1);
|
||||
int n = strlen(s+1);
|
||||
|
||||
// KMP - fail function {
|
||||
F[1] = 0; int j = 0;
|
||||
for(int i=2; i<=n;i++)
|
||||
{
|
||||
while(j > 0 and s[i] != s[j+1]) j = F[j];
|
||||
F[i] = j+=(s[i] == s[j+1]);
|
||||
}
|
||||
}
|
||||
|
||||
//Z - Z array {
|
||||
Z[1] = n; int j = 1, r = 0;
|
||||
for(int i=2; i<=n; i++)
|
||||
{
|
||||
Z[i] = i<j+r?min(Z[i-j+1], j+r-i):0;
|
||||
while(s[1+Z[i]] == s[i+Z[i]]) Z[i]++;
|
||||
if(j+r < i+Z[i]) j = i, r = Z[i];
|
||||
}
|
||||
}
|
||||
|
||||
//Manacher - M array {
|
||||
M[1] = 0; int j = 1, r = 0;
|
||||
for(int i=2; i<=n; i++)
|
||||
{
|
||||
M[i] = i<j+r?min(M[2*j-i], j+r-i):0;
|
||||
while(1 <= i-M[i]-1 && i+M[i]+1 <= n
|
||||
&& s[i-M[i]-1] == s[i+M[i]+1]) M[i]++;
|
||||
if(j+r < i+M[i]) j = i, r = M[i];
|
||||
}
|
||||
}
|
||||
|
||||
//Suffix Array - SA {
|
||||
int t = 1; ord[n+1] = 0; tmp[0] = 0; sa[0] = 0;
|
||||
|
||||
auto cmp = [&t, &n](int i,int j) {
|
||||
return ord[i] == ord[j]
|
||||
?ord[min(i+t, n+1)]<ord[min(j+t, n+1)]
|
||||
:ord[i]<ord[j];
|
||||
};
|
||||
|
||||
forr(i, n) ord[i] = s[i], sa[i] = i;
|
||||
sort(sa+1, sa+1+n, [](int i,int j){return ord[i]<ord[j];});
|
||||
|
||||
forr(i, n) tmp[sa[i]] = tmp[sa[i-1]] + (ord[sa[i-1]]<ord[sa[i]]);
|
||||
swap(tmp, ord);
|
||||
|
||||
while(t < n) {
|
||||
fors(i, 0, n) cnt[i] = 0;
|
||||
forr(i, n) cnt[ord[min(i+t, n+1)]]++;
|
||||
forr(i, n) cnt[i] += cnt[i-1];
|
||||
fore(i, n, 1) tmp[cnt[ord[min(i+t, n+1)]]--] = i;
|
||||
|
||||
fors(i, 0, n) cnt[i] = 0;
|
||||
forr(i, n) cnt[ord[i]]++;
|
||||
forr(i, n) cnt[i] += cnt[i-1];
|
||||
fore(i, n, 1) sa[cnt[ord[tmp[i]]]--] = tmp[i];
|
||||
|
||||
forr(i, n) tmp[sa[i]] = tmp[sa[i-1]] + cmp(sa[i-1], sa[i]);
|
||||
swap(ord, tmp);
|
||||
|
||||
t<<=1;
|
||||
if(ord[sa[n]] == n) break;
|
||||
}
|
||||
}
|
||||
|
||||
//LCP array {
|
||||
int k = 0;
|
||||
forr(i, n) if(ord[i] != 1) {
|
||||
int j = sa[ord[i]-1];
|
||||
while(s[i+k] == s[j+k]) k++;
|
||||
lcp[ord[i]] = k;
|
||||
|
||||
if(k > 0) k--;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nF : "); forr(i, n) printf("%d ", F[i]);
|
||||
printf("\nZ : "); forr(i, n) printf("%d ", Z[i]);
|
||||
printf("\nM : "); forr(i, n) printf("%d ", M[i]);
|
||||
printf("\nSA : "); forr(i, n) printf("%d ", sa[i]);
|
||||
printf("\nLCP : x "); fors(i, 2, n) printf("%d ", lcp[i]);
|
||||
|
||||
printf("\n"); forr(i, n) printf("%s\n", s+sa[i]);
|
||||
}
|
||||
17
2025fall/source/String/KMP.cpp
Normal file
17
2025fall/source/String/KMP.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
int fail[N]; // N : s의 최대 길이
|
||||
vi kmp(char obj[], char s[]) {
|
||||
vi ret;
|
||||
for(int i = 1, j = 0; s[i]; i++) {
|
||||
fail[i] = 0;
|
||||
while(j > 0 and s[i] != s[j]) j = fail[j-1];
|
||||
if(s[i] == s[j]) fail[i] = ++j;
|
||||
}
|
||||
for(int i = 0, j = 0; obj[i]; i++) {
|
||||
while(j > 0 and obj[i] != s[j]) j = fail[j-1];
|
||||
if(obj[i] == s[j]) {
|
||||
if(s[j+1]) j++;
|
||||
else ret.push_back(i-j), j = fail[j];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
132
2025fall/source/String/std::string.cpp
Normal file
132
2025fall/source/String/std::string.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
/////////////////////////////////////////////////////////
|
||||
string s; //변수 선언
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
string s = "Hwan"; //output : Hwan
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
string s1("Hwan"); //output ㄷ: Hwan
|
||||
string s2(4, 'A'); //output : AAAA
|
||||
string s3(s1, 0, s1.length() - 2); //output : HW
|
||||
string s4(s1, 2, s1.length()); //output : an
|
||||
string s5(s2); //output : AAAA
|
||||
string s6("ABCDE", 3); //output : ABC
|
||||
|
||||
char c[] = "TEST Code!!";
|
||||
string s7(c); //output : TEST Code!!
|
||||
/////////////////////////////////////////////////////////
|
||||
string s = "ABCDE123";
|
||||
|
||||
cout << s.at(2) << endl; //output : C (범위가 맞지 않으면 예외처리를 함)
|
||||
cout << s[0] << endl; //output : A
|
||||
cout << s.front() << endl; //output : A
|
||||
cout << s.back() << endl; //output : 3
|
||||
|
||||
const char * c = s.c_str(); //배열로써 접근이 가능하며 '\0'에 접근이 가능하다.
|
||||
|
||||
cout << c << endl; //output : ABCDE123
|
||||
|
||||
cout << (c_arr == s) ? true : false; //output : 1(true)
|
||||
cout << (&(c_arr[0]) == &(s[0])) ? true : false; //output : 1(true)
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
string s = "ABCDE123";
|
||||
string::iterator iter = s.begin();
|
||||
string r_s, cp;
|
||||
|
||||
for (; iter != s.end(); iter++) {
|
||||
cout << *iter;
|
||||
if (*iter == 'E')
|
||||
break;
|
||||
} //output : ABCDE
|
||||
|
||||
|
||||
copy(s.rbegin(), s.rend(), back_inserter(r_s));
|
||||
copy(s.begin(), s.end(), back_inserter(cp));
|
||||
|
||||
cout << r_s << endl; //output : 321EDCBA
|
||||
cout << (s == r_s) ? true : false; //output : 0(false)
|
||||
cout << (s == cp) ? true : false; //output : 1(true)
|
||||
cout << (&(s[0]) == &(cp[0])) ? true : false; //output : 0(false)
|
||||
/////////////////////////////////////////////////////////
|
||||
string s = "ABCDE123"
|
||||
|
||||
s.insert(0, "TEST"); //output : TESTABCDE123
|
||||
s.insert(s.begin() + s.find_first_of('D') + 1, ':'); // output : TESTABCD:123(문자만 가능)
|
||||
|
||||
|
||||
////////// (compare) s = TESTABCD:123 /////////////
|
||||
s.compare("TESTABCD:123"); //output : 0
|
||||
s.compare("a"); //output : -1
|
||||
s.compare("X"); //output : -1
|
||||
s.compare("BBBBBBBBBBBBBBB"); //output : 1
|
||||
s.compare("100000000000000000000000"); //output : 1
|
||||
s.compare("VVVVV"); //output : -1
|
||||
|
||||
|
||||
////////// (erase) s = TESTABCD:123 /////////////
|
||||
s.erase(0, 4); //output : ABCD:123
|
||||
s.erase(find(s.begin(), s.end(), 'D')); //output : ABC:123('D'만 지움)
|
||||
s.erase(s.find(':')); //output : ABC(':'부터 뒤 문자까지 모두 지움)
|
||||
|
||||
|
||||
////////// (push, pop) s = ABC /////////////
|
||||
s.push_back('S'); //output : ABCS
|
||||
s.pop_back(); //output : ABC
|
||||
|
||||
|
||||
////////// (append) s = ABC /////////////
|
||||
s.append("TEST"); //output : ABCTEST
|
||||
s.append(1, '1'); //output : ABCTEST1
|
||||
s.append("123456789", 3, 3); //output : ABCTEST1456
|
||||
|
||||
|
||||
////////// (clear) s = ABCTEST1456 /////////////
|
||||
const char c[] = "Hwan";
|
||||
s.append(c); //output : ABCTEST1456Hwan
|
||||
s += c; //output : ABCTEST1456HwanHwan(capacity() = 15 -> 31)
|
||||
s.clear(); //s.size() = 0, s.capacity() = 31
|
||||
|
||||
|
||||
////////// (replace) s = '' /////////////
|
||||
s.append("ABCD123"); //output : ABCD123
|
||||
s.replace(4, 2, "Hwan"); //output : ABCDHwan3
|
||||
s.replace(s.find('H'), s.size() - s.find('H'), "WOW"); //output : ABCDWOW
|
||||
|
||||
|
||||
////////// (substr) s = ABCDWOW /////////////
|
||||
string temp = s.substr(4); //output : WOW;
|
||||
temp = s.substr(3, 2); //output : DW;
|
||||
temp = s.substr(s.size() - 3, 50); //output : WOW;
|
||||
|
||||
|
||||
////////// (copy) s = ABCDWOW /////////////
|
||||
char arr[5]{};
|
||||
s.copy(arr, sizeof arr - 1); //output : ABCD (마지막 '\n' 포함)
|
||||
|
||||
|
||||
////////// (resize) s = ABCDWOW /////////////
|
||||
s.resize(100); //output : ABCDWOW, s.size() = 100, s.capacity() = 111
|
||||
s.resize(4); //output : ABCD, s.size() = 4, s.capacity() = 15
|
||||
|
||||
|
||||
////////// (swap) s = ABCD /////////////
|
||||
string sw = "AAA";
|
||||
s.swap(sw); //s = "AAA", sw = "ABCD"
|
||||
|
||||
|
||||
/////////// c++ 20 ///////////////////
|
||||
s = "hello Hwan";
|
||||
s.starts_with("hello"); //output : true;
|
||||
s.starts_with('h'); //output : true;
|
||||
s.starts_with("Hwan"); //output : false;
|
||||
s.starts_with('x'); //output : false;
|
||||
|
||||
s.ends_with("Hwan"); //output : true;
|
||||
s.ends_with('n'); //output : true;
|
||||
s.ends_with("hello"); //output : false;
|
||||
s.ends_with('q'); //output : false;
|
||||
Reference in New Issue
Block a user