【C++实现python字符串函数库】一:分割函数:split、rsplit
2016-01-18 16:50
666 查看
【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字符串函数库】二:字符串匹配函数startswith与endswith
- 【C++实现python字符串函数库】strip、lstrip、rstrip方法
- C++ 复制控制之复制构造函数
- C++强制类型转换操作符 static_cast
- C++强制类型转换操作符 const_cast
- C++强制类型转换操作符 dynamic_cast
- 二叉查找树 C++实现(含完整代码)
- C++ 序列式容器之vector
- C++内联函数
- C++ 合成默认构造函数的真相
- C++ 隐式类类型转换
- 深度探究C++中的函数重载的用法
- C++中 #define的用法
- C++的XML编程经验――LIBXML2库使用指南
- 关于C++ const 的全面总结
- C++中使用TinyXML2
- 最大连续子序列之和
- protobuf序列化存储
- 用gdb调C++标准库
- c++构造函数中抛出异常的用途和用法