• 【POJ2887】【块状链表】Big String


    Description

    You are given a string and supposed to do some string manipulations.

    Input

    The first line of the input contains the initial string. You can assume that it is non-empty and its length does not exceed 1,000,000.

    The second line contains the number of manipulation commands N (0 < N ≤ 2,000). The following N lines describe a command each. The commands are in one of the two formats below:

    1. I ch p: Insert a character ch before the p-th character of the current string. If p is larger than the length of the string, the character is appended to the end of the string.
    2. Q p: Query the p-th character of the current string. The input ensures that the p-th character exists.

    All characters in the input are digits or lowercase letters of the English alphabet.

    Output

    For each Q command output one line containing only the single character queried.

    Sample Input

    ab
    7
    Q 1
    I c 2
    I d 4
    I e 2
    Q 5
    I f 1
    Q 3

    Sample Output

    a
    d
    e

    Source

    【分析】

    知识拿块状链表练练手而已。

    这是我写的第一个块状链表,怎么说呢,块状链表应该说是写起来比较麻烦的,因为要注意的边界条件有点多,不过适应了应该会很好骗分。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <vector>
      6 #include <utility>
      7 #include <iomanip>
      8 #include <string>
      9 #include <cmath>
     10 #include <queue>
     11 #include <map>
     12 
     13 const int MAXC = 1000000 + 10; 
     14 const int MAXM = 1000 + 10; 
     15 const int MAXN = 1000000 + 10;
     16 const int N=2000, L=2000;//L代表单个块的长度,N为最大的总块数 
     17 using namespace std;
     18 struct Block_List {//BLOCK_LIST为块状链表的英文名 
     19     struct Node {
     20         char str[L];
     21         //next数组志向下一个块状链表 
     22         int next, size;
     23         void init(){
     24              memset(str, 0, sizeof(str));
     25              next = -1;
     26              size = 0;
     27         }
     28     }list[N];
     29     int head, tot;
     30 
     31     void init(char str[]){
     32          head = tot = 0;//整个块状链表进行初始化
     33          list[tot++].init();//进行第一个块状链表的初始化
     34          for (int i = 0, cur = head; str[i]; cur = list[cur].next){
     35              for (int j = 0; j < L && str[i]; j++, i++){
     36                  list[cur].str[j] = str[i];
     37                  list[cur].size++;
     38              }
     39              //还能继续装 
     40              if (str[i]){
     41                 list[tot].init();//注意tot永远指向下一个空的块状链表
     42                 list[cur].next = tot++; 
     43              }
     44          } 
     45          for (int cur = head; cur != -1; cur = list[cur].next)
     46          if (list[cur].size == L) split(cur);//分割块状链表 
     47     }
     48     //对第x块块状链表进行分割 
     49     void split(int x){
     50          list[tot].init();
     51          //注意块状链表的下标是从0 - (L - 1) 
     52          for (int i = L / 2; i < L; i++){
     53              list[tot].str[i - L/2] = list[x].str[i];
     54              list[tot].size++;
     55              list[x].size--;
     56              list[x].str[i] = 0;//清空?好像没什么用 
     57          }
     58          list[tot].next = list[x].next;
     59          list[x].next = tot++;
     60     }
     61     void insert(int pos, char val){
     62          int cur = head;
     63          //注意开始不需要-1是因为一定成立,注意不要让任何一个块状链表达到满的状态,不然维护起来很麻烦 
     64          while (pos - list[cur].size > 0 && list[cur].next != -1){
     65                pos -= list[cur].size;
     66                cur = list[cur].next; 
     67          }
     68          if (pos >= list[cur].size) list[cur].str[list[cur].size] = val;
     69          else {
     70               //先进行移动
     71               for (int i = list[cur].size; i > pos; i--) list[cur].str[i] = list[cur].str[i - 1] ;
     72               list[cur].str[pos] = val;
     73          }
     74          list[cur].size++;
     75          if (list[cur].size == L) split(cur);
     76     }
     77     char find(int pos){
     78          int cur = head;
     79          while ( pos - list[cur].size > 0){
     80                pos -= list[cur].size;
     81                cur = list[cur].next;
     82          }
     83          return list[cur].str[pos - 1];//注意要-1 
     84     }
     85 }A;
     86 char str[MAXN];
     87 int n;
     88 
     89 int main() {
     90     #ifdef LOCAL
     91     freopen("data.txt",  "r",  stdin);
     92     freopen("out.txt",  "w",  stdout); 
     93     #endif
     94     scanf("%s%d", str, &n);
     95     A.init(str);//初始化块状链表
     96     for (int i = 0; i < n; i++){
     97         int pos;
     98         scanf("%s", str);
     99         if (str[0] == 'I'){//插入单个的单词 
    100            char S[2]; 
    101            scanf("%s%d", S, &pos);
    102            A.insert(pos - 1, S[0]);
    103         } else {
    104            scanf("%d", &pos);
    105            printf("%c
    ", A.find( pos ));
    106         }
    107     } 
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    spring @component的作用
    Spring 开启Annotation <context:annotation-config> 和 <context:component-scan>诠释及区别
    servlet中实现页面跳转return “r:”和return “f:
    MyEclipse中SVN的使用方法 此博文包含图片 (2012-04-19 12:18:35)
    MyEclipse使用总结——MyEclipse10安装SVN插件
    javaweb学习总结(九)—— 通过Servlet生成验证码图片
    Spring-springmvc-mybatis整合
    MyBatis连接SQLServer数据库
    mybatis入门基础(二)----原始dao的开发和mapper代理开发
    MyBatis入门基础(一)
  • 原文地址:https://www.cnblogs.com/hoskey/p/4322417.html
Copyright © 2020-2023  润新知