【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个函数:

  1. reverse_strings :用于rsplit_whitepace与rsplit函数。
  1. split_whitespace :用于split调用,以空格作为分隔符对整个字符串做分隔处理(默认)
  1. rsplit_whitespace :用于 rsplit调用,以空格作为分隔符对整个字符串做分隔处理(默认)
  1. split 我们所期待的函数
  1. rsplit 我们所期待的函数

在函数的实现中,我们会调用到C++容器提供的一些接口:vector容器的push_backsubstr等。

头文件与宏定义

在这两个函数的实现中,我们需要如下头文件与宏定义:

#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的更多相关文章

  1. python字符串——"奇葩“的内置函数

      一.前言 python编程语言里的字符串与我们初期所学的c语言内的字符串还是有一定不同的,比如python字符串里的内置函数就比语言的要多得多:字符串内的书写格式也会有一点差异,例:字符串内含有引 ...

  2. [Python学习] python 科学计算库NumPy—tile函数

    在学习knn分类算法的过程中用到了tile函数,有诸多的不理解,记录下来此函数的用法.   函数原型:numpy.tile(A,reps) #简单理解是此函数将A进行重复输出 其中A和reps都是ar ...

  3. 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 ...

  4. Python利用PyExecJS库执行JS函数

      在Web渗透流程的暴力登录场景和爬虫抓取场景中,经常会遇到一些登录表单用DES之类的加密方式来加密参数,也就是说,你不搞定这些前端加密,你的编写的脚本是不可能Login成功的.针对这个问题,现在有 ...

  5. Python的Requests库基本方法函数

    一.Requests 库的七个常用函数: 1. requests.request(method,url,**kwargs) :method:请求方式,对应get/put/post等七种 :拟获取页面的 ...

  6. python中BeautifulSoup库中find函数

    http://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html#contents 简单的用法: find(name, at ...

  7. discuz核心函数库function_core的函数注释

    /** * 系统错误处理 * @param <type> $message 错误信息 * @param <type> $show 是否显示信息 * @param <typ ...

  8. 苹果浏览器Safari对JS函数库中newDate()函数中的参数的解析中不支持形如“2020-01-01”形式

    苹果浏览器safari对new Date('1937-01-01')不支持,用.replace(/-/g, "/")函数替换掉中划线即可 如果不做处理,会报错:invalid da ...

  9. [Python学习笔记][第四章Python字符串]

    2016/1/28学习内容 第四章 Python字符串与正则表达式之字符串 编码规则 UTF-8 以1个字节表示英语字符(兼容ASCII),以3个字节表示中文及其他语言,UTF-8对全世界所有国家需要 ...

  10. PHP用mb_string函数库处理与windows相关中文字符

    昨天想批处理以前下载的一堆文件,把文件里的关键内容用正则匹配出来,集中处理.在操作文件时遇到一个问题,就是windows操作系统中的编码问题. 我们都知道windows中(当然是中文版),文件名和文件 ...

随机推荐

  1. Oracle死锁查询及处理

    一.数据库死锁的现象程序在执行的过程中,点击确定或保存按钮,程序没有响应,也没有出现报错.二.死锁的原理当对于数据库某个表的某一列做更新或删除等操作,执行完毕后该条语句不提交,另一条对于这一列数据做更 ...

  2. Castle.Net 基本应用

    什么是Castle Castle是针对.NET平台的一个开源项目,从数据访问框架ORM到IOC容器,再到WEB层的MVC框架.AOP,基本包括了整个开发过程中的所有东西,为我们快速的构建企业级的应用程 ...

  3. SQL server 专业词汇

    sql组成:DDL:数据库模式定义语言,关键字:createDML:数据操纵语言,关键字:Insert.delete.updateDCL:数据库控制语言 ,关键字:grant.removeDQL:数据 ...

  4. css3 box-sizing属性

    个人总结: 如果需要兼容IE6 IE7,使用content-box.现在流行bootstrap3,需注意它使用的是border-box. box-sizing属性可以为三个值之一:content-bo ...

  5. AngularJS中的身份验证

    欢迎大家指导与讨论 : )  一.  身份验证的意义  首先呢,网络应用的身份验证的意图在于:保护网站中的重要资源.基于某些原因这些资源并不能公开,比如付费资源(交过钱的用户才能上的网络课程),或者一 ...

  6. Linux 信号详解二(信号分类,信号处理,kill)

    信号分类 信号分为可靠信号和不可靠信号 不可靠信号的缺点 ①:处理完信号,需要重新再注册信号:②信号可能丢失. Linux已经对缺点①做了优化,现在的不可靠问题主要指的是信号可能丢失 信号还可以分为实 ...

  7. 【转】如何拿到半数面试公司Offer——我的Python求职之路

    原文地址 从八月底开始找工作,短短的一星期多一些,面试了9家公司,拿到5份Offer,可能是因为我所面试的公司都是些创业性的公司吧,不过还是感触良多,因为学习Python的时间还很短,没想到还算比较容 ...

  8. 【Android测试】【随笔】Android Studio环境搭建

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/5482778.html 随着Android Studio的推 ...

  9. 在nodeJs的Express框架下用TypeScript编写router路由出现import关键字错误的解决方案

    问题出现场景 在项目中采用nodejs做中间层,做页面的首屏渲染,同时采用express作为主web框架,其中express的router页面路由我采用ts语言来编写.如下: //page.ts 文件 ...

  10. Xamarin Android -创建Splash Screen (一)

    ......(空话少说) Xamarin 开发的技术资料很少,通过学习,把自己的学习过程及其中碰到的问题与大家分享. Splash Screen 就是在应用程序启动时,出现的一张图片,一般App的Sp ...