追随科技的脚步从未停止

必须敢于正视,然后可谓敢想,敢做!

了解更多
23
Apr

MC

sxcmods.zip

11
Apr

对于还原精灵机器实现读档、存档的脚本

读档.bat

@echo off
@echo start copy?
@taskkill /f /t /im msedge.exe
@echo A | xcopy "D:dataedgedata" "C:UserscybAppDataLocalMicrosoftEdgeUser DataDefault" /E/H/C/I
@echo A | xcopy "D:data163data" "C:UserscybAppDataLocalNetEase" /E/H/C/I
echo _ _
echo | __ | |
echo | | | | _ | |
echo | | | | / | ' / _ | |
echo | |__| | | (_) | | | | | | __/ |_|
echo |_____/ ___/ |_| |_| ___| (_)
@pause

存档

@echo start copy?
@taskkill /f /t /im msedge.exe
@echo A | xcopy "C:UserscybAppDataLocalMicrosoftEdgeUser DataDefault" "D:dataedgedata" /E/H/C/I
@echo A | xcopy "C:UserscybAppDataLocalNetEase" "D:data163data" /E/H/C/I
echo _ _
echo | __ | |
echo | | | | _ | |
echo | | | | / | ' / _ | |
echo | |__| | | (_) | | | | | | __/ |_|
echo |_____/ ___/ |_| |_| ___| (_)
pause

21
Mar

DOMoj食用手册

跳至主内容区域
赤红幻想
The Deep Red Fantasy
赤红幻想搜索
搜索
主页
首页
游戏
应用
小说
日志
辣鸡代码
漫画
文章导航← 上一篇下一篇 →
关于搭建 domjudge 还有其他一些 ICPC Tool 之类的事
发表于2021年6月2日由Vingying
(最新更新:2022.11.18)

总之看官方文档看得简直谜语人……

总结一下:有 DOMjudge 8.1.3, Judgehost, Resolver, Presentation

搭建环境:
DOMserver: Ubuntu 20.04(64) Version: 8.1.3
Judgehost: Ubuntu 20.04(64) Version: 8.1.3(下面拉的 docker 镜像,注意只有 amd64 的,没有 arm)
CDS: Ubuntu 20.04(64) Version: 2.4.727
Presentation Clients: win10(64) Version: 2.4.727
Presentation Admin: win10(64) Version: 2.3.491
Resolver: win10(64) Version: 2.4.727
打印机:HP LaserJet M1136 MFP
Win10: 需要支持 bash 环境,以及含有 jdk1.8 及以上,这里可以下载 JDK 11.0.15
下面从刚重装完系统开始一步一步搞吧(

Domjudge 8.1.3
一键脚本
先直接上个一键 bash 脚本:

mkdir /home/dom/
cd /home/dom/
sudo apt-get update
sudo apt-get upgrade
sudo apt install -y gcc g++ make zip unzip mariadb-server \
apache2 php php-cli libapache2-mod-php php-zip \
php-gd php-curl php-mysql php-json php-xml php-intl php-mbstring \
acl bsdmainutils ntp phpmyadmin python-pygments \
libcgroup-dev linuxdoc-tools linuxdoc-tools-text \
groff texlive-latex-recommended texlive-latex-extra \
texlive-fonts-recommended texlive-lang-european composer
sudo apt install -y enscript
sudo apt install -y libcurl4-gnutls-dev libjsoncpp-dev libmagic-dev
sudo phpenmod json

wget https://www.domjudge.org/releases/domjudge-8.1.3.tar.gz
tar -zxvf domjudge-8.1.3.tar.gz
cd /home/dom/domjudge-8.1.3/
sudo ./configure --prefix=/home/dom/domjudge --with-domjudge-user=root --with-baseurl=127.0.0.1
make domserver && sudo make install-domserver

sudo /home/dom/domjudge/domserver/bin/dj_setup_database -u root install

cd /home/dom/domjudge/domserver
sudo ln -s /home/dom/domjudge/domserver/etc/apache.conf /etc/apache2/conf-available/domjudge.conf
sudo a2enmod rewrite
sudo a2enconf domjudge
sudo systemctl reload apache2
sudo chown www-data:www-data -R webapp/var/*

cat /home/dom/domjudge/domserver/etc/initial_admin_password.secret
cat /home/dom/domjudge/domserver/etc/restapi.secret
Bash
最后两行显示的分别是 admin 的账号密码,和 judgehost 连接上去的密码。具体可以看后面的内容。

装好了之后,还需要手动配置一下数据库和 apache2。具体内容直接从【配置 MySQL】看即可。

环境依赖
总之官网上面说的都很谜语人,仿佛默认你都把所有依赖都装好了一样(
首先,默认已经把该换的源都换好了,就执行

sudo apt-get update
sudo apt-get upgrade
Bash
然后就开始愉快地装各种依赖了,执行

sudo apt install gcc g++ make zip unzip mariadb-server \

    apache2 php php-cli libapache2-mod-php php-zip \
    php-gd php-curl php-mysql php-json php-xml php-intl php-mbstring \
    acl bsdmainutils ntp phpmyadmin python-pygments \
    libcgroup-dev linuxdoc-tools linuxdoc-tools-text \
    groff texlive-latex-recommended texlive-latex-extra \
    texlive-fonts-recommended texlive-lang-european composer

sudo apt install enscript
Bash
执行过程中安装时选择 apache2,在建立 MySQL 时也顺便就把账号密码都搞了。接下来执行

sudo apt install libcurl4-gnutls-dev libjsoncpp-dev libmagic-dev
sudo phpenmod json
Bash
于是,你要的依赖都建好啦!

如果遇到安装过程中输入 Y 还是直接 Abort 的情况,在 install 后面加一个 -y 参数即可。

编译 DOMjudge 8.1.3
编译这一步说实话,还是搞了有一点久的……

首先需要创建一个非 root 用户,并且拥有 sudo 权限,执行

useradd -m
passwd
Bash
然后输入新用户的密码,之后

vi /etc/sudoers
Bash
里面 root 这一行下面加上一行,格式同 root 一行,只是 root 改成用户名。
下面都用 表示上面新建的用户名。

在 /home// 下面下载 DOMjudge

wget https://www.domjudge.org/releases/domjudge-8.1.3.tar.gz
Bash
然后解压:

tar -zxvf domjudge-8.1.3.tar.gz
Bash
然后

cd /home//domjudge-8.1.3/
Bash
之后就开始编译,执行如下命令:

sudo ./configure --prefix=/home//domjudge --with-domjudge-user=root --with-baseurl=127.0.0.1
make domserver && sudo make install-domserver
Bash
如果要生成更多文档,执行如下命令:

make docs && sudo make install-docs
Bash
但至少我这步失败了 233 好像是因为 python 的问题?所以这一步(指生成文档)失败了也不用管。

至此也就编译成功啦

配置数据库
sudo /home//domjudge/domserver/bin/dj_setup_database -u root install
Bash
配置 Web 服务器
cd /home//domjudge/domserver
sudo ln -s /home//domjudge/domserver/etc/apache.conf /etc/apache2/conf-available/domjudge.conf
sudo a2enmod rewrite
sudo a2enconf domjudge
sudo systemctl reload apache2
sudo chown www-data:www-data -R webapp/var/*
Bash
现在,内网的话就可以访问 http://127.0.0.1/domjudge 然后就看到如下类似界面

反正差不多就行……
此时可以用用户名 admin 和

/home//domjudge/domserver/etc/initial_admin_password.secret
HTML
内的密码来登录管理后台了。

如果是第三方服务器,比如阿里云啥的,要用公网 ip 访问的话检查一下有没有开放 80 端口。

配置 MySQL
执行:

vi /etc/mysql/conf.d/mysql.cnf
Bash
然后里面追加下面内容

[mysqld]
max_connections = 1000
max_allowed_packet = 16MB
innodb_log_file_size = 48MB
SQL
其中 max_allowed_packet 数值改成两倍于题目测试数据文件的大小,innodb_log_file_size 数值改成十倍于题目测试数据文件的大小。
若使用的是 mariadb,则 /etc/mysql/mariadb.conf.d/50-server.cnf 中 max_allowed_packet 一项也需要修改。

之后执行

sudo systemctl restart mysql
Bash
配置 Apache2
vi /etc/apache2/apache2.conf
Bash
搜索 KeepAlive 关键字,将其值设为 Off,并在其后新增一行内容:

MaxClients 1000
SQL
然后退出,执行

sudo systemctl restart apache2
Bash
之后去
/etc/php/php版本号/apache2/php.ini“ 里,需要修改的东西都在 DOMjudge 后台管理里面有个 Config checker 的东西,位置如下

根据里面的东西来改即可。

至此,DOMserver 的配置全部完毕!更多内容可以参考 https://github.com/minorcong/cn-xcpc-docs/blob/master/domserver.md

Judgehost (docker)
表示实在受不了不用 docker 直接嗯搭的折磨了……所以 Judgehost 就直接用 docker 搭算了(

下载 docker
curl -sSL https://get.daocloud.io/docker | sh
Bash
设置 cgroups
然后需要设置本机 cgroups,编辑 /etc/default/grub 文件,将下面这行

GRUB_CMDLINE_LINUX_DEFAULT=""
Bash
修改为

GRUB_CMDLINE_LINUX_DEFAULT="quiet cgroup_enable=memory swapaccount=1"
Bash
之后执行

update-grub
Bash
然后再重启机子即可,之后检查下 /proc/cmdline 里面有无对应 log,有的话就好耶~
如果没有的话,有些机子可能会被 /etc/default/grub.d/ 里面的东西覆盖,在 update-grub 可以看到 Sourcing 了哪些文件,都检查一下,凡是有 GRUB_CMDLINE_LINUX_DEFAULT 的地方都改一下即可。

运行 Judgehost
接下来就是直接在 docker 里面运行 Judgehost。命令如下:

docker run -d -it --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro --name judgehost-0 --hostname judgedaemon-0 -e DAEMON_ID=0 -e CONTAINER_TIMEZONE=Asia/Shanghai -e JUDGEDAEMON_PASSWORD= -e DOMSERVER_BASEURL= domjudge/judgehost:8.1.3
Bash
其中 domserver password 是在

/home//domjudge/domserver/etc/restapi.secret
HTML
里面,domjudge url 就是 domserver 对应的地址,最后要加个 / 符号。

如果要配置多台 Judgehost,就把上面 judgehost-0, judgedaemon-0, 对应编号一起改了,依次递增即可。如果一台机子 CPU 是多核(物理核)的话,核心编号就是 DAEMON_ID,从 0 开始编号。

然后在 domjudge 后台管理界面就应该看得到几个 Judgehost 了,像这样

好,终于把这杀千刀的 Judgehost 配置好了(

配置打印机
这次用的打印机据说有点老了,但还是能用就行。

通过 USB 连接上打印机之后,执行

sudo apt install hplip
Bash
除了与 root 用户有关的那个选项注意一下其他一路默认即可。

之后再安装

sudo apt install hplip-gui
Bash
之后在打印机连接的情况下再安装

sudo apt install hp-plugins
Bash
之后执行

sudo hp-setup
Bash
如果没有图形的界面的话,执行

sudo hp-setup -i
Bash
然后选择 USB,之后会自动寻找到该打印机,一路安装好即可。

之后去 DOMjudge 后台,找到 print_command(在 Configuration 啥的地方),里面加上一句

enscript -b [username] -a 0-10 -f Courier9 [file] 2>&1
Bash
其中 username 就是用户名,0~10 就是每次请求只打印前 10 页。

之后,找个用户来登录,就可以看到上面有个 Print,如图

就可以愉快打印啦~

之后再连接惠普系列的打印机时,就不需要配置上面这些了,即插即用

配置 ICPC Tools
注:以下的内容还未在 DOMjudge 8.1.3 测试过,都是基于 7.3.4 测试的

这是个甚么东西?主要就是用来显示一些东西用的,总的来说配好了的话还挺有那味的(

这一部分主要参照 官方文档,但这上面也有一点小错误,这里就整理下吧。

配置 CDS
CDS 又叫 Contest Data Server,主要用以比赛后台的一些管理服务,得先配置好这个才能用其他 Tools(Resolver 除外)。

首先,在 DOMjudge 后台创建一个账号,并且分配其角色为 API reader、API writer、Source code reader,记录下用户名和密码(下面用户名和密码分别称为 usercds 和 usercdspwd)。

之后,在需要运行 CDS 的机子上下载并安装 CDS(这个东西占用资源较大,不太建议把 DOMserver 和 CDS 放一起,当然机子够神的话也无所谓),链接在这里(CDS v2.4.727)。
下载好了之后解压,把 wlp 目录重命名为 cds,方便好认些。

接下来,修改 cds/usr/servers/cds/config/cdsConfig.xml,里面所有的内容替换成如下:

<!-- Set location= to a directory that the user running the CDS can write to -->
<contest location="/home/cds/contest-data" recordReactions="false">
    <!-- Set the url to the URL of your DOMjudge installation, followed by /api/contests/<cid>, where <cid> is your CID or external ID -->
    <!-- Set the user and password to the user you created in the previous step -->
    <ccs
        url="https://www.domjudge.org/demoweb/api/contests/nwerc18"
        user="cds"
        password="somepassword" />
</contest>


HTML
其中 location 替换成一个不需要 root 就能访问或者修改的目录(比如

/home//cds/contest-data
HTML
),url 就是

/api/contests/
HTML
,其中 contest cid 就是下面这个

另外还有 user 和 password,分别就对应 usercds 和 usercdspwd。

接下来修改 cds/usr/servers/cds/users.xml,里面的所有用户名不能修改,否则会很麻烦,把所有密码修改一下,为了安全(不修改也可以,但不推荐)。

接下来就可以运行(需要装 java jdk 11 或以上)

cds/bin/server start cds
Bash
来启动 CDS 了,关闭的话把 start 换成 stop 即可(没有 restart)。

之后,访问

https://:8443/
HTTP
,这里需要保证 8443 端口开放,直接就 ip:8443 即可。忽略 SSL 警告,就会看到如下界面:

点右上角 login,用 users.xml 里面 admin 的信息来登录。

至此,CDS 算是弄好啦

配置 presentation admin
这又是个甚么东西?可以看 这份文档。总之就是个屏幕显示后台管理工具,可以管理多个 Client 的屏幕显示。

这个东西可以装在任意一台电脑上,点这里下载Presentation Admin v2.3.491,并且据说在 macOS 和 Windows 下更不容易挂?

2.4.727 版本用下面的方法连不通,2.3.491 则可以,目前还没有发现原因。总之能跑就行(

我是在 Windows 下弄的,下载解压之后,在 bash 环境下在该目录内运行(没有 bash 可以装个 git)

ICPC_FONT="Microsoft Yahei" ./presAdmin.bat https://:8443/api/contests/ presAdmin
Bash
其中 presAdmin 还有其密码见 users.xml,server ip 就是上面说的那个 ip:8443。cid 则是上面所说的 contest cid。

要记得一定要加个 ICPC_FONT=”Microsoft Yahei” ,否则可能中文支持有问题。后面 ICPC Tools 所有东西都要加个这个。

之后,会出现这个界面

如果一直显示 Disconnected 就重新试一下。

配置 presentation clients
上面这张图左边一个 Client 都没有,接下来来配置。

同样,这一步我还是选择了一台 Windows 来配置的。下载地址Presentation Client v2.4.727,官方文档见 这里

Clients 2.3 版本的有 bug,会遇到可能出现 main connection 之后程序就退出且 log 没有 error。官方给的解决方法是用最新版本的 Client(即 2.4 版本)。这个时候对于一些字体或者 emoji 表情能够正常显示而 2.3 版本则不行。

之后解压,还是在 bash 环境下在该目录下运行

ICPC_FONT="Microsoft Yahei" ./client.bat https://:8443/api/contests/ presentation --name
Bash
其中 presentation 及密码见 users.xml,最后的 name 是指这台 client 的名称,可以不加。cid 同上面 contest cid。

这样执行完之后,会看到整个屏幕都是下面这个

以及 presentationAdmin 这边也多了一台 Client

然后就可以愉快体验辣(

其他的一个比较有用的参数:–display=id,即如果连了多台显示器,用这个来指定显示的显示器编号。

配置 Resolver(滚榜)
十分感谢 SYSU-Lanly,这里参考了他的博客。这里就用他的这套工具来弄。

先总结一下做了什么:一个就是最基础的滚榜,然后就是给队伍加上了照片。

一场比赛结束后,首先在 DOMjudge 上 Finalize 这场比赛,之后再来调用 resolver。

resolver 可以支持 CDP 格式的文件夹,2.4 版本之后支持的 CDP 文件夹格式如下:

.
├── config // 非必需
│ ├── contest.yaml // 从domjudge Import/export页面导出即可
│ ├── groups.tsv // 从domjudge Import/export页面导出即可
│ ├── problemset.yaml
│ └── teams.tsv // 从domjudge Import/export页面导出即可
├── contest
│ ├── banner.png // resolver无用,但在cds放置于此就可显示banner
│ └── logo.png // resolver主页面的图片&无照片队伍的默认照片
├── events.xml // 滚榜数据
├── groups // Categories照片,但在resolver似乎没起到作用
│ └── 3 // Categories的id
│ └── logo.png
├── organizations // Affiliations照片,只要某Affiliations的队伍有logo,其他同Affiliations的队伍就都是该logo
│ ├── 3000 // 该Affiliations所对应的任一队伍的icpc id
│ │ └── logo.png
│ ├── 3001
│ │ └── logo.png
│ ├── 3012
│ │ └── logo.png
│ ├── 3017
│ │ ├── country_flag.png // 照源码里是这样放置的,但在resolver似乎没起到作用
│ │ └── logo.png
│ └── 3187
│ └── logo.png
└── teams // 队伍照片

├── 3000            // 队伍的icpc id
│   └── photo.png   // 照片名字固定是photo
├── 3001
│   └── photo.png
├── 3009
│   └── photo.png
└── 3010
    └── photo.png

所以队伍照片等等直接按照上面的格式来就行…… 就只有一个 teams 文件夹带上 events.xml 就是最简单的结构了。

最主要的就是这个 events.xml 怎么生成,这里采用了 Lanly 的工具:Github – icpc-resolver-from-domjudge。剩下的直接按照这里面的流程来就行。

不过注意一点,就是配置 config.json 中,各个奖的总数之和不能超过人数。

其中的执行 ./resolver.bat 命令在 Git Bash 下运行,用如下格式:

ICPC_FONT="Microsoft Yahei" ./resolver.bat ./cdp/
Bash
如果这场比赛没有 Finalize 的话,上述命令需要在最后加一句
–test“

如果遇到 java 报 OutOfMemory 则直接修改 resolver.bat 内最后一句命令,将 -Xmx=1024m 调大,比如 -Xmx=4g 再试试。

然后就可以愉快滚榜啦,具体操作见官方文档

下面的是之前的解决方案,可以不用看了,仅作参考
这一步也是很多坑……

一场比赛结束后,首先在 DOMjudge 上 Finalize 这场比赛,之后去

http:///api/contests//event-feed?stream=false
HTML
下载 event-feed。下载完之后,加一个 .json 后缀名,之后来下载 Resolvers v2.4.727,这一步还是在 Windows 上面搞。

之后打开 awards.bat,并且在 Disk 里面找到 event-feed.json,这一步可能会提示这个

一般来说是没有 Finalize 的问题,但也有可能 Finalize 了也有这个。这里不管,点右上角 Save,保存一个 json 文件,姑且命名为 test.json。

之后仍然在 bash 环境下运行

ICPC_FONT="Microsoft Yahei" ./resolver.bat test.json --test
Bash
注意:这一步不要./resolver.sh,亲测有点问题。最后的
–test“ 是在有前面那个 Warning 的情况下加的。

如果遇到 java 报 OutOfMemory 则直接修改 resolver.bat 内最后一句命令,将 -Xmx=1024m 调大,比如 -Xmx=4g 再试试。

然后就可以愉快滚榜啦,具体操作见官方文档

References
CN-XCPC-DOCS
计算机 · DOMjudge Docker 配置
Connecting the ICPC Tools with DOMjudge
ICPC Tools
docker hub – domjudge
DOMjudge Manual 7.3
ICPCToy – DOMjudge
Lanly – 滚榜程序Resolver源码阅读

06
Mar

【ACM笔记一】STL容器

STL 容器

常用的数据结构:

数据结构说明
向量(vector)连续存储元素。底层数据结构为数组,支持快速随机访问
字符串(string)字符串处理容器
双端队列(deque)连续存储的指向不同元素的指针所组成的数组。底层数据结构为一个中央控制器和多个缓冲区,支持首尾元素(中间不能)快速增删,也支持随机访问
链表(list)有节点组成的链表,每个节点包含着一个元素。底层数据结构为双向链表,支持节点的快速增删
栈(stack)后进先出的序列。底层一般用deque(默认)或者list实现
队列(queue)先进先出的序列。底层一般用deque(默认)或者list实现
优先队列(priority_queue)元素的进出对顺序由某个谓词或者关系函数决定的一种队列。底层数据结构一般为vector(默认)或者deque
集合(set)/多重集合(multiset)由节点组成的红黑树,每个节点都包含着一个元素,set中的所有元素有序但不重复,multiset中的所有关键字有序但可以重复
映射(map)/多重映射(multimap)由(关键字,值)堆组成的集合,底层的数据结构为红黑树,map中的所有元素有序但不重复,multimap中的所有关键字有序但可以重复

3.2.什么是STL算法

STL算法是用来操作容器中数据的模板函数,STL提供了大约100个实现算法的模板函数。

例如,STL用sort()对一个vector中的数据进行排序,用find()搜索一个list中的对象。

正是由于采用模板函数设计(即泛型设计),STL算法具有很好的通用性,例如排序算法sort()不仅可以

对内置数据类型的数据(如int数据)排序,也可以对自定义的结构体数据排序,不仅可以递增排序,
也可以按照程序员指定的方式排序(如递减),从而简化代码,提高算法设计效率。

3.什么是STL迭代器

简单地说,STL迭代器用于访问容器中的数据对象。每个容器都有自己的迭代器,只有容器自己知道如何

访问自己的元素。迭代器像C/C++中的指针,算法通过迭代器来定位和操作容器中的元素。

常用的迭代器如下:

iterator:指向容器中存放元素的迭代器,用于正向遍历容器中的元素
const_iterator:指向容器中存放元素的常量迭代器,只能读取容器中的元素
reverse_iterator:指向容器中存放元素的反向迭代器,只能反向遍历容器中的元素
const_reverse_iterator:指向容器中存放元素的常量反向迭代器,只能读取容器中的元素

迭代器的常用运算如下:

++ : 正向移动迭代器
-- : 反向移动迭代器
*: 返回迭代器所指的元素值

二、常用的STL容器

STL容器很多,每一个容器就是一个类模板,大致分为顺序容器、适配器容器和关联容器3种类型。

1.顺序容器

顺序容器按照线性次序的位置存储数据,即第1个元素,第2个元素,依次类推。

STL提供的顺序容器有vector、string、deque和list。

1)vector(向量容器)

    它是一个向量类模板。向量容器相当于数组,它存储具有相同数据类型的一组元素,
    
    如下图所示为vector容器v的一般存储方式,可以从末尾快速地插入与删除元素,
    快速地随机访问元素,但是在序列中间插入、删除元素较慢,因为需要移动插入或删除位置后面地所有元素。
    如果初始分配的空间不够,当超过空间大小时会重新分配更大的的空间(通常按两倍大小扩展),
    此时需要进行大量的元素复制,从而增加性能开销。

//定义vector容器的几种方式如下:
vector<int> v1;                     // 定义元素为int的向量v1
vector<int> v2(10);                 // 指定向量v2的初始大小为10个int元素
vector<double> v3(10, 1.23);        // 指定v3的10个初始元素的初值为1.23
vector<int> v4(a, a + 5);           // 用数组 a[0, 4] 共5个元素初始化v4
    vector提供了一系列成员函数,vector的主要成员函数如下:

empty():判断当前向量是否为空
size():返回当前向量容器中的实际元素个数
[]:返回指定下标的元素
reserve(n):为当前向量容器预分配n个元素的存储空间
capacity():返回当前向量容器在重新进行内存分配以前所能容纳的元素个数
resize(n):调整当前向量容器的大小,使其可以容纳n个元素
push_back():在当前向量容器尾部添加一个元素
insert(pos, elem):在pos位置插入元素elem,即将元素elem插入到迭代器pos指定的元素之前
front():获取当前容器的第一个元素
back():获取当前容器的最后一个元素
erase():删除当前向量容器中某个迭代器或者迭代器区间指定的元素
clear():删除当前容器的所有元素
begin():引用容器的第一个元素
end():引用容器的最后一个元素后面的一个位置
rbegin():引用容器的最后一个元素
rend():引用容器的第一个元素前面的一个位置

2)string(字符串容器)

string是一个保存字符序列的容器,下图所示为string容器s的一般存储方式,
它的所有元素为字符类型,类似vector[HTMLREMOVED],因此除了有字符串的一些常用操作外,
还包含了所有序列容器的操作。常用操作包括增加,删除,查找,修改,输入,输出等。
//创建string容器的几种方式如下:

string():建立一个空串
string(const string& str):用字符串str建立当前字符串
string(const string& str, size_type idx):用字符串str起始于idx的字符建立当前字符串
string(const string& str, size_type idx, size_type num):用字符串str起始于idx的num个字符建立当前字符串
string(const char* cstr):用C-字符串cstr建立当前字符串
string(const char* cstr, size_type len):用C-字符串cstr开头的len个字符建立当前字符串
string(size_type num, char c):用num个字符c建立当前字符串

//示例:

char cstr[] = "China! Great Wall";      // C-字符串
string s1(cstr);                        // s1:China! Great Wall
string s2(s1);                          // s2:China! Great Wall
string s3(cstr, 7, 11);                 // s3:Great Wall
string s4(cstr, 6);                     // s4:China!
string s5(5, 'A');                      // s5:AAAAA

//常用函数:

empty():判断当前字符串是否为空
size():返回当前字符串的实际字符个数
length():返回当前字符串的实际字符个数
[idx]:返回当前字符串位于idx位置的元素,idx从0开始
at(idx):返回当前字符串位于idx位置的元素
append(cstr):在当前字符串末尾添加一个字符串str
insert(size_type idx, string str):在当前字符串的idx处插入一个字符串str
find(string s, size_type pos):从前字符串的pos位置开始查找s的第一个位置,找到返回位置,未找到返回-1
replace(size_type idx, size_type len, string str):将当前字符串中起始于idx的len个字符用str替换
substr(size_type idx):返回当前字符串起始于idx的子串
substr(size_type idx, size_type len):返回当前字符串起始于idx的长度为len的子串
erase():删除字符串的所有字符
clear():删除字符串的所有字符
erase(size_type idx):删除字符串从idx开始的所有字符

3)deque(双端队列容器)

双端队列容器由若干个块构成,每个块中元素的地址是连续的,块之间的地址是不连续的。

可以从前面或后面快速的插入与删除元素,并可以快速的随机访问元素,但在中间位置插入和删除元素较慢。

定义deque的几种方式:
deuqe<int> dq1;                                 // 定义元素为int的双端队列dq1
deque<int> dq2(10);                             // 指定dq2的初始大小为10个int元素
deque<double> dq3(10, 1.23);                    // 指定dq3的10个初始元素的初值为1.23
deque<int> dq4(dq2.degin(), dq2.end());         // 用dq2 的所有元素初始化dq4
empty():判断双端队列是否为空
size():返回双端队列的元素个数
front():取队头元素
back():取队尾元素
push_front(elem):在队头插入元素elem
push_back(elem):在队尾插入元素elem
pop_front(elem):删除队头一个元素
pop_back(elem):删除队尾一个元素
erase():从双端队列中删除一个或几个元素
clear():删除双端队列的所有元素
begin():引用容器的第一个元素
end():引用容器的最后一个元素后面的一个位置
rbegin():引用容器的最后一个元素
rend():引用容器的第一个元素前面的一个位置

4)list(链表容器)

可从任何地方快速插入与删除。每个节点通过指针链接,不能随机访问元素,为了访问特定的元素,
必须从第一个元素位置(表头)开始,随指针从一个元素到下一个元素,直到找到。

//定义list的几种方式:

list<int> l1;                   // 定义元素为int的链表l1
list<int> l2(10);               // 指定链表l2的初始大小为10个int元素
list<double> l3(10, 1.23);      // 指定dq3的10个初始元素的初值为1.23
list<int> l4(a, a + 5);         // 用数组 a[0,·· 4] 共5个元素初始化l4
empty():判断链表是否为空
size():返回链表的元素个数
push_back():在链表尾部插入元素
pop_back():删除链表的最后一个元素
remove():删除链表中所有指定值的元素
erase():从链表中删除一个或几个元素
unique():删除链表中相邻的重复元素
clear():删除链表的所有元素
insert(pos, elem):在pos位置插入元素elem
insert(pos, n, elem):在pos位置插入n个元素elem
reverse():反转链表
sort():对链表中的元素排序
begin():引用容器的第一个元素
end():引用容器的最后一个元素后面的一个位置
rbegin():引用容器的最后一个元素
rend():引用容器的第一个元素前面的一个位置

2.关联容器

关联容器中的每个元素有一个key(关键字),通过key来存储和读取元素。这些关键字可能与元素在容器中的位置无关,所以关联容器不提供顺序容器中的front(), push_front(), back(), push_back()以及pop_back()操作。

1)set(集合容器)/multiset(多重集合容器)

set和multiset都是集合类模板,其元素称为关键字。set的关键字是唯一的,multiset的关键字可以不唯一,

而且默认情况下会对元素按关键字自动升序排列,所以查找速度较快。

empty():判断容器是否为空
size():返回容器中的实际元素个数
insert():插入元素
erase():从容器中删除一个或几个元素
clear():删除所有元素
count(k):返回容器中关键字k出现的次数
find(k):如果存在k, 返回该元素的迭代器,否则返回end()值
upper_bound():返回一个迭代器,指向关键字大于k的第一个元素
upper_bound():返回一个迭代器,指向关键字不小于k的第一个元素
begin():用于正向迭代,返回容器的第一个元素
end():用于正向迭代,返回容器的最后一个元素后面的一个位置
rbegin():用于反向迭代,返回容器的最后一个元素
rend():用于反向迭代,返回容器的第一个元素前面的一个位置

2)映射(map)/多重映射(multimap)

set和multiset都是映射类模板,映射是实现关键字与值关系的存储结构,可以使用一个关键字key来访问相应的数据值value。set/multiset中的key和value都是key类型,而set/multiset中的key和value是一个pair类结构。

    pair类结构的声明如下:

struct pair {
    T first;
    T second;
}

pair有两个分量(二元组),first为第一个分量(在map对应key),second为第二个分量(在map对应value)。

empty():判断容器是否为空
size():返回容器中的实际元素个数
map[key]:返回关键字key的元素的引用,如果不存在,则以key为关键字插入一个元素(不适合multimap)
insert(elem):插入一个元素elem并返回该元素的位置
clear():删除所有元素
count():容器中指定关键字的元素个数(map中只有1或0)
find():在容器中查找元素
begin():用于正向迭代,返回容器的第一个元素
end():用于正向迭代,返回容器的最后一个元素后面的一个位置
rbegin():用于反向迭代,返回容器的最后一个元素
rend():用于反向迭代,返回容器的第一个元素前面的一个位置

3.适配器容器

适配器容器是指基于其他容器实现的容器。

1)stack(栈容器)

后进先出。默认底层容器是deque.
stack容器只有一个出口,即栈顶,可以在栈顶插入(进栈)和删除(出栈)元素,而不允许顺序遍历。

empty():判断栈是否为空
size():返回栈的实际元素个数
push(elem):元素elem进栈
top():返回栈顶
pop():元素出栈

2)queue(队列容器)

先进先出,不允许顺序遍历

empty():判断队列是否为空
size():返回队列的实际元素个数
front():返回队头元素
back():返回队尾元素
push(elem):元素elem进队
pop():元素出队

3)priorityqueue(优先队列容器)

优先队列是一种受限访问操作的存储结构,元素可以以任意顺序进入优先队列。

empty():判断优先队列是否为空
size():返回优先队列的实际元素个数
push(elem):元素elem进队
top():获取队头元素
pop():元素出队

28
Aug

一个人读书的本意是什么?

这个问题不是问你读书的目的,而是本意,我认为,读书的本意就是四句话,为天地立兴,为生民立命,为往圣继绝学,为万世开太平