【C++实现python字符串函数库】一:分割函数:split、rsplit
【C++实现python字符串函数库】split()与rsplit()方法
前言
本系列文章将介绍python提供的字符串函数,并尝试使用C++来实现这些函数。这些C++函数在这里做单独的分析,最后我们将把这些函数放在命名空间中,真正作为一个函数库来使用。
本节内容
在本节,我们将实现两个python字符串分割函数。这两个函数的函数原型为:
split(spe = None,maxsplit= -1)
rsplit(spe= None ,maxsplit = -1)
这两个方法使用参数spe作为分隔符,将字符串切割成指定的maxsplit段,并以列表的形式返回切割后的字符串。默认的分隔符是空格,默认情况下对所有的分隔符进行分割:
>>>
>>> s = "I'm not to see you"
>>> s.split()
["I'm", 'not', 'to', 'see', 'you']
>>>
>>> s.rsplit()
["I'm", 'not', 'to', 'see', 'you']
>>>
可以看到字符串根据空格进行分割,分割成的各段作为列表的元素组成了列表并返回。
我们再来看更多的例子:
分隔成指定段数
>>>
>>> s = 'aaaaaaaaaaa'
>>> s.split('a',2) #依据'a'进行分割,最大分割数为2(分割两次)
['', '', 'aaaaaaaaa']
>>>
>>>
>>> s.split('a',1000)#分隔数偏多
['', '', '', '', '', '', '', '', '', '', '', '']
>>>
>>>
>>> s.split('a',-19)#分割数为负数
['', '', '', '', '', '', '', '', '', '', '', '']
>>>
split方法从左至右处理字符串,而rsplit方法从右至左处理字符串:
>>> ##两个方法的区别
>>> s
'aaaaaaaaaaa'
>>> s.split('a',2)
['', '', 'aaaaaaaaa']
>>> s.rsplit('a',2)
['aaaaaaaaa', '', '']
>>>
C++实现
我们使用容器vector来保存字符串分割后的元素。尽管我们的目标是实现split与rsplit这两个函数,但是模块化的思想促使我们定义出以下这5个函数:
- reverse_strings :用于rsplit_whitepace与rsplit函数。
- split_whitespace :用于split调用,以空格作为分隔符对整个字符串做分隔处理(默认)
- rsplit_whitespace :用于 rsplit调用,以空格作为分隔符对整个字符串做分隔处理(默认)
- split 我们所期待的函数
- rsplit 我们所期待的函数
在函数的实现中,我们会调用到C++容器提供的一些接口:vector容器的push_back,substr等。
头文件与宏定义
在这两个函数的实现中,我们需要如下头文件与宏定义:
#include<vector>
#include<string>
#define MAX_32BIT_INT 2147483467
倒序函数reverse_strings
这个函数提供给rsplit函数使用。具体使用继续向下看。
//采用std的swap函数
void reverse_strings(std::vector< std::string > & result)
{
for (std::vector< std::string >::size_type i = 0; i < result.size() / 2; i++)
{
std::swap(result[i], result[result.size() - 1 - i]);
}
}
spilt()方法默认情况下处理函数:split_whitespace
void split_whitespace(const std::string &str, std::vector<std::string> &result, int maxsplit)
{
std::string::size_type i, j, len = str.size();
for (i = j = 0; i < len;)
{
while (i < len&&::isspace(str[i]))
i++;
j = i;
while (i < len&&!::isspace(str[i]))
i++;
if (j < i)
{
if (maxsplit-- <= 0)
break;
result.push_back(str.substr(j, i - j));
while (i < len&&::isspace(str[i]))
i++;
j = i;
}
}
if (j < len)
{
result.push_back(str.substr(j, len - j));
}
}
split()函数
void split(const std::string &str, std::vector<std::string>&result, const std::string &sep, int maxslit)
{
result.clear();
if (maxslit < 0)
maxslit = MAX_32BIT_INT; //MAX_32BIT_INT是自己定义的一个整数,当maxslit为负数时,对整个字符串做切割处理
//split函数默认为空格为分隔符
if (sep.size() == 0)
{
//调用函数进行空格切割
split_whitespace(str, result, maxslit);
return;
}
std::string::size_type i, j, len = str.size(), n = sep.size();
i = j = 0;
while (i + n <= len)
{
if (str[i] == sep[0] && str.substr(i, n)== sep)
{
if (maxslit-- <= 0)
break;
result.push_back(str.substr(j, i - j));
i = j = i + n;
}
else
i++;
}
//剩下部分
result.push_back(str.substr(j, len - j));
}
rsplit()方法默认情况处理函数
void rsplit_whitespace(const std::string &str, std::vector<std::string>&result, int maxsplit)
{
std::string::size_type i,j,len = str.size();
for (i = j = len; i > 0;)
{
while (i > 0 && ::isspace(str[i - 1]))
i--;
j = i;
while (i > 0 && !::isspace(str[i - 1]))
i--;
if (j > i)
{
if (maxsplit-- <= 0)
break;
result.push_back(str.substr(i, j - i));
while (i > 0 && ::isspace(str[i - 1]))
i--;
j = i;
}
}
if (j > 0)
{
result.push_back(str.substr(0, j));
}
reverse_strings(result);
}
rsplit()函数
void rsplit(const std::string &str, std::vector<std::string>&result, const std::string &sep, int maxsplit)
{
if (maxsplit < 0)
{
split(str, result, sep, maxsplit);
return;
}
result.clear();
if (sep.size() == 0)
{
rsplit_whitespace(str, result, maxsplit);
return;
}
std::string::size_type i, j;
std::string::size_type len = str.size();
std::string::size_type n = sep.size();
i = j = len;
while (i >= n)
{
if (str[i - 1] == sep[n - 1] && str.substr(i - 1, n) == sep)
{
if (maxsplit-- <= 0)
break;
result.push_back(str.substr(i, n));
i = j = i - n;
}
else
{
i--;
}
}
result.push_back(str.substr(0, j));
reverse_strings(result);
}
测试
string s = "I'm not to see you";
vector<string> result;
string sep = " ";
split(s,result,sep,10);
结果:
string b = "abc abc abc abc";
vector<string>result;
string sep = "a";
split(b, result, sep, 2);
for (int i = 0; i < result.size(); i++)
cout << result[i] << endl;
结果:
string b = "abc abc abc abc";
vector<string>result;
string sep = "a";
rsplit(b, result, sep, 2);
for (int i = 0; i < result.size(); i++)
cout << result[i] << endl;
结果:
感谢耐心看完,如果有错误的地方,恳请指出。希望喜欢C++与python的同学多交流。
【C++实现python字符串函数库】一:分割函数:split、rsplit的更多相关文章
- python字符串——"奇葩“的内置函数
一.前言 python编程语言里的字符串与我们初期所学的c语言内的字符串还是有一定不同的,比如python字符串里的内置函数就比语言的要多得多:字符串内的书写格式也会有一点差异,例:字符串内含有引 ...
- [Python学习] python 科学计算库NumPy—tile函数
在学习knn分类算法的过程中用到了tile函数,有诸多的不理解,记录下来此函数的用法. 函数原型:numpy.tile(A,reps) #简单理解是此函数将A进行重复输出 其中A和reps都是ar ...
- python 字符串转16进制函数
需要用python处理16进制的文本,比如像下面这个文本 40 80 C0 40 80 C0 40 80 C0 40 80 C0 40 BF CC 40 80 C0 40 80 C0 40 80 C0 ...
- Python利用PyExecJS库执行JS函数
在Web渗透流程的暴力登录场景和爬虫抓取场景中,经常会遇到一些登录表单用DES之类的加密方式来加密参数,也就是说,你不搞定这些前端加密,你的编写的脚本是不可能Login成功的.针对这个问题,现在有 ...
- Python的Requests库基本方法函数
一.Requests 库的七个常用函数: 1. requests.request(method,url,**kwargs) :method:请求方式,对应get/put/post等七种 :拟获取页面的 ...
- python中BeautifulSoup库中find函数
http://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html#contents 简单的用法: find(name, at ...
- discuz核心函数库function_core的函数注释
/** * 系统错误处理 * @param <type> $message 错误信息 * @param <type> $show 是否显示信息 * @param <typ ...
- 苹果浏览器Safari对JS函数库中newDate()函数中的参数的解析中不支持形如“2020-01-01”形式
苹果浏览器safari对new Date('1937-01-01')不支持,用.replace(/-/g, "/")函数替换掉中划线即可 如果不做处理,会报错:invalid da ...
- [Python学习笔记][第四章Python字符串]
2016/1/28学习内容 第四章 Python字符串与正则表达式之字符串 编码规则 UTF-8 以1个字节表示英语字符(兼容ASCII),以3个字节表示中文及其他语言,UTF-8对全世界所有国家需要 ...
- PHP用mb_string函数库处理与windows相关中文字符
昨天想批处理以前下载的一堆文件,把文件里的关键内容用正则匹配出来,集中处理.在操作文件时遇到一个问题,就是windows操作系统中的编码问题. 我们都知道windows中(当然是中文版),文件名和文件 ...
随机推荐
- li标签包含img的问题
我们在制作页面时,经常有可能碰到这样的设计: li 图一 图一的布局代码如下: <ul> <li><img src=”pic1.jpg” />& ...
- django复习笔记1:环境配置
一.IDE 推荐使用sublime安装djaneiro插件. 1.安装方式 package control中搜索djaneiro 支持补全请参考:Django support for Sublime ...
- MySQL触发器如何正确使用
MySQL触发器如何正确使用 2010-05-18 15:58 佚名 博客园 字号:T | T 我们今天主要向大家介绍的是MySQL触发器进行正确使用,其中包括对MySQL触发器发器的语句创建,触发时 ...
- C#开发中Windows域认证登录2(扩展吉日嘎拉GPM系统)
原文地址:http://www.cuiwenyuan.com/shanghai/post/Windows-AD-Logon-Intergrated-into-Jirigala-GPM-DotNet-B ...
- pip安装包报错:Microsoft Visual C++ 9.0 is required Unable to find vcvarsall.bat
pip安装包报错:Microsoft Visual C++ 9.0 is required Unable to find vcvarsall.bat Windows7下pip安装包报错:Microso ...
- ORA-28000: the account is locked-的解决办法
ORA-28000: the account is locked第一步:使用PL/SQL,登录名为system,数据库名称不变,选择类型的时候把Normal修改为Sysdba;第二步:选择myjob, ...
- 简单高效的nodejs爬虫模型
这篇文章讲解一下yunshare项目的爬虫模型. 使用nodejs开发爬虫很简单,不需要类似python的scrapy这样的爬虫框架,只需要用request或者superagent这样的http库就能 ...
- 重拾Blog
上个月是我入职现在的公司三周年的月份,所以又续订了五年的合同,最近有一些思考,也不知道这个五年能否还会一直在这个公司工作. 一切随缘吧. 闲适有毒,忙碌的时光总是过的很快,自从加入这个公司以来,日常的 ...
- [bzoj2286][Sdoi2011]消耗战(虚树上的DP)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2286 分析:对于普通的树形dp:f[x]=min(∑f[son],m[x]),其中f[ ...
- [Offer收割]编程练习赛5-1 小Ho的防护盾
#1357 : 小Ho的防护盾 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho的虚拟城市正在遭受小Hi的攻击,小Hi用来攻击小Ho城市的武器是一艘歼星舰,这艘歼星 ...