【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. HTML 学习笔记(列表)

    HTML 列表 html中列表使用标签<ul>和 <ol>来实现,不同的行用标签<li>来实现 <li>中包含的就是列表每行的内容.列表包含有序列表&l ...

  2. 【转】TestFlight APP测试(IOS如何让上架前给其他人测试)

    原文网址:http://blog.csdn.net/dexin5195/article/details/43966571 大家都知道, 以前iOS项目要测试只需要上传到testflightapp.co ...

  3. 常见HTTP状态基本解释

    本文摘自互联网,但是忘记了具体网址,请见谅 在网站建设的实际应用中,容易出现很多小小的失误,就像mysql当初优化不到位,影响整体网站的浏览效果一样,其实,网站的常规http状态码的表现也是一样,Go ...

  4. windows和ubuntu下gif动态图片的制作

    现在社交软件中, 各种各样的动图为大家交流很大的乐趣.  Gif图片比视频小, 比静态JPG图片形象生动, 更适用于产品展示和步骤演示等. 这里简单介绍一下在window系统和ubuntu系统下gif ...

  5. AngularJS中的缓存

    欢迎大家指导与讨论 : ) 缓存篇 一个缓存就是一个组件,它可以透明地储存数据,以便以后可以更快地服务于请求.多次重复地获取资源可能会导致数据重复,消耗时间.因此缓存适用于变化性不大的一些数据,缓存能 ...

  6. web—第四章css&第五章

     web—第四章css&第五章 终于迎接等待已久的CSS,在没学这个之前,我们只会用一点img,查一点小图片,或者是用style改一下颜色,而且比较麻烦.现在多了个css在文件夹在创建一个cs ...

  7. Redis学习笔记(一)

    一.Redis入门概述 1.是什么? (1)全称:REmote DIctionary Server(远程字典服务器).是完全开源免费的,用C语言编写的, 遵守BCD协议.是一个高性能的(key/val ...

  8. WPF下制作的简单瀑布流效果

    最近又在搞点小东西,美化界面的时候发现瀑布流效果比较不错.顺便就搬到了WPF,下面是界面 我对WEB前端不熟,JS和CSS怎么实现的,我没去研究过,这里就说下WPF的实现思路,相当简单. 1.最重要的 ...

  9. 使用pngquant来压缩png资源缩小apk

    最近发现了一个叫做pngquant的工具,可以有效的压缩资源文件中的png文件,从而减小发布的apk的大小.我发现这个工具有两个特点: 1. 真无损,压缩后重新运行了我的app发现是没有任何区别的 2 ...

  10. JavaScript 10分钟入门

    JavaScript 10分钟入门 随着公司内部技术分享(JS进阶)投票的失利,先译一篇不错的JS入门博文,方便不太了解JS的童鞋快速学习和掌握这门神奇的语言. 以下为译文,原文地址:http://w ...