【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. Git管理项目实例说明-记录和跟踪项目

    假设一个HTML项目,使用Git来记录和跟踪这个项目,包括以下内容:1)创建版本库.2)添加与修改文件.3)创建新分支.4)打标签并整理版本库.5)克隆版本库. 1.创建版本库 Creating a ...

  2. Python的高级特性11:拓展基本数据类型(dict)

    字典的创建有两种方式,如果出现In [26]这样的赋值方式就会报错. In [17]: s['name'] = 'alex' In [18]: s['sex'] = 'male' In [19]: s ...

  3. Hibernate总结2 API和配置文件

    1,Configuration 配置 获取config配置文件的方法 Configuration cfg = new Configuration(); cfg.下面的方法 configure() co ...

  4. ASP.NET Repeater 绑定 DropDownList Calendar 选择日期

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  5. ubuntu12.04禁止单用户本地无密码root登录

    1)grub-mkpasswd-pbkdf2 拿到类似grub.pbkdf2.sha512.10000.C093FE6825CDCC2F84934ABC406445E92EE098733C60E6D1 ...

  6. 离线安装 Cloudera ( CDH 5.x )

    要配置生产环境前,最好严格按照官方文档/说明配置环境.比如,官方说这个安装包用于RETHAT6, CENTOS6,那就要装到6的版本下,不然很容易出现各种各样的错. 配置这个CDH5我入了很多坑,最重 ...

  7. Spring Security授权 AccessDecisionManager

    Spring Security授权 AccessDecisionManager 博客分类: Security Spring   在前面那篇博客有一段配置: <http auto-config=& ...

  8. 如何在 Apache 中为你的网站设置404页面

    一个好的网站,拥有一个好的 404页面 是标配. 为何要有 404页面?如何设置一个 404页面? why 404 pages? 在本地,比如我打开 localhost/fuck.htm(该文件不存在 ...

  9. Hashtable Dictionary List 谁效率更高

    一 前言 很少接触HashTable晚上回来简单看了看,然后做一些增加和移除的操作,就想和List 与 Dictionary比较下存数据与取数据的差距,然后便有了如下的一此测试, 当然我测的方法可能不 ...

  10. [CF#250 Div.2 D]The Child and Zoo(并查集)

    题目:http://codeforces.com/problemset/problem/437/D 题意:有n个点,m条边的无向图,保证所有点都能互通,n,m<=10^5 每个点都有权值,每条边 ...