Skip to content

Commit 94a2ac3

Browse files
authored
Merge pull request #1266 from maspypy/ahc
問題追加 aho corasick
2 parents c97796e + fc2fe8c commit 94a2ac3

15 files changed

Lines changed: 750 additions & 0 deletions

string/aho_corasick/checker.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// https://github.com/MikeMirzayanov/testlib/blob/master/checkers/wcmp.cpp
2+
3+
// The MIT License (MIT)
4+
5+
// Copyright (c) 2015 Mike Mirzayanov
6+
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files (the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions:
13+
14+
// The above copyright notice and this permission notice shall be included in all
15+
// copies or substantial portions of the Software.
16+
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
// SOFTWARE.
24+
25+
#include "testlib.h"
26+
27+
using namespace std;
28+
29+
int main(int argc, char * argv[])
30+
{
31+
setName("compare sequences of tokens");
32+
registerTestlibCmd(argc, argv);
33+
34+
int n = 0;
35+
string j, p;
36+
37+
while (!ans.seekEof() && !ouf.seekEof())
38+
{
39+
n++;
40+
41+
ans.readWordTo(j);
42+
ouf.readWordTo(p);
43+
44+
if (j != p)
45+
quitf(_wa, "%d%s words differ - expected: '%s', found: '%s'", n, englishEnding(n).c_str(), compress(j).c_str(), compress(p).c_str());
46+
}
47+
48+
if (ans.seekEof() && ouf.seekEof())
49+
{
50+
if (n == 1)
51+
quitf(_ok, "\"%s\"", compress(j).c_str());
52+
else
53+
quitf(_ok, "%d tokens", n);
54+
}
55+
else
56+
{
57+
if (ans.seekEof())
58+
quitf(_wa, "Participant output contains extra tokens");
59+
else
60+
quitf(_wa, "Unexpected EOF in the participants output");
61+
}
62+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include <iostream>
2+
#include <cstdio>
3+
#include <cstdlib>
4+
#include <vector>
5+
#include "random.h"
6+
#include "../params.h"
7+
8+
using namespace std;
9+
10+
void out(Random& gen, vector<string> dat) {
11+
gen.shuffle(dat.begin(), dat.end());
12+
int n = dat.size();
13+
printf("%d\n", n);
14+
for (auto& x: dat) printf("%s\n", x.c_str());
15+
}
16+
17+
int main(int, char* argv[]) {
18+
long long seed = atoll(argv[1]);
19+
auto gen = Random(seed);
20+
21+
// 個数
22+
int ks[] = {1, 2, 10, 100};
23+
24+
int K = ks[(seed % 4)];
25+
26+
vector<int> S;
27+
vector<int> cut = gen.choice(K - 1, 1, int(MAX_S_SUM - 1));
28+
cut.insert(cut.begin(), 0);
29+
cut.emplace_back(MAX_S_SUM);
30+
assert(int(cut.size()) == K + 1);
31+
for (int i = 0; i < K; ++i) S.emplace_back(cut[i + 1] - cut[i]);
32+
33+
char ch = gen.uniform<char>('a', 'z');
34+
vector<string> dat;
35+
for (int n: S) {
36+
string X(n, ch);
37+
int k = gen.uniform<int>(1, 3);
38+
X[k] = gen.uniform<char>('a', 'z');
39+
dat.emplace_back(X);
40+
}
41+
42+
out(gen, dat);
43+
return 0;
44+
}

string/aho_corasick/gen/bfs.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include <cstdio>
2+
#include <cstdlib>
3+
#include <vector>
4+
#include "random.h"
5+
#include "../params.h"
6+
7+
using namespace std;
8+
9+
void out(Random& gen, vector<string> dat) {
10+
gen.shuffle(dat.begin(), dat.end());
11+
int n = dat.size();
12+
printf("%d\n", n);
13+
for (auto& x: dat) printf("%s\n", x.c_str());
14+
}
15+
16+
int main(int, char* argv[]) {
17+
long long seed = atoll(argv[1]);
18+
auto gen = Random(seed);
19+
20+
int ks[] = {1, 2, 5, 26};
21+
int k = ks[seed % 4];
22+
23+
int now = 0;
24+
vector<string> dat;
25+
dat.emplace_back("");
26+
for (int i = 0;; ++i) {
27+
string S = dat[i];
28+
if (now + (S.size()) + 1 > MAX_S_SUM) break;
29+
for (int c = 0; c < k; ++c) {
30+
string nxt = char('a' + c) + S;
31+
if (now + (nxt.size()) <= MAX_S_SUM) {
32+
now += nxt.size();
33+
dat.emplace_back(nxt);
34+
}
35+
}
36+
}
37+
dat.erase(dat.begin());
38+
out(gen, dat);
39+
40+
return 0;
41+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
4
2+
b
3+
a
4+
c
5+
a
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
3
2+
b
3+
a
4+
ab
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
1
2+
abcabcaba
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
5
2+
aaa
3+
a
4+
aa
5+
aaaaa
6+
a
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <iostream>
2+
#include <cstdio>
3+
#include <cstdlib>
4+
#include <vector>
5+
#include <tuple>
6+
7+
#include "random.h"
8+
#include "../params.h"
9+
10+
using namespace std;
11+
12+
void out(Random& gen, vector<string> dat) {
13+
gen.shuffle(dat.begin(), dat.end());
14+
int n = dat.size();
15+
printf("%d\n", n);
16+
for (auto& x: dat) printf("%s\n", x.c_str());
17+
}
18+
19+
int main(int, char* argv[]) {
20+
long long seed = atoll(argv[1]);
21+
auto gen = Random(seed);
22+
23+
// 個数
24+
int ks[] = {1, 2, 10, 100};
25+
26+
int K = ks[(seed % 4)];
27+
28+
vector<int> S;
29+
vector<int> cut = gen.choice(K - 1, 1, int(MAX_S_SUM - 1));
30+
cut.insert(cut.begin(), 0);
31+
cut.emplace_back(MAX_S_SUM);
32+
assert(int(cut.size()) == K + 1);
33+
for (int i = 0; i < K; ++i) S.emplace_back(cut[i + 1] - cut[i]);
34+
35+
int a_size = 1 + ((seed / 4) % 2);
36+
int b_size = 1 + ((seed / 4) / 2);
37+
38+
string A(a_size, '?'), B(b_size, '?');
39+
for (int i = 0; i < a_size; ++i) { A[i] = gen.uniform<char>('a', 'z'); }
40+
for (int i = 0; i < b_size; ++i) { B[i] = gen.uniform<char>('a', 'z'); }
41+
42+
while (1) {
43+
tie(A, B) = make_pair(B, A + B);
44+
if (int(A.size()) > MAX_S_SUM) break;
45+
}
46+
47+
string X = A;
48+
49+
vector<string> dat;
50+
int L = 0;
51+
for (int n: S) {
52+
dat.emplace_back(X.substr(L, n));
53+
L += n;
54+
}
55+
56+
out(gen, dat);
57+
return 0;
58+
}

string/aho_corasick/gen/random.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <iostream>
2+
#include <cstdio>
3+
#include <cstdlib>
4+
#include <vector>
5+
#include "random.h"
6+
#include "../params.h"
7+
8+
using namespace std;
9+
10+
void out(Random& gen, vector<string> dat) {
11+
gen.shuffle(dat.begin(), dat.end());
12+
int n = dat.size();
13+
printf("%d\n", n);
14+
for (auto& x: dat) printf("%s\n", x.c_str());
15+
}
16+
17+
int main(int, char* argv[]) {
18+
long long seed = atoll(argv[1]);
19+
auto gen = Random(seed);
20+
21+
vector<int> S;
22+
23+
if (0 <= (seed % 8) && (seed % 8) < 4) {
24+
// 文字列長 [1,k]
25+
int ks[] = {1, 2, 10, 100};
26+
int K = ks[seed % 8];
27+
int now = 0;
28+
while (now < MAX_S_SUM) {
29+
int k = gen.uniform<int>(1, K);
30+
if (now + k > MAX_S_SUM) continue;
31+
S.emplace_back(k), now += k;
32+
}
33+
} else if (4 <= (seed % 8) && (seed % 8) < 8) {
34+
// 個数 [1,k]
35+
int ks[] = {1, 2, 10, 100};
36+
int K = ks[(seed % 8) - 4];
37+
vector<int> cut = gen.choice(K - 1, 1, int(MAX_S_SUM - 1));
38+
cut.insert(cut.begin(), 0);
39+
cut.emplace_back(MAX_S_SUM);
40+
assert(int(cut.size()) == K + 1);
41+
for (int i = 0; i < K; ++i) S.emplace_back(cut[i + 1] - cut[i]);
42+
} else {
43+
assert(0);
44+
}
45+
46+
int ks[] = {2, 5, 26};
47+
int sigma = ks[seed % 3];
48+
49+
vector<string> dat;
50+
for (int n: S) {
51+
string X(n, '?');
52+
for (int i = 0; i < n; ++i) { X[i] = char(gen.uniform<int>(0, sigma - 1) + 'a'); }
53+
dat.emplace_back(X);
54+
}
55+
56+
out(gen, dat);
57+
return 0;
58+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include <iostream>
2+
#include <cstdio>
3+
#include <cstdlib>
4+
#include <vector>
5+
#include "random.h"
6+
#include "../params.h"
7+
8+
using namespace std;
9+
10+
void out(Random& gen, vector<string> dat) {
11+
gen.shuffle(dat.begin(), dat.end());
12+
int n = dat.size();
13+
printf("%d\n", n);
14+
for (auto& x: dat) printf("%s\n", x.c_str());
15+
}
16+
17+
int main(int, char* argv[]) {
18+
long long seed = atoll(argv[1]);
19+
auto gen = Random(seed);
20+
21+
// 個数
22+
int ks[] = {1, 2, 10, 100};
23+
// 周期
24+
int ps[] = {2, 3, 10, 100};
25+
26+
int K = ks[(seed % 4)];
27+
int P = ps[(seed / 4) % 4];
28+
29+
vector<int> S;
30+
vector<int> cut = gen.choice(K - 1, 1, int(MAX_S_SUM - 1));
31+
cut.insert(cut.begin(), 0);
32+
cut.emplace_back(MAX_S_SUM);
33+
assert(int(cut.size()) == K + 1);
34+
for (int i = 0; i < K; ++i) S.emplace_back(cut[i + 1] - cut[i]);
35+
36+
string base;
37+
for (int i = 0; i < P; ++i) base += char('a' + gen.uniform<int>(0, 25));
38+
string X;
39+
while (int(X.size()) < MAX_S_SUM) X += base;
40+
41+
vector<string> dat;
42+
int L = 0;
43+
for (int n: S) {
44+
dat.emplace_back(X.substr(L, n));
45+
L += n;
46+
}
47+
48+
out(gen, dat);
49+
return 0;
50+
}

0 commit comments

Comments
 (0)