用链表模拟文本编辑操作
L、R光标左右移动、到尽头则不移动
S、切换插入模式 覆盖模式
C 选中模式开启,再次按下C 则为复制到剪切板
V粘贴
B 删除光标前一个字符 在尽头则不删除
D删除光标前一个字符 在尽头则不删除、如果C选中模式开启了且选择了文字,则删除该段文字
按下C后 再按下除CLR外任何一个字母都会 使 C选中模式 无效
因为用了STL的list 其中pos为当前光标 (当时没注意到以下2点,一直runtime error)
删除的时候 应该接收erase函数返回的迭代器。这样用 才不会丢失pos指针 、 pos=xx.erase(y); 由于erase后pos与数组头的位置不会改变,所以不需要修改pos_num
而插入的时候pos会自动往后走,所以不必接收返回的迭代器、但是计算pos与数组头相对位置的pos_num要随之加1
最后注意一下清空一些变量、剪切板、
数据比较弱,据说直接数组模拟也可以过
代码没封装好 。写得相当挫。。。查错都麻烦,以后不要这样写了
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <queue> #include <list> #include <set> #include <vector> using namespace std; list<char> sb; list <char>::iterator pos,tmp,tp; list <char>::iterator st,ed,s1,s2; char tm[10005]; char cop[10005]; int len_cop; int pos_num; int st_num; void show() { for (tmp=sb.begin();tmp!=sb.end();tmp++) printf("%c",*tmp); printf("\n"); } int main() { int t,len; int i; scanf("%d",&t); while(t--) { sb.clear(); scanf("%d",&len); getchar(); scanf("%s",tm); int leng=strlen(tm); if (len==0) { printf("NOTHING\n"); continue; } pos=sb.begin(); pos++; int S=0; int copy_state=0; pos_num=0; st_num=len_cop=0; for (i=0;i<leng;i++) { if (tm[i]>='a'&&tm[i]<='z') { copy_state=0; if (S==0)//insert mode { if (sb.size()<len) { sb.insert(pos,tm[i]); pos_num++; } } else //overwrite { if (pos!=sb.end()) pos=sb.erase(pos); if (sb.size()<len) { sb.insert(pos,tm[i]); pos_num++; } } } else { if (tm[i]=='L'&&pos!=sb.begin()) { pos--; pos_num--; if (copy_state==1) { ed=pos; st_num--; } } if (tm[i]=='R'&&pos!=sb.end()) { pos++; pos_num++; if (copy_state==1) { ed=pos; st_num++; } } if (tm[i]=='S') { copy_state=0; S=!S; } if (tm[i]=='C') { if (copy_state==0) { copy_state=1; st=pos; ed=pos; st_num=0; } else { len_cop=copy_state=0; if (st==ed) continue; if (st_num>0) { for (tmp=st;tmp!=ed;tmp++) { cop[++len_cop]=*tmp; } } else { for (tmp=ed;tmp!=st;tmp++) { cop[++len_cop]=*tmp; } } } } if (tm[i]=='D') { if (copy_state==0) { if (pos==sb.end()) continue; pos=sb.erase(pos); } else { copy_state=0; if (st_num>0) { pos_num-=st_num; pos=sb.erase(st,ed); } else pos=sb.erase(ed,st); } } if (tm[i]=='B') { copy_state=0; if (pos==sb.begin()) continue; pos--; pos_num--; pos=sb.erase(pos); } if (tm[i]=='V') { copy_state=0; if (len_cop>0) { if (S==0)//insert mode { if (sb.size()+len_cop<=len) { for (int j=1;j<=len_cop;j++) { sb.insert(pos,cop[j]); pos_num++; } } } else //overwrite { if (pos_num+len_cop<=len) { s1=s2=pos; int j; int len1=sb.size()-pos_num; for (j=1;j<=len_cop&&j<=len1;j++) s2++; pos=sb.erase(s1,s2); for (j=1;j<=len_cop;j++) { sb.insert(pos,cop[j]); pos_num++; } } } } } } } if (sb.size()==0) { printf("NOTHING\n"); continue; } else { show(); } } return 0; }