浅谈 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=;i<=len;i++) printf("%d %d \n",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=;i<=n;i++) scanf("%d",&m),ro.push_back(m);
debug(n);
return ;
}
/*
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=;i<=n;i++) scanf("%d",&m),ro.push_front(m);
debug(n);
return ;
}
/*
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=;i<=n;i++) scanf("%d",&m),ro.push_back(m);
debug(n);
int ll;
scanf("%d",&ll);
for(int i=;i<=ll;i++) scanf("%d%d",&m,&p),ro.insert(m,p),debug(n);
return ;
}
/*
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[]={,,,,};
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&m),ro.push_back(m);
scanf("%d",&ll);
for(int i=;i<ll;i++) scanf("%d",&a[i]);
int pos;scanf("%d",&pos);
ro.insert(pos,a);
n+=ll;
debug(n);
return ;
}
/*
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[]={,,,,};
int x,y;
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&m),ro.push_back(m);
scanf("%d",&ll);
for(int i=;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 ;
}
/*
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=;i<=n;i++) scanf("%d",&m),ro.push_back(m);
debug(n);
int pos;
scanf("%d",&pos);
ro.erase(pos);
debug(n);
return ;
}
/*
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=;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 ;
}
/*
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:\text{本小可爱这辈子都学不会指针的}$
int a[]={,,,,};
int main()
{
scanf("%d",&n);
for(int i=;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=;i<;i++) printf(" %d ",a[i]);
return ;
}
/*
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=;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 ;
}
/*
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[]={,,,,};
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&m),ro.push_back(m);
// debug(n);
int pos;int len;
scanf("%d%d",&pos,&len);
for(int i=;i<len;i++) scanf("%d",&a[i]);
int st,en;
scanf("%d%d",&st,&en);
ro.replace(pos,st,a,en);
debug(n+);//多输出点看看
return ;
}
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$类型的话还会有彩蛋呢$……$但是一般这几个操作就够了(其实是本宝宝就知道这些了)
然后就……
本文完结撒花了 吧……
希望能对大家有所帮助。
浅谈 cxx rope的更多相关文章
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈SQL注入风险 - 一个Login拿下Server
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
- 浅谈WebService的版本兼容性设计
在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...
- 浅谈angular2+ionic2
浅谈angular2+ionic2 前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别. 1. 项目所用:angular2+ionic2 ...
- iOS开发之浅谈MVVM的架构设计与团队协作
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- Linux特殊符号浅谈
Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...
- 浅谈Angular的 $q, defer, promise
浅谈Angular的 $q, defer, promise 时间 2016-01-13 00:28:00 博客园-原创精华区 原文 http://www.cnblogs.com/big-snow/ ...
随机推荐
- 前端自动化之ts编译
前端自动化之ts编译 gulp引用包:gulp-tsc gulpfiles.js代码: var typescript = require('gulp-tsc'); gulp.task('compile ...
- python学习——练习题(1)
""" 题目:有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? """ import itertools d ...
- BurpSuite—-Sequencer模块(定序器)
一.简介 Burp Sequencer是一种用于分析数据项的一个样本中的随机性质量的工具.你可以用它来测试应用程序的session tokens(会话tokens)或其他重要数据项的本意是不可预测的, ...
- Lucene Payload 的研究与应用
Payload (元数据) 诞生于 Lucene 的2.2 版本,它是在 Lucene 2.1 索引文件格式的基础上扩展而来,提供了一种可以灵活配置的高级索引技术,在某些特定应用场景下能优化基于 Lu ...
- C++获取时间并命名为文件名
#include <time.h> char pStrPath1[20];time_t currTime;struct tm *mt;Mat saveImg1; currTime = ti ...
- 面向对象property属性、静态方法和类方法
一.property属性 1.什么是property特性? property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值. from math import pi class Circl ...
- Part5核心初始化_lesson4---关闭中断
1.关闭cpsr寄存器里面的I(中断)和F(快速中断)位: 2.设置中断屏蔽寄存器. 针对2440: 这是中断处理过程,当有中断源(没有子中断源)来的时候,它会把这个中断记录在SRCPND里面:它还要 ...
- 实践作业3:白盒测试----开始测试用例的设计DAY3
白盒测试与黑盒测试很大不同之处在于白盒测试必须读相应代码,对代码有一定了解的情况下针对代码的逻辑进行测试用例的设计.白盒测试有六种覆盖标准:语句覆盖.判定覆盖.条件覆盖.判定/条件覆盖.条件组合覆盖和 ...
- Jmeter跨线程组调用token
BeanShell PostProcessor使用 1.正则提取token后添加:后置处理器-->BeanShell PostProcessor 2.BeanShell PostProcesso ...
- Java IO输入输出流 FileWriter 字符流
字节缓冲流 //为什么要使用包装流,使用包装流是为了提高读写操作的性能. public class Packing_flowDemo { public static void main(String[ ...