-
Notifications
You must be signed in to change notification settings - Fork 0
/
Q1b_2018201103.cpp
147 lines (129 loc) · 4.31 KB
/
Q1b_2018201103.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
Priyendu Mori
2018201103
Q1_a suffix array - minimum lexicographic rotation
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
/*
comparator to sort vector of pair<index, pair<rank,new rank>>
according to rank and then according to next rank
*/
bool comp(pair<int,pair<int,int>> a, pair<int,pair<int,int>> b){
if(a.second.first == b.second.first){
if(a.second.second < b.second.second) return true;
else return false;
}
else{
if(a.second.first < b.second.first) return true;
else return false;
}
}
/*
function to build suffix array and return it
*/
vector<ll> buildSuffix(string str){
//vector of {index,{rank,new rank}}
vector<pair<int,pair<int,int>>> suffix(str.size());
//index vector helps in finding the sorted index of next part of the string
//e.g abbc: there's bc after ab, so we need sorted index of ab which is found from index vector
vector<ll> index(str.size());
//considering one char of string
//assign it's ascii value as it's current rank
//assign next char's ascii value as it's next rank
//if next char is not present, next rank should be -1
for(ll i=0;i<str.size();i++){
ll rank0=str[i]-'0';
ll rank1;
if((i+1)<str.size()) rank1=str[i+1]-'0';
else rank1=-1;
suffix[i]={i,{rank0,rank1}};
}
//sort the array according to comparator defined previously
sort(suffix.begin(), suffix.end(), comp);
//doing the same thing for next 2 chars than next 4 chars and so on
for(ll p=4;p<2*str.size();p*=2){
//assigning index and rank tothe first suffix
ll rank=0;
ll previous_rank=suffix[0].second.first;
suffix[0].second.first=rank;
index[suffix[0].first]=0;
//iterating to assign ranks and new ranks to all the other suffixes
for(ll i=1;i<str.size();i++){
//if the previous {rank,new rank} pair is same as this {rank,new rank} pair
//assign the same rank as previous
//else increment the rank and assign that rank to this suffix
if(suffix[i].second.first==previous_rank && suffix[i].second.second==suffix[i-1].second.second){
previous_rank=suffix[i].second.first;
suffix[i].second.first=rank;
}
else{
rank++;
previous_rank=suffix[i].second.first;
suffix[i].second.first=rank;
}
index[suffix[i].first]=i;
}
//assign new rank to every suffix
for(ll i=0;i<str.size();i++){
//find the index where next suffix is residing
//if next is within range assign rank of that suffix to this suffixes new rank
//else assign -1 as new rank
ll next=suffix[i].first + p/2;
ll new_rank;
if(next<str.size()){
new_rank=suffix[index[next]].second.first;
}
else{
new_rank=-1;
}
suffix[i].second.second=new_rank;
}
//sort suffixes according to comparator
sort(suffix.begin(), suffix.end(), comp);
}
//construct the suffix array by copying index from vector of {index,{rank,new rank}}
vector<ll> suffix_vector(str.size());
for(ll i=0;i<str.size();i++){
suffix_vector[i]=suffix[i].first;
}
return suffix_vector;
}
/*
returns longest matching prefix size of string a and b
*/
ll findPrefixSize(string a, string b){
ll size=min(a.size(), b.size());
ll count=0;
for(ll i=0;i<size;i++){
if(a[i]==b[i]){
count++;
}
else return count;
}
return count;
}
int main(){
ios_base::sync_with_stdio(false);
string str;
cout<<"Enter String "<<endl;
cin>>str;
ll k;
cin>>k;
vector<ll> ans=buildSuffix(str);
// for(auto i:ans){
// cout<<i<<" ";
// }
// cout<<endl;
ll maximum=0;
for(ll i=0;i<=str.size()-k;i++){
// cout<<str.substr(ans[i])<<endl;
// cout<<str.substr(ans[i+k-1])<<endl;
// cout<<findPrefixSize(str.substr(i), str.substr(i+k-1))<<endl;
maximum=max(maximum,findPrefixSize(str.substr(ans[i]), str.substr(ans[i+k-1])));
}
if(maximum==0) maximum--;
cout<<maximum<<endl;
return 0;
}