有穷自动机实现拆分字符串为vector

拆分字符串为vector

字符串分割,在网上看到几种方法https://www.jb51.net/article/55954.htm
1 使用strtok分割

//借助strtok实现split
#include 
#include  
int main()
{
char s[] = "Golden Global View,disk * desk";
const char* d = " ,*";
char* p;
p = strtok(s, d);
while (p)
{
printf("%s\n", p);
p = strtok(NULL, d);
}
return 0;
}

但是 strtok 在高版本的vs 中需要定义 _CRT_NON_CONFORMING_WCSTOK才能使用,而且在内部实现有
_SECURE_VERSION版本和非安全版本,非安全版本多线程同时访问会可能会发生问题。
2 用STL进行字符串的分割

//字符串分割函数
std::vector split(std::string str, std::string pattern)
{
	std::string::size_type pos;
	std::vector result;
	str += pattern;//扩展字符串以方便操作
	int size = str.size();

	for (int i = 0; i < size; i++)
	{
		pos = str.find(pattern, i);
		if (pos < size)
		{
			std::string s = str.substr(i, pos - i);
			result.push_back(s);
			i = pos + pattern.size() - 1;
		}
	}
	return result;
}

这个例子没有考虑多个拆分符的情况
3 使用boost 库
这种情况不贴代码了,就是库的使用,boost太大,不喜欢

这里再介绍一种方法
根据基本的有穷自动机
有穷自动机实现拆分字符串为vector_第1张图片

  • 我们实现对分隔符的处理
  • 0 是初始状态
  • 1 的时候接收到一个普通字符
  • 2 是结束状态
  • 处理分隔符在 状态1->0跳转的时候处理,保存字符串
  • 从0-2 从 1->2 是退出
  • 下面贴代码
template
bool in_string(T c, const T* str)
{
	while (*str)
	{
		if (*str++ == c)
		{
			return true;
		}
	}
	return false;
}
void split_string(
	string& roldids,
	string& split_str,
	vector& vec)
{
	int i = 0;
	int pos = -1;
	char c = 0;
	int stat = 0;
	while (true)
	{
		char c = roldids[i];
		switch (stat)
		{
		case 0:
		{
			if (!in_string(c, split_str.data()))
			{
				stat = 1;
				pos = i;
			}
			if (c == 0)
			{
				return;
			}

			break;
		}
		case 1:
			if (in_string(c, split_str.data()) || (c == 0 && pos != roldids.size() - 1))
			{
				string s;
				s.insert(s.begin(), roldids.begin() + pos, roldids.begin() + i);
				vec.push_back(s);
				stat = 0;
			}
			if (c == 0)
			{
				return;
			}
			break;
		}
		i++;
	}
}
  • 上面代码就是拆分函数,输出到vector中去
  • 下面是测试函数
int main()
{
	//测试用例
	//1 使用一种分割符 3 个测试用例
	//2 使用混合分隔符
	//3 分割符在最前
	//4 分割符在最后
	//5 分隔符凑在一起
	string s = "hello,welcome,to beijing,欢迎到中国来;啦啦啦";
	string split_str = ", ;";
	vector vec;

	split_string(s, split_str, vec);

	s = ",; hello,welcome,to,beijing, ; ";

	vec.clear();

	split_string(s, split_str, vec);
	return 0;
}
  • 仅仅使用了有穷自动机画了个简单的图就搞定了。如果使用正则表达式的库或许威力更大,但是少了些乐趣。
  • 下面完整代码
// 各种类型转字符串.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include 
#include 
#include 
#include 
#include 
#include       // std::setw
#include 
using namespace std;
std::string to_utf8(int32_t v)
{
	char b[8] = {};
	_itoa_s(v, b, 10);
	return b;
}
template
bool in_string(T c, const T* str)
{
	while (*str)
	{
		if (*str++ == c)
		{
			return true;
		}
	}
	return false;
}

void split_string(
	string& roldids,
	string& split_str,
	vector& vec)
{
	int i = 0;
	int pos = -1;
	char c = 0;
	int stat = 0;
	while (true)
	{
		char c = roldids[i];
		switch (stat)
		{
		case 0:
		{
			if (!in_string(c, split_str.data()))
			{
				stat = 1;
				pos = i;
			}
			if (c == 0)
			{
				return;
			}

			break;
		}
		case 1:
			if (in_string(c, split_str.data()) || (c == 0 && pos != roldids.size() - 1))
			{
				string s;
				s.insert(s.begin(), roldids.begin() + pos, roldids.begin() + i);
				vec.push_back(s);
				stat = 0;
			}
			if (c == 0)
			{
				return;
			}
			break;
		}
		i++;
	}
}

int main()
{
	//测试用例
	//1 使用一种分割符 3 个测试用例
	//2 使用混合分隔符
	//3 分割符在最前
	//4 分割符在最后
	//5 分隔符凑在一起
	string s = "hello,welcome,to beijing,欢迎到中国来;啦啦啦";
	string split_str = ", ;";
	vector vec;

	split_string(s, split_str, vec);

	s = ",; hello,welcome,to,beijing, ; ";

	vec.clear();

	split_string(s, split_str, vec);
	return 0;
}

你可能感兴趣的:(学习,经验,算法,vc,有穷自动机,字符串)