Skip to content

Commit dfd1574

Browse files
committed
Improve wildcard matching
1 parent ed7c725 commit dfd1574

File tree

2 files changed

+38
-23
lines changed

2 files changed

+38
-23
lines changed

cp-algo/util/complex.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ namespace cp_algo {
2727
complex conj() const {return {x, -y};}
2828
T norm() const {return x * x + y * y;}
2929
T abs() const {return std::sqrt(norm());}
30-
T real() const {return x;}
31-
T imag() const {return y;}
30+
T const real() const {return x;}
31+
T const imag() const {return y;}
3232
T& real() {return x;}
3333
T& imag() {return y;}
3434
static constexpr complex polar(T r, T theta) {return {r * cos(theta), r * sin(theta)};}
@@ -41,8 +41,8 @@ namespace cp_algo {
4141
template<typename T> T abs(complex<T> x) {return x.abs();}
4242
template<typename T> T& real(complex<T> &x) {return x.real();}
4343
template<typename T> T& imag(complex<T> &x) {return x.imag();}
44-
template<typename T> T real(complex<T> const& x) {return x.real();}
45-
template<typename T> T imag(complex<T> const& x) {return x.imag();}
44+
template<typename T> T const real(complex<T> const& x) {return x.real();}
45+
template<typename T> T const imag(complex<T> const& x) {return x.imag();}
4646
template<typename T>
4747
constexpr complex<T> polar(T r, T theta) {
4848
return complex<T>::polar(r, theta);

verify/poly/wildcard.test.cpp

+34-19
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,53 @@ void semicorr(auto &a, auto &b) {
2222
}
2323

2424
auto is_integer(auto a) {
25-
static const ftype eps = 1e-8;
26-
return cp_algo::abs(imag(a)) < eps
27-
&& cp_algo::abs(real(a) - cp_algo::round(real(a))) < eps;
25+
static const ftype eps = 1e-9;
26+
return cp_algo::abs(a - cp_algo::round(a)) < eps;
2827
}
2928

3029
string matches(string const& A, string const& B, char wild = '*') {
31-
static point project[2][128];
30+
static ftype project[2][128];
3231
static bool init = false;
3332
if(!init) {
3433
init = true;
34+
std::random_device rd;
35+
std::mt19937 gen(rd());
36+
std::uniform_real_distribution<> dis(.5, 2.);
3537
for(int i = 0; i < 128; i++) {
36-
project[0][i] = cp_algo::polar<ftype>(1., (ftype)cp_algo::random::rng());
37-
project[1][i] = conj(project[0][i]);
38+
ftype x = dis(gen);
39+
project[0][i] = x;
40+
project[1][i] = 1. / x;
3841
}
3942
}
4043
project[0][(int)wild] = project[1][(int)wild] = 0;
4144
vector<cvector> P;
42-
P.emplace_back(size(A));
43-
P.emplace_back(size(A));
44-
for(auto [i, c]: A | views::enumerate) {
45-
P[0].set(i, project[0][(int)c]);
46-
}
47-
for(auto [i, c]: B | views::reverse | views::enumerate) {
48-
P[1].set(i, project[1][(int)c]);
49-
}
45+
P.emplace_back((size(A) + 1) / 2);
46+
P.emplace_back((size(A) + 1) / 2);
47+
int N = P[0].size();
48+
auto assign = [&](int z) {
49+
return [&, z](auto ic) {
50+
auto [i, c] = ic;
51+
if(i < N) {
52+
real(P[z].r[i / fft::flen])[i % fft::flen] = project[z][(int)c];
53+
} else {
54+
i -= N;
55+
imag(P[z].r[i / fft::flen])[i % fft::flen] = project[z][(int)c];
56+
}
57+
};
58+
};
59+
ranges::for_each(A | views::enumerate, assign(0));
60+
ranges::for_each(B | views::reverse | views::enumerate, assign(1));
5061
cp_algo::checkpoint("cvector fill");
5162
semicorr(P[0], P[1]);
52-
string ans(size(P[0]), '0');
53-
auto start = (size(B) - 1) / fft::flen * fft::flen;
54-
for(size_t j = start; j < size(ans); j += fft::flen) {
55-
auto r = P[0].at(j);
56-
auto check = is_integer(r);
63+
string ans(2 * size(P[0]), '0');
64+
int start = (ssize(B) - 1) / fft::flen * fft::flen;
65+
for(int j = start; j < ssize(ans); j += fft::flen) {
66+
decltype(is_integer(real(P[0].at(j)))) check;
67+
if(j < N) {
68+
check = is_integer(real(P[0].at(j)));
69+
} else {
70+
check = is_integer(imag(P[0].at(j - N)));
71+
}
5772
for(int z = 0; z < 4; z++) {
5873
ans[j + z] ^= (bool)check[z];
5974
}

0 commit comments

Comments
 (0)