【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個函數:

  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的同學多交流。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM