数据结构常用算法分析(C++版)-串与正则表达式

内容简介

字符串是我们编程最常面对的类型之一,这节我们一起来就简单来看看字符串的存储与使用, 下面从C和C++两个方面分别看一下字符串的定义、存储与使用! 最后结合正则表达式,看看正则表达式在C/C++中的使用!

串和正则表达式的相关代码已经托管到Github上了~我是代码,快点我

C语言字符处理函数

C语言对字符串定义有2种形式:

  • char* 前者只是一个指针,不确定字符串的存储位置;
  • char str[] 后者申请内存区域保存字符串的位置!

下面代码首先说明了字符的几种定义方式,接着使用了常用处理函数 最后结合strtok方法,实现了字符串分割函数split()

一言不合看代码:


char** split(char str[],char* pattern)  
{  

	char *p;
	char * result[50];
	int i=1;
	p=strtok(str,pattern);
	result[i]=p;
	while(p)
	{
		cout<<p<<endl;
		p=strtok(NULL,pattern);
		result[i]=p;
		i++;
	}

	return result;
}  

void TestCString()
{
	char * s1="121";//size=4 len=3 字符串放在常量区域
	char s2[]="222";//size=4 len=3 字符串保存在数组中
	char s3[10]="333";//size=10 len=3 编译器会自动添加'\0'(字符数组与字符串区别)
//	s2="444";// 编译不通过
	s1="121";// 编译通过
	cout<<strlen(s3)<<endl;
	cout<<sizeof(s3)<<endl;

	//C字符串函数命名规范 strxxx() 
	//注意:C语言的相关函数并不做容量检测,在copy/cat前应确认大小满足,否则可能会出错
	cout<<strcmp(s1,s2)<<endl;//可选n 表示前n个
	cout<<strcat(s3,s1)<<endl;//可选n 表示s1前n个
	cout<<strcpy(s3,s1)<<endl;//可选n 表示s1前n个
	cout<<strchr(s1,'2')<<endl;
	cout<<strstr(s1,"21")<<endl;
    //方法1:
	char str[]="a,b,c";
	cout<<split(str,",")[2]<<endl;
}


```cpp


## C++字符处理函数

C++使用string类保存字符串,定义方式也是多种多样,
下面的代码首先讲述了几种定义方式,接着展示了string类的几种使用方法!

最后使用find()/substr() 实现了C++版字符串分割函数split(string,string)

一言不合还看代码:

```cpp

//字符串分割函数
vector<string> split(string str,string pattern)  
{  
	int pos;  
	vector<string> result; 
	int i=0;
	while(true){		
		pos=str.find(pattern,i);  
		if(pos>0&&i<str.size())  
		{  
			result.push_back(str.substr(i,pos-i));  
			i=pos+pattern.size();  
		}
		else
		{
			result.push_back(str.substr(i,str.size())); 
			break;
		}
		}  
	return result;  
}  


void TestCppString()
{
	//定义
	string s1 = "aaa";  
	string s2 = s1;//相同内容,不同对象,不同地址
	if(s2 == s1){  
		cout<<"s2 = s1"<<endl;  
	}  
	string s3("value");   
	string s4(10, 'c');
	cout<<s4<<endl;

	cout<<sizeof(s1)<<endl;//16
	cout<<s1.size()<<endl;//3
	cout<<s1.length()<<endl;//3
	cout<<s1.compare(s2)<<endl;//0
	cout<<s1+s2<<endl;//aaaaaa
	cout<<s1.substr(1)<<endl;//aa
	cout<<s3.find("ue",0)<<endl;//3
	cout<<s1.insert(s1.size(),"bcd")<<endl;//aaabcd
	cout<<s1.replace(s1.size()-3,s1.size(),"efg")<<endl;//aaaefg
	cout<<s1.capacity()<<endl;
	cout<<s1[2]<<endl;
	cout<<s1.c_str()<<endl;
	itoa(123,s1.begin(),10);
	cout<<s1<<endl;//litoa() 将长整型值转换为字符串  ultoa()
	s1="21";
	cout<<atoi(s1.c_str())<<endl;

//	方法2:
	cout<<split("a,b,c",",")[2]<<endl;
}

Regex的使用

Regex作为字符串匹配、处理的利器,在这一节怎么能少了这一法宝呢? 下面就是一个C语言下的“HelloRegex”

通过代码可以看出,在C/C++下使用Regex主要步骤有三步:

  • 生成正则表达式,使用regcomp()方法;
  • 进行正则表达式匹配,使用regexec()方法;
  • 最后释放生成的正则表达式空间!

哈哈,一言不合再看代码:


#include<regex.h>

void Regex()
{
    const char * pRegexStr = "[a-z].*";  
    const char * pText = "hello";  
   
    regex_t oRegex;  
    int nErrCode = 0;  
    char szErrMsg[1024] = {0};
    size_t unErrMsgLen = 0;  
   
    if ((nErrCode = regcomp(&oRegex, pRegexStr, 0)) == 0)  
    {  
        if ((nErrCode = regexec(&oRegex, pText, 0, NULL, 0)) == 0)  
        {  
            cout<<pText<<" matches: "<<pRegexStr<<endl; 
            regfree(&oRegex);  
            return 0;  
        }
    }
    unErrMsgLen = regerror(nErrCode, &oRegex, szErrMsg, sizeof(szErrMsg));  
    unErrMsgLen = unErrMsgLen < sizeof(szErrMsg) ? unErrMsgLen : sizeof(szErrMsg) - 1;  
    szErrMsg[unErrMsgLen] = '\0';  
    cout<<"ErrMsg:  "<<szErrMsg<<endl;  
    regfree(&oRegex);  
    return 0;


代码运行结果:

正则表达式执行结果

KMP算法

本来想写KMP算法的,但是感觉似懂非懂,哈哈,还是先Mark一下吧,以后再写!

参考文献:

C/C++字符串处理 C语言字符处理 C/C++中的Regex库

Search

    Post Directory