-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
141 lines (114 loc) · 5.16 KB
/
main.cpp
File metadata and controls
141 lines (114 loc) · 5.16 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
#include <bits/stdc++.h>
using namespace std;
#define ll long long
// ==========================================
// 1. GLOBAL CONSTANTS (Terminal Colors)
// ==========================================
const string RESET = "\033[0m";
const string RED = "\033[31m";
const string GREEN = "\033[32m";
const string YELLOW = "\033[33m";
// Calculates the minimum operations required (Pure DP)
int calculateMinOperations(int i, int j, const string& word1, const string& word2, vector<vector<int>>& memo);
// Recursively reconstructs the path, returns the colored diff, and logs the steps
string reconstructPath(int i, int j, const string& word1, const string& word2, vector<vector<int>>& memo, vector<string>& stepLog);
// Manages the state, calls the functions, and handles all Console I/O
void runTextComparisonSystem(const string& oldText, const string& newText);
int calculateMinOperations(int i, int j, const string& word1, const string& word2, vector<vector<int>>& memo) {
// Base cases
if (i < 0) return j + 1;
if (j < 0) return i + 1;
int &ret = memo[i][j];
if (ret != -1) return ret;
ret = 1e9; // Infinity
// Match State
if (word1[i] == word2[j]) {
ret = min(ret, calculateMinOperations(i - 1, j - 1, word1, word2, memo));
}
// Delete, Insert, Replace States
ret = min(ret, 1 + calculateMinOperations(i - 1, j, word1, word2, memo));
ret = min(ret, 1 + calculateMinOperations(i, j - 1, word1, word2, memo));
ret = min(ret, 1 + calculateMinOperations(i - 1, j - 1, word1, word2, memo));
return ret;
}
string reconstructPath(int i, int j, const string& word1, const string& word2, vector<vector<int>>& memo, vector<string>& stepLog) {
// Base Case 1: Insert remaining characters
if (i < 0) {
string diffResult = "";
for (int k = 0; k <= j; ++k) {
stepLog.push_back(GREEN + "INSERT " + to_string(k + 1) + " (" + word2[k] + ")" + RESET);
diffResult += GREEN + word2[k] + RESET;
}
return diffResult;
}
// Base Case 2: Delete remaining characters
if (j < 0) {
string diffResult = "";
for (int k = 0; k <= i; ++k) {
stepLog.push_back(RED + "DELETE " + to_string(k + 1) + " (" + word1[k] + ")" + RESET);
diffResult += RED + word1[k] + RESET;
}
return diffResult;
}
int ret = memo[i][j];
// Backtrack 1: Match
if (word1[i] == word2[j] && ret == calculateMinOperations(i - 1, j - 1, word1, word2, memo)) {
string previousDiff = reconstructPath(i - 1, j - 1, word1, word2, memo, stepLog);
return previousDiff + word1[i];
}
// Backtrack 2: Delete
if (ret == 1 + calculateMinOperations(i - 1, j, word1, word2, memo)) {
string previousDiff = reconstructPath(i - 1, j, word1, word2, memo, stepLog);
stepLog.push_back(RED + "DELETE " + to_string(i + 1) + " (" + word1[i] + ")" + RESET);
return previousDiff + RED + word1[i] + RESET;
}
// Backtrack 3: Insert
if (ret == 1 + calculateMinOperations(i, j - 1, word1, word2, memo)) {
string previousDiff = reconstructPath(i, j - 1, word1, word2, memo, stepLog);
stepLog.push_back(GREEN + "INSERT " + to_string(j + 1) + " (" + word2[j] + ")" + RESET);
return previousDiff + GREEN + word2[j] + RESET;
}
// Backtrack 4: Replace
if (ret == 1 + calculateMinOperations(i - 1, j - 1, word1, word2, memo)) {
string previousDiff = reconstructPath(i - 1, j - 1, word1, word2, memo, stepLog);
stepLog.push_back(YELLOW + "REPLACE " + to_string(j + 1) + " (" + word2[j] + ")" + RESET);
return previousDiff + YELLOW + word2[j] + RESET;
}
return "";
}
void runTextComparisonSystem(const string& oldText, const string& newText) {
int n = oldText.size();
int m = newText.size();
// State Initialization
vector<vector<int>> memo(n, vector<int>(m, -1));
vector<string> stepLog; // Holds the step-by-step instructions
cout << "====================================\n";
cout << "Original Text : " << oldText << "\n";
cout << "Modified Text : " << newText << "\n";
cout << "====================================\n";
// Step 1: Execute Pure DP Function
int totalOperations = calculateMinOperations(n - 1, m - 1, oldText, newText, memo);
cout << "Total Operations Needed: " << totalOperations << '\n';
cout << "====================================\n\n";
// Step 2: Execute Path Reconstruction (Functional state passing)
string finalVisualDiff = reconstructPath(n - 1, m - 1, oldText, newText, memo, stepLog);
// Step 3: Print the accumulated Step-by-Step Log
cout << "--- Step-by-Step Operations ---\n";
for (const string& step : stepLog) {
cout << step << '\n';
}
// Step 4: Print the Final Visual Diff
cout << "\n--- Final Visual Diff ---\n";
cout << finalVisualDiff << '\n';
cout << "====================================\n\n";
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
// Define Inputs
string oldText = "Dynamic Progamming is hard.";
string newText = "Dynamic Programming is fun!";
// Run System
runTextComparisonSystem(oldText, newText);
return 0;
}