• 浅谈 cxx rope


    一般说的浅谈是永远不会短的 

    然后$qwq$本宝宝并不想讲实现原理 会用就行了呗    

    然后方便起见,本文规定数组$a$的第$1$位为$a[0]$

    并且本文的所有$debug$为了方便看到我们$rope$长度之后的东西,会多输出若干位(看$debug$程序就懂了)

    所以一些输出可能跟我的不一样(比较明显,显然数组越界)

    进入正题

    首先需要的头文件:

    #include<ext/rope>

    需要的命名空间

    using namespace __gnu_cxx;

    之后声明一个$rope$

    rope</*这里面是填变量类型*/> ro;

    如果命名空间是$std$的话可以这么写:

    __gnu_cxx::rope</*变量类型*/> ro;

    这里以变量类型为$int$的$rope$来举例

    前置技能是知道怎么访问:

    获取$ro$的第$i$位是$ro[i-1]$ 因为$rope$是从$0$开始的

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<ext/rope>
    using namespace std;
    __gnu_cxx::rope<int>ro;
    int n,m,p;
    void debug(int len)
    {
        for(int i=0;i<=len;i++) printf("%d %d 
    ",i,ro[i]);//输出0~len这len+1位存的是啥 
        puts("");
        return ; 
    }
    前置头文件+函数+声明

    然后是添加删除,   

        (1). $push \_ back$和$push \_ front$

        $push \_ back(n);$

        表示在当前$rope$序列最后添加一个$n$;

        $push \_ front(n)$就是在最前面啦。

        然后测试一下:

    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&m),ro.push_back(m);
        debug(n);
        return 0;
    }
    /*
    testdata.in:
    5
    1 2 3 4 5
    testdata.out:
    0 1
    1 2
    2 3
    3 4
    4 5
    5 2576(或者别的)
    */

        然后又知道了如果我们访问的第$i$位要是没赋值的话会输出随机的一个数(刚刚就是$ro[5]$我们并没有赋值)。

    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&m),ro.push_front(m);
        debug(n);
        return 0;
    }
    /*
    testdata.out
    0 5 
    1 4 
    2 3 
    3 2 
    4 1 
    5 0 (或者其它)
    */
    push_front

        然后自己动手试试就更能理解了。

       

        (2).一个极其好用的插入函数:$insert(pos,x)$表示在第$pos$位插入一个数$n$(就是第$pos$位变成$n$,之前的第$pos$和$pos$后面的依次向右移)

    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&m),ro.push_back(m);
        debug(n);
        int ll;
        scanf("%d",&ll);
        for(int i=1;i<=ll;i++) scanf("%d%d",&m,&p),ro.insert(m,p),debug(n);
        return 0;
    }
    /*
    testdata.in:
    5
    1 2 3 4 5
    1
    1 10
    testdataout:
    0 1
    1 2
    2 3
    3 4
    4 5
    5 312 (或者其他)

    0 1
    1 10
    2 2
    3 3
    4 4
    5 5
    */

        所以$insert(0,n)$就等同于$push \_ front(n)$

        然后这个$insert()$还有个好处是这玩意支持整个数组同时插入

        $insert(pos,a)$(a为一个数组名)表示将a数组整个插入(从$a[0]$开始一直插入,直到某一位为$0$,不插入值为$0$的这一位)

    int ll;int a[5]={0,0,0,0,0};
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&m),ro.push_back(m);
        scanf("%d",&ll);
        for(int i=0;i<ll;i++) scanf("%d",&a[i]);
        int pos;scanf("%d",&pos);
        ro.insert(pos,a);
        n+=ll;
        debug(n);
        return 0;
    }
    /*
    testdata1.in:
    5
    1 2 3 4 5
    3
    11 12 13
    1
    testdata1.out:
    0 1 
    1 11 
    2 12 
    3 13 
    4 2 
    5 3 
    6 4 
    7 5 
    8 0  
    */
    /*
    testdata2.in:
    5
    1 2 3 4 5
    3
    0 11 13
    1
    testdata2.out:
    0 1 
    1 2 
    2 3 
    3 4 
    4 5 
    5 0 
    6 0 
    7 0 
    8 0 
    */
    /*
    testdata3.in:
    5
    1 2 3 4 5
    3
    11 0 13
    1
    testdata3.out:
    0 1 
    1 11 
    2 2 
    3 3 
    4 4 
    5 5 
    6 0 
    7 0 
    8 0 
    */
    testdata

        通过第一个数据我们见识到了$insert$的整段插入,第二,三个数据说明了$insert$会插入到下一位是$0$的这一位。

        当然,万一我们的某些题里一定要有$0$怎么办?我们不想全部插入怎么办?

        $insert(pos,a+x,a+y)$表示将$a$数组的$a[x]$开始到$a[y-1]$位总共$y-x$位一起在$pos$插入到$rope$里。

    int ll;int a[5]={0,0,0,0,0};
    int x,y;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&m),ro.push_back(m);
    
        scanf("%d",&ll);
        for(int i=0;i<ll;i++) scanf("%d",&a[i]);
    
        scanf("%d%d",&x,&y); 
    
        int pos;scanf("%d",&pos);
    
        ro.insert(pos,a+x,a+y);
        n+=ll;
        debug(n);
        return 0;
    }
    /*
    testdata.in:
    5
    1 2 3 4 5
    4
    11 0 13 14
    1 3
    1
    testdata.out:
    0 1 
    1 0 
    2 13 
    3 2 
    4 3 
    5 4 
    6 5 
    7 0 
    8 0 
    9 0 
    */
    testdata

         

         下面开始讲删除操作

          删除的函数很少啊$……$

          $erase(pos)$一个很玄学的参数,表示从$ro[pos]$开始为第$1$位 ,往后删掉共$pos+1$位

    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&m),ro.push_back(m);
        debug(n);
        int pos;
        scanf("%d",&pos);
        ro.erase(pos);
        debug(n);
        return 0;
    }
    /*
    testdata1.in:
    6
    1 2 3 4 5 6
    0
    testdata1.out:
    0 1 
    1 2 
    2 3 
    3 4 
    4 5 
    5 6 
    6 40 (or any)
    
    0 2 
    1 3 
    2 4 
    3 5 
    4 6 
    5 1028672837 (or any) 
    6 1432107587 (or any)
    */
    /*
    testdata2.in:
    6
    1 2 3 4 5 6
    1
    testdata2.out:
    0 1 
    1 2 
    2 3 
    3 4 
    4 5 
    5 6 
    6 40 (or any) 
    
    0 1 
    1 4 
    2 5 
    3 6 
    4 0  (or any)
    5 0  (or any)
    6 0  (or any)
    
    */
    /*
    testdata3.in:
    6
    1 2 3 4 5 6
    4
    testdata3.out:
    0 1 
    1 2 
    2 3 
    3 4 
    4 5 
    5 6 
    6 40 (or any)
    
    0 1 
    1 2 
    2 3 
    3 4 
    4 1409315703 (or any)
    5 1028672837 (or any)
    6 1432107587 (or any)
    */
    testdata

    其中$(or any)$表示是或者其他值(应该是$or else$ 的吧……本宝宝的英语好菜啊)

         $erase(pos,len)$表示从$ro[pos]$开始为第$1$位,往后删掉共$len$位。

    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&m),ro.push_back(m);
        debug(n);
        int pos;int ll;
        scanf("%d%d",&pos,&ll);
        ro.erase(pos,ll);
        debug(n);
        return 0;
    }
    /*
    testdata.in:
    6
    1 2 3 4 5 6
    1 4
    testdata.out:
    0 1
    1 2
    2 3
    3 4
    4 5
    5 6
    6 40 (or else)

    0 1
    1 6
    2 6816088 (or else)
    3 0 (or else)
    4 0 (or else)
    5 0 (or else)
    6 0 (or else)
    */

     嘤嘤嘤!插入终于写完了,累死宝宝了$qwq$,歇一会,回来再更  $2018.7.9 9:54$

    本宝宝回来了$2018.7.9   10:38$


     然后就是修改替换转移了

      $copy(pos,len,&x)$其中$&x$为一个指针或者数组名(不也是一个指针么?qwq)表示将$ro[pos]$为第一位到$ro[pos+len-1]$这总共$len$位的东西赋值到$a$上(数组的话从$a[0]$开始)

      $ps: ext{本小可爱这辈子都学不会指针的}$

    int a[5]={0,0,0,0,0};
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&m),ro.push_back(m);
        debug(n);
        int pos;int ll;
        scanf("%d%d",&pos,&ll);
        ro.copy(pos,ll,a);
    //    debug(n); 看心情,反正能不开也没事
        for(int i=0;i<5;i++) printf(" %d ",a[i]);
        return 0;
    }
    /*
    testdata.in:
    6
    1 2 3 4 5 6
    1 3
    testdata.out:
    0 1 
    1 2 
    2 3 
    3 4 
    4 5 
    5 6 
    6 40 (or else)
    
     2  3  4  0  0 
    */
    testdata

      

      $replace(pos,len,x)$将$ro[pos]$为第一位到$ro[pos+len-1]$这$len$位用$x$替换,顺便删除这一段(具体看下面$debug$)

    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&m),ro.push_back(m);
        debug(n);
        int pos;int ll;int oldval,newval;
        scanf("%d%d%d",&pos,&ll,&newval);
        ro.replace(pos,ll,newval);
        debug(n);
        return 0;
    }
    /*
    testdata.in:
    6
    1 2 3 4 5 6
    1 3 11
    testdata.out:
    0 1 
    1 2 
    2 3 
    3 4 
    4 5 
    5 6 
    6 40 (or else)
    
    0 1 
    1 11 
    2 5 
    3 6 
    4 0 (or else)
    5 0 (or else)
    6 0 (or else)
    */
    testdata

      我们发现,我们在$testdata$里目的是将$1$到$3$替换成$11$然后输出中告诉我们了,我们把原先$1$到$3$的值也顺便覆盖掉了。

      其实相当于先$erase(pos,len)$然后在$insert(pos,newval)$

     

      $replace(pos,st,&x,en)$ 在$pos$插入$x$的前$en$位,其中重叠$st$位.(详见数据)

    int a[5]={0,0,0,0,0};
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&m),ro.push_back(m);
    //    debug(n);
        int pos;int len;
        scanf("%d%d",&pos,&len);
        for(int i=0;i<len;i++) scanf("%d",&a[i]);
        int st,en;
        scanf("%d%d",&st,&en);
        ro.replace(pos,st,a,en);
        debug(n+4);//多输出点看看
        return 0;
    }

    UPD:从这里起省略(or else)自己想吧 

    /*
    testdata1.in:
    6
    1 2 3 4 5 6
    2 4
    11 12 13 14
    0 1
    testdata1.out:
    0 1 
    1 2 
    2 11 
    3 3 
    4 4 
    5 5 
    6 6 
    7 0 
    8 0 
    9 0 
    10 1658256847 
    */
    /*
    testdata2.in:
    6
    1 2 3 4 5 6
    2 4
    11 12 13 14
    0 2
    testdata2.out:
    0 1 
    1 2 
    2 11 
    3 12 
    4 3 
    5 4 
    6 5 
    7 6 
    8 0 
    9 0 
    10 794409564 
    */
    /*
    testdata3.in:
    6
    1 2 3 4 5 6
    2 4
    11 12 13 14
    1 4
    testdata3.out:
    0 1 
    1 2 
    2 11 
    3 12 
    4 13 
    5 14 
    6 4 
    7 5 
    8 6 
    9 0 
    10 0 
    */
    /*
    testdata4.in:
    6
    1 2 3 4 5 6
    2 4
    11 12 13 14
    5 4
    testdata4.out:
    0 1 
    1 2 
    2 11 
    3 12 
    4 13 
    5 14 
    6 0 
    7 0 
    8 0 
    9 0 
    10 926115120 
    */
    testdata

      我们发现,当$st=0$时,相当于直接从$a$里插入长度为$en$,$st!=0$时是覆盖$st$位插入,如$testdata3$我们本应该是在$ro[6]$的$3$被覆盖掉了。

      而又如$testdata4$当覆盖的长度大于我们要加的长度的时候,原先的就会全被清除。  

      $substr(pos,x)$提取从$pos$开始$x$个。


    另外就是$rope$支持$size()$调取大小,支持$swap()$


    以上这些如果是$char$类型的话还会有彩蛋呢$……$但是一般这几个操作就够了(其实是本宝宝就知道这些了)

    然后就……

    本文完结撒花了 吧……

    希望能对大家有所帮助。

  • 相关阅读:
    js 多物体运动
    js运动 淡入淡出
    js运动 分享到
    正则 重复项最多得子项
    jq 拖拽
    jq 弹出窗口
    jq 选项卡
    jq 写法
    Codeforces 185A Plant( 递推关系 + 矩阵快速幂 )
    HDU 2604 Queuing( 递推关系 + 矩阵快速幂 )
  • 原文地址:https://www.cnblogs.com/arcturus/p/9282360.html
Copyright © 2020-2023  润新知