-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathwsjcpp_diff_text.cpp
More file actions
186 lines (169 loc) · 4.97 KB
/
Copy pathwsjcpp_diff_text.cpp
File metadata and controls
186 lines (169 loc) · 4.97 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
#include "wsjcpp_diff_text.h"
#include <sstream>
namespace wsjcpp {
diff_text_row::diff_text_row(
int number_of_line,
const std::string &key,
const std::string &line
) :
m_number_of_line(number_of_line)
, m_key(key)
, m_line(line)
{}
int diff_text_row::number_of_line() const {
return m_number_of_line;
}
std::string diff_text_row::key() const {
return m_key;
}
diff_text_row_action diff_text_row::action() const {
if (m_key == "!del") {
return diff_text_row_action::DELETE;
}
if (m_key == "!add") {
return diff_text_row_action::INSERT;
}
if (m_key == m_line) {
return diff_text_row_action::NONE;
}
return diff_text_row_action::NONE;
}
bool diff_text_row::is_delete() const {
return action() == diff_text_row_action::DELETE;
}
bool diff_text_row::is_insert() const {
return action() == diff_text_row_action::INSERT;
}
std::string diff_text_row::line() const {
return m_line;
}
std::string diff_text_row::to_string() const {
std::string ret;
ret += std::to_string(m_number_of_line);
ret += ":";
if (action() == diff_text_row_action::DELETE) {
ret += "-";
} else if (action() == diff_text_row_action::INSERT) {
ret += "+";
} else {
ret += ".";
}
ret += m_line;
return ret;
}
void diff_text_split(const std::string &text, std::vector<std::string> &output) {
std::istringstream is_text(text);
std::string line = "";
while (getline(is_text, line, '\n')) {
output.push_back(line);
}
}
void diff_text_compare(
const std::string &text_left,
const std::string &text_right,
std::vector<diff_text_row> &output_diff
) {
std::vector<std::string> list_left;
diff_text_split(text_left, list_left);
std::vector<std::string> list_right;
diff_text_split(text_right, list_right);
std::vector<std::string> sWord;
sWord.push_back("!add");
sWord.push_back("!del");
int len1 = list_left.size();
int len2 = list_right.size();
int i = 0, j = 0;
// main comparisons
while ((i < len1) && (j < len2)) {
if (list_left[i] != list_right[j]) {
// checkout for added rows
for (int k = j + 1; k < len2; ++k) {
if (list_left[i] == list_right[k]) {
while (j<k) {
output_diff.push_back(diff_text_row(j, sWord.at(0), list_right.at(j)));
j++;
}
goto exit;
}
}
// checkout for deleted rows
for (int k = i + 1; k < len1; ++k) {
if (list_left[k] == list_right[j]) {
while (i<k) {
output_diff.push_back(diff_text_row(i, sWord.at(1), list_left.at(i)));
i++;
}
goto exit;
}
}
output_diff.push_back(diff_text_row(i, list_left.at(i), list_right.at(j)));
exit:;
}
i++, j++;
}
//work with the end of the texts
while (j < len2) {
output_diff.push_back(diff_text_row(j, sWord.at(0), list_right.at(j)));
j++;
}
while (i < len1) {
output_diff.push_back(diff_text_row(i, sWord.at(1), list_left.at(i)));
i++;
}
}
void diff_text_merge(
std::string &curtxt,
std::string &txt1,
std::string &txt2,
std::vector<diff_text_row> &arr_left,
std::vector<diff_text_row> &arr_right
) {
diff_text_compare(txt1, txt2, arr_left);
diff_text_compare(txt1, curtxt, arr_right);
for (unsigned int i = 0; i < arr_right.size(); ++i) {
const diff_text_row &row_right = arr_right.at(i);
for (unsigned int j = 0; j < arr_left.size(); ++j) {
const diff_text_row &row_left = arr_left.at(j);
//delete of matches and 'del'/'add' overlays from the first vector
bool bLinesEqual = row_right.line() == row_left.line();
if (bLinesEqual &&
(
(row_right.is_insert() && row_left.is_insert())
|| (row_left.is_delete())
)
) {
arr_left.erase(arr_left.begin() + j);
break;
}
}
}
for (unsigned int i = 0; i < arr_left.size(); ++i) {
const diff_text_row &row_left = arr_left.at(i);
for (unsigned int j = 0; j < arr_right.size(); ++j) {
const diff_text_row &row_right = arr_right.at(j);
//delete of del overlays from the second vector and update of priority
bool bLinesEqual = row_left.key() == row_right.line(); // TODO check why comparing key and line here ?
bool bKeysEqual = row_left.key() == row_right.key();
std::string key_right = row_right.key();
if (
(bLinesEqual && row_right.is_delete())
|| (bKeysEqual && !row_right.is_insert() && !row_right.is_delete())
) {
arr_right.erase(arr_right.begin() + j);
break;
}
}
}
// merge and sort vectors
arr_left.reserve(arr_left.size() + arr_right.size());
arr_left.insert(arr_left.end(), arr_right.begin(), arr_right.end());
for (unsigned int i = 0; i < arr_left.size(); ++i) {
for (unsigned int j = arr_left.size() - 1; j > i; --j) {
if (arr_left.at(j - 1).number_of_line() > arr_left.at(j).number_of_line()) {
// TODO redesign
std::swap(arr_left.at(j - 1), arr_left.at(j));
}
}
}
}
} // namespace wsjcpp