forked from new299/DS
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathedit_distance.h
More file actions
200 lines (154 loc) · 4.74 KB
/
Copy pathedit_distance.h
File metadata and controls
200 lines (154 loc) · 4.74 KB
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
const int cost_del = 1;
const int cost_ins = 1;
const int cost_sub = 1;
int hamming_distance(string &s1,string &s2) {
int distance=0;
for(int n=0;(n<s1.size()) && (n<s2.size());n++) {
if(s1[n] != s2[n]) { distance++; }
else { if(s1[n] == '1') {distance-=200;}}
}
return distance;
}
string trim(string str) {
string strout;
bool saw_1 = false;
for(size_t n=0;n<str.size();n++) {
if(str[n] == '1') saw_1 = true;
if(saw_1) strout += str[n];
}
saw_1 = false;
string strout1;
for(int n=strout.size()-1;n>=0;n--) {
if(strout[n] == '1') saw_1 = true;
if(saw_1) strout1 += strout[n];
}
string frw;
for(int n=strout1.size()-1;n>=0;n--) {
frw += strout1[n];
}
return frw;
}
int edit_distance_r(const string &s1,const string &s2) {
int n1 = s1.size();
int n2 = s2.size();
int* p = new int[n2+1];
int* q = new int[n2+1];
int* r;
p[0] = 0;
for( int j = 1; j <= n2; ++j )
p[j] = p[j-1] + cost_ins;
for( int i = 1; i <= n1; ++i )
{
q[0] = p[0] + cost_del;
for( unsigned int j = 1; j <= n2; ++j )
{
int d_del = p[j] + cost_del;
int d_ins = q[j-1] + cost_ins;
int d_sub = p[j-1];
// d_sub += ( s1[i-1] == s2[j-1] ? 0 : cost_sub );
if((s1[i-1] == s2[j-1]) && (s1[i-1] == '1')) d_sub -= 2;
else d_sub += 0;
if((s1[i-1] != s2[j-1])) {
d_sub += cost_sub;
if(s1[i-1] == '1') d_sub += 2;
if(s2[j-1] == '1') d_sub += 2;
}
q[j] = std::min( std::min( d_del, d_ins ), d_sub );
}
r = p;
p = q;
q = r;
}
int tmp = p[n2];
delete[] p;
delete[] q;
return tmp;
}
int black_count(string &s) {
int count=0;
for(size_t n=0;n<s.size();n++) {
if(s[n] == '1') count++;
}
return count;
}
int calc_distance(const string &s1_in,const string &s2_in,int offset,bool fast) {
string s1;
string s2;
if(fast == true) {
for(size_t n=0;n<s1_in.size();n++) { if((n%2)==0) s1 += s1_in[n]; }
for(size_t n=0;n<s2_in.size();n++) { if((n%2)==0) s2 += s2_in[n]; }
offset = offset/2;
} else {
s1 = s1_in;
s2 = s2_in;
}
if(s1.size() < 2) return -1;
if(s2.size() < 2) return -1;
int s1_start;
int s1_end;
int s2_start;
int s2_end;
if(offset < 0) {
s1_start = 0-offset;
s1_end = s1.size();
s2_start = 0;
s2_end = s1.size()+offset;
} else {
s1_start = 0;
s1_end = s1.size() - offset;
s2_start = offset;
s2_end = s2.size();
}
//cout << "s1 range: " << s1_start << " " << s1_end << endl;
//cout << "s2 range: " << s2_start << " " << s2_end << endl;
string s1_region = s1.substr(s1_start,s1_end-s1_start);
string s2_region = s2.substr(s2_start,s2_end-s2_start);
//int score = hamming_distance(s1_region,s2_region);
int score = edit_distance_r(s1_region,s2_region);
//cout << "offset: " << offset << endl;
//cout << "score : " << score << endl;
int overlap_size = 0;
if(s1_region.size() < s2_region.size()) overlap_size = s1_region.size();
else overlap_size = s2_region.size();
//cout << "score: " << score << " overlap_size: " << overlap_size << endl;
if(overlap_size < 10) return 0;
// cout << "offset : " << offset << endl;
// cout << "score : " << score << endl;
// cout << "score scaled: " << (100-score);
// cout << "over scaled: " << 100*((double)overlap_size/(double)s1.size()) << endl;
return (100-score) + 100*((double)overlap_size/(double)s1.size());// + black_count(s1_region) + black_count(s2_region);
}
// overlappy
int edit_distance(const string &s1,const string &s2) {
//cout << "edit_distance here" << endl;
int offset=(0-s1.size())+1;
offset += 20; // at least 20px overlap
int max_score = -1;
int max_score_offset = offset;
//cout << "offset: " << offset << endl;
//cout << "s1size: " << s1.size() << endl;
int s1size = s1.size();
int s2size = s2.size();
int ssize;
if(s1size < s2size) ssize = s1size-1; else ssize = s2size-1;
ssize -= 20; // at least 20px overlap
for(;offset<ssize;offset+=10) {
int score = calc_distance(s1,s2,offset,true);
if(score > max_score) {
max_score = score;
max_score_offset = offset;
}
}
int overlap_max = max_score_offset+20;
if((overlap_max < (ssize+20)) && ((max_score_offset-20) > (offset=(0-s1.size())+1) ))
for(offset=max_score_offset-20;offset<overlap_max;offset++) {
int score = calc_distance(s1,s2,offset,false);
if(score > max_score) {
max_score = score;
max_score_offset = offset;
}
}
cout << "max_score_offset: " << max_score_offset << endl;
cout << "max_score : " << max_score << endl;
return max_score;
}