#include #include #include #include using namespace std; /* Mamber & Myers Suffix array */ typedef pair pp; struct less_{ vector &last; int step; less_(vector &last, int step):last(last), step(step){} bool operator () (int lhs, int rhs) const{ return(pp(last[lhs], last[lhs+step]) < pp(last[rhs], last[rhs+step])); } }; vector suffix_array(string &str) { int Norg = str.size(), N; for(N = 1; N <= Norg; N <<= 1); vector last(str.begin(), str.end()); last.resize(N, -1); vector ix, next(N); for(int k = 1; ; k *= 2){ /* cout << "Phase " << k << ":" << endl; for(int i = 0; i < N; ++i) cout << last[i] << " "; cout << endl;*/ ix.clear(); for(int i = 0; i < Norg; ++i) ix.push_back(i); for(int i = Norg; i < N; ++i) last[i] = -1; sort(ix.begin(), ix.end(), less_(last,k)); int alphas = -1; pp lastc = pp(-1, -1); for(int i = 0; i < Norg; ++i){ pp curc = pp(last[ix[i]], last[ix[i]+k]); if(lastc != curc) ++alphas; lastc = curc; next[ix[i]] = alphas; } if(alphas >= Norg-1){ vector ret; for(int i = 0; i < ix.size(); ++i) ret.push_back(str.c_str() + ix[i]); return ret; } next.swap(last); } } bool cmp(const char *l, const char *r) { return strcmp(l, r) < 0; } /* template T bound(bool islower, string& text, string key, T beg, T en) { if(beg == en) return beg; T middle = beg + (en - beg) / 2; // cout <<"Middle = " << *middle << endl; string t(text, *middle, key.size()); if((islower && t < key) || (!islower && t <= key)) return bound(islower, text, key, middle + 1, en); else return bound(islower, text, key, beg, middle); }*/ int main(void) { ifstream cin("english.test.in"); int ncases = 0; while(true){ string line; if(!getline(cin, line)) break; if(ncases) cout << endl; ++ncases; string thetext; while(getline(cin, line)){ if(line == "%%%%%") break; thetext += ' '; thetext += line; } vector sa = suffix_array(thetext); /* for(int i = 0; i < sa.size(); ++i){ cout << sa[i] << endl; } cout << endl;*/ // thetext+=string(500, '\x01'); cout << "Case " << ncases << ":" << endl; while(getline(cin, line)){ if(line == "%%%%%") break; string linenxt = line; ++linenxt[linenxt.size() - 1]; cout << lower_bound(sa.begin(), sa.end(), linenxt.c_str(), cmp) - lower_bound(sa.begin(), sa.end(), line.c_str(), cmp) << endl; // beg = bound(true, thetext, line, sa.begin(), sa.end()); // cout << "before bound2"<