這些日子,可可不和卡卡一塊兒玩了,原來可可正廢寢忘食的想作一個簡單而高效的文本編輯器。你能幫助他嗎?爲了明確任務目標,可可對「文本編輯器」作了一個抽象的定義: 文本:由0個或多個字符構成的序列。這些字符的ASCII碼在閉區間[32, 126]內,也就是說,這些字符均爲可見字符或空格。光標:在一段文本中用於指示位置的標記,能夠位於文本的第一個字符以前,文本的最後一個字符以後或文本的某兩個相鄰字符之間。文本編輯器:爲一個能夠對一段文本和該文本中的一個光標進行以下七條操做的程序。若是這段文本爲空,咱們就說這個文本編輯器是空的。 編寫一個程序: 創建一個空的文本編輯器。 從輸入文件中讀入一些操做指令並執行。 對全部執行過的GET操做,將指定的內容寫入輸出文件。php
輸入文件中第一行是指令條數N,如下是須要執行的N個操做。除了回車符以外,輸入文件的全部字符的ASCII碼都在閉區間[32, 126]內。且行尾沒有空格。ios
依次對應輸入文件中每條GET指令的輸出,不得有任何多餘的字符。編輯器
對輸入數據咱們有以下假定: MOVE操做不超過50 000個,INSERT、DELETE和ROTATE操做做的總個數不超過6 000,GET操做不超過20 000個,PREV和NEXT操做的總個數不超過20 000。 全部INSERT插入的字符數之和不超過2M(1M=1 024*1 024)。 DELETE操做、ROTATE操做和GET操做執行時光標後必然有足夠的字符。MOVE、PREV、NEXT操做不會把光標移動到非法位置。 輸入文件沒有錯誤。spa
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<queue>
5 #include<algorithm>
6 using namespace std;
7 const int MAXN=2000000+10;
8 const int BlockSize=3000 + 100,BlockNum=3000 + 10;
9 int Cur=0,head,tot;
10 char str[MAXN];
11 struct Block
12 {
13 int size,nxt;
14 bool rev;
15 char a[BlockSize];
16 void Clear()
17 {
18 size=0;nxt=-1,rev=0;
19 }
20 }B[BlockNum];
21 queue<int>q;//鐢ㄤ竴涓槦鍒楁潵緇存姢褰撳墠鏈夊摢浜涘潡
22 int NewNode()
23 {
24 int t=q.front();q.pop();
25 B[t].Clear();
26 return t;
27 }
28 inline void Pre()
29 {
30 while(q.size()!=0) q.pop();
31 for(int i=0;i<BlockNum;i++) q.push(i);
32 head = NewNode();
33 }
34 void Find(int &idx,int &cur)
35 {
36 while(idx!=-1&&cur>B[idx].size) cur-=B[idx].size,idx=B[idx].nxt;
37 }
38 void Pushdown(int idx)
39 {
40 if(B[idx].rev)
41 {
42 // for(int i=0;i<B[idx].size;i++)
43 // cout<<B[idx].a[i];cout<<endl;
44 reverse(B[idx].a,B[idx].a+B[idx].size);
45 // for(int i=0;i<B[idx].size;i++)
46 // cout<<B[idx].a[i];cout<<endl;
47 B[idx].rev=0;
48 }
49
50 }
51 inline void Split(int idx,int cur)
52 {
53 if(idx==-1||cur==B[idx].size) return ;
54 Pushdown(idx);
55 int tot=NewNode();
56 memcpy(B[tot].a,B[idx].a+cur,sizeof(char) * (B[idx].size-cur) );
57 B[tot].size=B[idx].size-cur;
58 B[idx].size=cur;
59 B[tot].nxt=B[idx].nxt;
60 B[idx].nxt=tot;
61 }
62 void Delet(int idx)
63 {
64 q.push(idx);
65 }
66 void Merge(int idx)
67 {
68 for(int i=idx;i!=-1;i=B[i].nxt)
69 for(int j=B[i].nxt;j!=-1;j=B[j].nxt)
70 {
71 if(B[i].size+B[j].size<=BlockSize)
72 {
73 Pushdown(i);
74 Pushdown(j);
75 memcpy(B[i].a+B[i].size,B[j].a,sizeof(char) * B[j].size);
76 B[i].size+=B[j].size;B[i].nxt=B[j].nxt;
77 Delet(j);
78 }
79 else break;
80 }
81 }
82 inline void Insert(int cur,int x,char *str)
83 {
84 int idx=head;
85 Find(idx,cur);
86 Split(idx,cur);
87 int i=0;//宸茬粡鍔犲靉鐨勪釜鏁?
88 while(i<x)
89 {
90 int Limit=min(BlockSize,x-i);
91 int tot=NewNode();
92 memcpy(B[tot].a,str+i,sizeof(char) * Limit);
93 B[tot].size=Limit;
94 B[tot].nxt=B[idx].nxt;
95 B[idx].nxt=tot;
96 idx=B[idx].nxt;
97 i+=Limit;
98 }
99 Merge(head);
100 }
101 void Print(int cur)
102 {
103 int idx=head;
104 Find(idx,cur);
105 if(cur==B[idx].size) idx=B[idx].nxt,cur=0;
106 Pushdown(idx);
107 printf("%c\n",B[idx].a[cur]);
108 }
109 void Rever(int l,int r)
110 {
111 int idx=head;
112 Find(idx,l);
113 Split(idx,l);
114 int Start=idx,StartNxt=B[idx].nxt;
115 idx=head;
116 Find(idx,r);
117 Split(idx,r);
118 int EndNxt=B[idx].nxt;
119 int Tmp[BlockNum],cnt=0;
120 for(int i=StartNxt;i!=EndNxt;i=B[i].nxt)
121 B[i].rev^=1,Tmp[++cnt]=i;
122 Tmp[++cnt]=Start;Tmp[0]=EndNxt;
123 for(int i=cnt;i>=1;i--)
124 B[Tmp[i]].nxt=Tmp[i-1];
125 Merge(head);
126 }
127 void Dele(int l,int r)
128 {
129 int idx=head;
130 Find(idx,l);
131 Split(idx,l);
132 int Start=idx,StartNxt=B[idx].nxt;
133 idx=head;
134 Find(idx,r);
135 Split(idx,r);
136 int EndNxt=B[idx].nxt;
137 for(int i=StartNxt;i!=EndNxt;i=B[i].nxt) Delet(i);
138 B[Start].nxt=EndNxt;
139 Merge(head);
140 }
141 int main()
142 {
143 #ifdef WIN32
144 freopen("a.in","r",stdin);
145 #else
146 #endif
147 int N;scanf("%d",&N);
148 char opt[20];
149 Pre();
150 while(N--)
151 {
152 scanf("%s",opt);
153 if(opt[0]=='M')
154 scanf("%d",&Cur);
155 else if(opt[0]=='I')
156 {
157 int len;
158 scanf("%d", &len);
159 int i = 0;
160 while(i < len) {char ch = getchar();if(ch >= 32 && ch <= 126) str[i++] = ch;}
161 str[i++] = '\0';
162 Insert(Cur,len,str);
163 }
164 else if(opt[0]=='D')
165 {
166 int x;
167 scanf("%d",&x);
168 Dele(Cur,Cur+x);
169 }
170 else if(opt[0]=='R')
171 {
172 int x;
173 scanf("%d",&x);
174 Rever(Cur,x+Cur);
175 }
176 else if(opt[0]=='G')
177 Print(Cur);
178 else if(opt[0]=='P') Cur--;
179 else if(opt[0]=='N') Cur++;
180 }
181 return 0;
182 }