新增了ActionManager类,用于管理撤回、重做

This commit is contained in:
梦凌汐 2024-12-19 01:36:28 +08:00
parent b20d8aa6d0
commit 00b7386cfb
3 changed files with 186 additions and 3 deletions

View File

@ -211,6 +211,24 @@ public:
long long operator-(iterator other) const { long long operator-(iterator other) const {
return ptr - other.ptr; return ptr - other.ptr;
} }
iterator& operator+=(size_t n) {
ptr += n;
return *this;
}
iterator& operator-=(size_t n) {
ptr -= n;
return *this;
}
friend iterator operator++(iterator& ite) {
++ite.ptr;
return ite;
}
friend iterator operator--(iterator& ite) {
--ite.ptr;
return ite;
}
}; };
iterator begin() { iterator begin() {
@ -224,6 +242,14 @@ public:
void erase(iterator target) { void erase(iterator target) {
erase(target - begin()); erase(target - begin());
} }
void reverse() {
MyVector<T> tmp = *this;
for (size_t i = 0; i < m_size / 2; ++i) {
std::swap(tmp[i], tmp[m_size - i - 1]);
}
*this = tmp;
}
}; };
#endif // MY_VECTOR_H #endif // MY_VECTOR_H

View File

@ -1,14 +1,148 @@
#ifndef ACTIONMANAGER_H #ifndef ACTIONMANAGER_H
#define ACTIONMANAGER_H #define ACTIONMANAGER_H
enum class EditAction { #include "../mystl/my_stack.h"
#include <string>
enum class EditActiontype {
Initialize, Initialize,
Insert, Insert,
Delete, Delete,
}; };
class ActionManager { struct EditAction {
EditActiontype type;
int pos;
std::string content;
};
} class ActionManager {
private:
MyStack<MyVector<EditAction>> undoStack_, redoStack_;
std::string content_;
MyVector<EditAction> calculateEditActions(const std::string &str1, const std::string &str2) { // 规定Editor只会在删除或者插入时提交因此只会同时存在一种操作
int m = str1.length();
int n = str2.length();
MyVector<MyVector<int>> dp(m + 1, MyVector<int>(n + 1));
for (int i = 0; i <= m; ++i) {
dp[i][0] = i;
}
for (int j = 0; j <= n; ++j) {
dp[0][j] = j;
}
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (str1[i - 1] == str2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = std::min(dp[i - 1][j], dp[i][j - 1]) + 1;
}
}
}
// 回溯以找到编辑操作
MyVector<EditAction> actions;
int i = m, j = n;
while (i > 0 && j > 0) {
if (str1[i - 1] == str2[j - 1]) {
--i;
--j;
} else if (dp[i][j] == dp[i - 1][j] + 1) {
actions.push_back({EditActiontype::Delete, i - 1, std::string(1, str1[i - 1])});
--i;
} else if (dp[i][j] == dp[i][j - 1] + 1) {
actions.push_back({EditActiontype::Insert, i, std::string(1, str2[j - 1])});
--j;
}
}
while (i > 0) {
actions.push_back({EditActiontype::Delete, i - 1, std::string(1, str1[i - 1])});
--i;
}
while (j > 0) {
actions.push_back({EditActiontype::Insert, i, std::string(1, str2[j - 1])});
--j;
}
actions.reverse();
// 考虑到先前进行的插入和删除操作,对随后插入和删除的位置进行修正
int offset = 0;
for (int i = 0; i < actions.size(); ++i) {
if (actions[i].type == EditActiontype::Insert) {
actions[i].pos += offset;
offset++;
} else if (actions[i].type == EditActiontype::Delete) {
actions[i].pos += offset;
offset--;
}
}
return actions;
}
std::string applyEditAction(MyVector<EditAction> &actions, std::string &content) {
std::string newContent = content;
for(int i = 0; i < actions.size(); i++) {
if(actions[i].type == EditActiontype::Insert) {
newContent.insert(actions[i].pos, actions[i].content);
} else if(actions[i].type == EditActiontype::Delete) {
newContent.erase(actions[i].pos, actions[i].content.size());
}
}
return newContent;
}
public:
ActionManager() {
}
ActionManager(const std::string &content) {
content_ = content;
}
void updateContent(const std::string &content) {
redoStack_.clear();
MyVector<EditAction> actions = calculateEditActions(content_, content);
content_ = content;
undoStack_.push(actions);
}
void undo() {
if (undoStack_.empty()) {
return;
}
MyVector<EditAction> actions = undoStack_.top();
undoStack_.pop();
std::string newContent = applyEditAction(actions, content_);
redoStack_.push(calculateEditActions(content_, newContent));
content_ = newContent;
}
void redo() {
if (redoStack_.empty()) {
return;
}
MyVector<EditAction> actions = redoStack_.top();
redoStack_.pop();
std::string newContent = applyEditAction(actions, content_);
undoStack_.push(calculateEditActions(content_, newContent));
content_ = newContent;
}
void setContent(const std::string &content) {
content_ = content;
undoStack_.clear();
redoStack_.clear();
}
std::string getContent() {
return content_;
}
};
#endif #endif

View File

@ -0,0 +1,23 @@
#include <stdio.h>
#include "ActionManager.h"
#include "../mystl/my_vector.h"
using namespace std;
int main() {
ActionManager am;
MyVector<EditAction> v;
v = am.calculateEditActions("i can see you, but u dont love me", "i cant hug u, but i love you");
printf("Actions: %zu\n", v.size());
//replay test
std::string s1 = "i can see you, but u dont love me";
for(int i = 0; i < v.size(); i++) {
if(v[i].type == EditActiontype::Insert) {
s1.insert(v[i].pos, v[i].content);
} else if(v[i].type == EditActiontype::Delete) {
s1.erase(v[i].pos, v[i].content.size());
}
}
printf("%s\n", s1.c_str());
return 0;
}