「Editor」
November 8, 2018
Assuming that the string is initially empty, the basic operations that can be performed are append/insert/delete/replace, as described below:
append: Appends a string of the specified length to the string.
insert: Inserts a string of the specified length at the specified position of an existing string.
delete: Removes a specified length of characters from an existing string at a specified location.
replace: Replaces a number of characters at a specified position in an existing string with another string.
字符串的位置从 1 开始计数
字符串中的字符,只能是 a-z、A-Z、0-9
每行由一个基本操作+后续参数组成,每种操作的参数不同,用冒号分隔
append:两个参数,分别是要追加字符串的长度、具体的字符串内容
insert:三个参数,分别是插入位置、要插入字符串的长度、具体的内容
delete:两个参数,分别是删除位置,要删除的字符个数
replace:四个参数,分别是替换位置,被替换长度,替换长度,具体的内容
样例:
append : 12 : abcdefghijkl # 操作完成后,字符串为 "abcdefghijkl" append : 10 : ABCDEFGHIJ # 操作完成后,字符串为 "abcdefghijklABCDEFGHIJ" #insert : 9 : 2 : pq # 本行忽略(忽略#开头的行) insert : 2 : 3 : XYZ # 操作完成后,字符串为 "aXYZbcdefghijklABCDEFGHIJ" delete : 10 : 2 # 操作完成后,字符串为 "aXYZbcdefijklABCDEFGHIJ" replace : 7 : 3 : 10 : 0123456789 # 操作完成后,字符串为 "aXYZbc0123456789ijklABCDEFGHIJ"
代码:
块状链表随便乱搞了一下就好了
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cctype> #include <cstring> #include <string> #define MAXIN 1 #define gc() (SS == TT && (TT = (SS = IN) + fread(IN,1,MAXIN,stdin),SS == TT) ? -1 : *SS++) int N, qqq; const int M = 1024 * 1024 * 1 + 5; int maxsize = 40000, maxnum; int num, *next, *sz, *pool; char **data, str[M], IN[MAXIN], *SS = IN, *TT = IN; char *pre; inline int read() { int now = 0, f = 1; register char c = gc(); for (; !isdigit(c); c = gc()) if (c == '-') f = -1; for (; isdigit(c); now = now * 10 + c - '0', c = gc()); return now * f; } inline int new_block() { return pool[++num]; } inline void del_block(int v) { pool[num--] = v; } void init() { for (int i = 1; i < maxnum; ++i) pool[i] = i; sz[0] = 0; //新建一个0节点,方便 表头就是0 next[0] = -1; } void merge(int cur, int Next) { memcpy(data[cur] + sz[cur], data[Next], sz[Next]); next[cur] = next[Next]; sz[cur] += sz[Next]; del_block(Next); } void maintain() { for (int cur = 0, Next = next[0]; ~cur; cur = next[cur], Next = next[cur]) while ((~Next) && sz[cur] + sz[Next] <= maxsize) { merge(cur, Next);//最好不用next[Next],因为已经合并、删掉了 Next = next[cur]; } } int get_index(int &pos) //找到pos所在的块,并将pos定位为块内位置 { int cur = 0; while ((~cur) && pos > sz[cur]) //把cur定位到某一块的末尾,不用下一块开头了(pos>=sz) { pos -= sz[cur]; cur = next[cur]; } return cur; } void update(int cur, int Next, int len, char *s)//给新的块Next设置数据及指针 { next[Next] = next[cur]; next[cur] = Next; sz[Next] = len; memcpy(data[Next], s, len); } void split(int cur, int pos) { if (cur == -1 || pos == sz[cur])//不能判!pos 因为后边会直接用next[cur],不分裂会跳过该块 return; int Next = new_block(); update(cur, Next, sz[cur] - pos, data[cur] + pos); sz[cur] = pos; } void insert(int pos, int len) { int cur = get_index(pos), sum = 0, Next; split(cur, pos); while (sum + maxsize <= len) { Next = new_block(); update(cur, Next, maxsize, str + sum);//先分成尽可能多的整块 sum += maxsize; cur = Next; } if (len - sum) //剩余的单独放到一块 Next = new_block(), update(cur, Next, len - sum, str + sum); maintain(); } void erase(int pos, int len) { int cur = get_index(pos), Next; split(cur, pos); Next = next[cur]; //because of here while ((~Next) && len > sz[Next]) len -= sz[Next], del_block(Next), Next = next[Next]; split(Next, len); del_block(Next), next[cur] = next[Next]; maintain(); } void get_data(int pos, int len) { delete[]pre; int cur = get_index(pos), sum = sz[cur] - pos; if (len < sum) sum = len; //memcpy(str, data[cur] + pos, sum); fwrite(data[cur] + pos, sizeof(char), sum, stdout); cur = next[cur]; while ((~cur) && sum + sz[cur] <= len) { //memcpy(str + sum, data[cur], sz[cur]); fwrite(data[cur], sizeof(char), sz[cur], stdout); sum += sz[cur]; cur = next[cur]; } if ((~cur) && len - sum) fwrite(data[cur], sizeof(char), len - sum, stdout); //memcpy(str + sum, data[cur], len - sum); //str[len] = '\0'; //printf("%s", str); } bool alloc(int size) { next = new(std::nothrow) int[size]; if (next == NULL) return false; sz = new(std::nothrow) int[size]; if (sz == NULL) return false; pool = new(std::nothrow) int[size]; if (pool == NULL) return false; data = new(std::nothrow) char*[size]; if (data == NULL) return false; for (int i = 0; i < size; ++i) { data[i] = new(std::nothrow) char[maxsize]; qqq = i; if (data[i] == NULL) return false; } return true; } int main() { freopen("input.txt", "rb", stdin); freopen("output.txt", "wb", stdout); fseek(stdin, 0L, SEEK_END); N = ftell(stdin); fseek(stdin, 0L, SEEK_SET); maxnum = N * 2 / maxsize + 100; pre = new(std::nothrow) char[M]; int left = 1, right = maxnum, mid = (left + right) / 2; while (1) { if (left == mid || right == mid) { maxnum = mid; break; } if (alloc(mid) == true) { delete[]next; delete[]sz; delete[]pool; for (int i = 0; i < mid; ++i) delete[]data[i]; delete[]data; left = mid; mid = (left + right) / 2; } else { delete[]next; delete[]sz; delete[]pool; for (int i = 0; i < qqq; ++i) delete[]data[i]; delete[]data; right = mid; mid = (left + right) / 2; } } alloc(maxnum); int limit; if (maxnum > 200) limit = (maxnum - 100)*maxsize / 2; else limit = 100 * maxsize / 2; init(); int pos = 0, len, tot = 0; char c; while (1) { c = gc(); if (c == -1) break; if (c == 'a') { len = read(); if (len + tot > limit) { get_data(0, tot); return 0; } while (1) { char ch = gc(); if (isdigit(ch) || islower(ch) || isupper(ch)) { str[0] = ch; break; } } fread(str + 1, sizeof(char)*(len - 1), 1, stdin); insert(tot, len); tot += len; //get_data(0, tot); while (gc() != '\n') ; } else if (c == 'i') { pos = read(); len = read(); if (len + tot > limit) { get_data(0, tot); return 0; } while (1) { char ch = gc(); if (isdigit(ch) || islower(ch) || isupper(ch)) { str[0] = ch; break; } } fread(str + 1, sizeof(char), len - 1, stdin); insert(pos - 1, len); tot += len; //get_data(0, tot); while (gc() != '\n') ; } else if (c == 'd') { pos = read(); len = read(); erase(pos - 1, len); tot -= len; //get_data(0, tot); } else if (c == 'r') { pos = read(); len = read(); erase(pos - 1, len); tot -= len; len = read(); if (len + tot > limit) { get_data(0, tot); return 0; } tot += len; while (1) { char ch = gc(); if (isdigit(ch) || islower(ch) || isupper(ch)) { str[0] = ch; break; } } fread(str + 1, sizeof(char), len - 1, stdin); insert(pos - 1, len); //get_data(0, tot); while (gc() != '\n') ; } else if (c == '#') while (gc() != '\n') ; } get_data(0, tot); fclose(stdout); fclose(stdin); return 0; }