`
hao3100590
  • 浏览: 128665 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

常见字符串操作大全

阅读更多

1.常见的字符串操作

如计算长度,求子串等都是考验基本功的,现在基本操作进行实现,如下

 

2.基本实现

mchar.h

 

//串的基本操作(注意:里面的所有操作要求串必须以'\0'结束)
#ifndef MCHAR_H
#define MCHAR_H

//注意:这里面的i都是位置,从1开始;而数组中对应于0,从0开始
class MChar{
	public:
		int strLen(const char *s);		//串长度(在输入串的时候,必须以'\0'结束)
		char* strCpy(char* s,const char* p);  //串拷贝,p拷贝给s,原来的值被覆盖
		char* strCat(char* s, const char* p);//串连接,将p连接到s后面
		char* subStr(char* s, int i, int len);//求从第i个位置开始的长度为len的子串
		int strCmp(const char* s, const char* p);				//串比较(s==p, return=0; s>p, return>0; else <0)
		int strIndex(const char* s, const char* p);			//子串定位(p若属于s,返回串p在s中的位置,否则返回0)
		void strInsert(char* s, int i, const char* p);//将串p插入到串s的第i个字符开始的位置上
		void strDelete(char* s, int i, int len);//删除串s中从第i个字符开始的长度为len的子串
		int findStr(const char* s, int ch);		//查找为ch的字符
		const char *toUpper(char *s);					//将所有小写字符转换为大写
		void itoaTest(int num, char str[]);		//整数转换为字符串
		int atoiTest(char s[]);								//字符串转换成整数atoi函数
		bool isPalindrome(char *s);						//判断输入的是否是一个回文字符串	
		void printStr(char* s);
};

#endif

 mchar.cpp

 

#include <iostream>
#include <cstring>
#include <assert.h>
#include "mchar.h"
using namespace std;

//串长度(在输入串的时候,必须以'\0'结束)
int MChar::strLen(const char *s){
	if(!s) throw "串不能为空!\n";
	int i=0;
	while(*s != '\0'){
		i++;
		s++;
	}
	return i;
}		

//串拷贝,p拷贝给s,原来的值被覆盖
char* MChar::strCpy(char* s,const char* p){
	if(!s || !p) throw "串不能为空!\n";
	char *address = s;
	//改进1,简洁
	//while(*p != '\0') *s++ = *p++;
	while((*s++ = *p++) != '\0');
	//改进2:去掉它*s = '\0';
	//改进3:增加返回值,返回最新的s地址,方便链式操作
	return address;
}


//串连接,将p连接到s后面
char* MChar::strCat(char* s, const char* p){
	if(!s || !p) throw "串不能为空!\n";
	while(*s != '\0') *s++;
	while(*p != '\0') *s++ = *p++;
	*s = '\0'; 
	return s;
}

//求从第i个位置开始的长度为len的子串
char* MChar::subStr(char* s, int i, int len){
	if(!s) throw "串不能为空!\n";
	int l = strLen(s);
	if(i<1 || i>l || i+len-2>l) throw "参数越界异常!\n";
	int j=1;
	char* t = s;
	while(j != i && *s != '\0'){ 
		j++;
		*s++;
	}
	while(*s != '\0' && len > 0)
	{
		len--; 
		*t++ = *s++;
	}
	*t = '\0';
	return t;
}

//串比较(s==p, return=0; s>p, return 1; else  -1)
int MChar::strCmp(const char* s, const char* p){
	if(!s || !p) throw "串不能为空!\n";
	while(*s != '\0'){
		if(*s++ == *p++) continue;
		else if(*s++ > *p++) return 1;
		else return -1;
	}
	if(*s == '\0' && *p == '\0') return 0;
	else return -1;
}			

//将串p插入到串s的第i个字符开始的位置上,假设s的长度足够长,不会溢出
void MChar::strInsert(char* s, int i, const char* p){
	if(!s && !p) throw "串不能为空!\n";
	int len = strLen(s);
	int len2 = strLen(p);
	if(i<1 || i>len+1) throw "参数越界异常!\n";
	int j=0;
	//不是j=len-1开始,因为要把'\0'也移动到后面
	for(j=len; j>=i-1; j--){
		s[len2+j] = s[j];
	}
	for(j=0; j<len2; j++){
		s[i+j-1] = p[j];
	}
}

//删除串s中从第i个字符开始的长度为len的子串
void MChar::strDelete(char* s, int i, int len){
	if(!s) throw "串不能为空!\n";
	int l = strLen(s);
	if(i<1 || i>l || i+len-1> l) throw "参数越界异常!\n";
	for(int j=i+len-1; j<=l; j++){
		s[j-len] = s[j];
	}
}

//查找为ch的字符
int MChar::findStr(const char* s, int ch){
	if(!s) throw "串不能为空!\n";
	int i=1;
	while(*s != '\0'){
		if(*s == (char)ch) return i;
		s++;
		i++;
	}
	return 0;
}

//子串定位(p若属于s,返回串p在s中的位置,否则返回0)
int MChar::strIndex(const char* s, const char* p){
	if(!s || !p) throw "串不能为空!\n";
	int i=0, j=0, r = 1;
	int sl = strLen(s);
	int pl = strLen(p);
	if(sl < pl) throw "参数异常,串长度!\n";
	while(i<sl && j<pl){
		if(s[i] == p[j]){
			i++; j++;
		}else{//恢复开始的位置的下一个位置
			i = i-j+1;
			j = 0;
		}
	}
	if(j >= pl) r = i-pl+1;
	else r = -1;
	return r;
}		
 
void MChar::printStr(char* s){
	if(!s) throw "串不能为空!\n";
	while(*s != '\0') cout<<*s++<<" ";
	cout<<endl;
}

const char* MChar::toUpper(char *s){
	if(!s) throw "串不能为空!\n";
	int l = 'a' - 'A';
	cout<<l<<endl;
	while(*s != '\0'){
		if(*s>= 'a' && *s<='z') *s = *s - l;
		s++;	
	}
	return s;
}

//整数转换为字符串
void MChar::itoaTest(int num, char str[]){		
	int n = num, i, k;
	char tmp[20];//假设不会发生溢出 
	if(num < 0) n = -n;
	for(k=0; n>0; k++){
		i = n % 10;
		tmp[k] = i + '0';//'0'-->48, '0'+1==49-->'1'
		n = n / 10;
	}
	//反向
	if(num < 0) tmp[k] = '-';
	else k--;
	for(i=0; k >= 0; i++){
		str[i] = tmp[k--];
	}
	str[i] = '\0';
}

//字符串转换成整数atoi函数(关键是注意,特殊字符的判断,前面的+-等)
/**注意四点:
	*1.整数以谁开头,‘+’,‘-’或者空格,要判断;
	*2.如果输入字符串是指针,首先判断是否为空;
	*3.输入字符串可能含非数字字符,如果含果断结束;
	*4.最后得到的整数特别大,可能溢出
	*/
int MChar::atoiTest(char s[]){
	int sign = 1, tmp = 0, i = 0;
	//判断前面是否有空格,回车等
	while(' '==s[i]||'\t'==s[i]) i++;
	//符号判断
	if(s[i]=='-'){
		i++;
		sign = -1;
	}else if(s[i]=='+'){
		i++;
		sign = 1;
	}
	while(s[i] != '\0'){
		//对于非数字,直接结束
		if(s[i] < '0' || s[i] > '9') throw "含有非数字字符!";
//或者使用断言代替throw,不过throw更好,他能提供具体原因,这个可以自己指定,方便找到原因
//assert(s[i] >= '0'); assert(s[i]<= '9');
		tmp = tmp*10 + s[i]-'0';
		//处理溢出
		if(tmp < 0) throw "整数过大溢出!";
//assert(tmp >= 0);
		i++;
	}	
	return sign*tmp;
}

//判断输入的是否是一个回文字符串
bool MChar::isPalindrome(char *s){
	char input[100];
  strcpy(input, s);
  int length = strlen(input);
  int begin = 0,end = length-1;
  while(begin<end)
  {
   if(s[begin]==s[end]){ 
	   	begin++;
	    end--;
   }else{
   	 	break;
   }           
  }
  if(begin<end) return false;
  else return true;     
}

 main.cpp

 

#include <iostream>
#include <cstring>
#include "mchar.h"
using namespace std;

int main(){
	MChar mc;
	char a[] = {'h','e','l','l','o','j','l','l','k','\0','o','o','o','o','o','o','o','o','o'};
	char b[] = {'g','m','\0'};
	char c[] = {'l','L','0','t','K','\0'};
	
	try{
		/*
		mc.printStr(a);
		cout<<"串长度:"<<mc.strLen(a)<<endl;
		cout<<"串拷贝:";
		char* s = new char[6];
		mc.strCpy(s, c);
		mc.printStr(s);
		delete s;
		
		cout<<"\n串连接:";
		mc.strCat(a, b);
		mc.printStr(a);
		
		cout<<"\n子串截取:";
		char* m = mc.subStr(a, 1, 4);
		if(m) mc.printStr(a);
		
		cout<<"\n串比较:";
		cout<<mc.strCmp(c, a)<<endl;
		
		
		cout<<"串插入:";
		mc.strInsert(a, 7, b);
		mc.printStr(a);
		
		cout<<"串删除:";
		mc.strDelete(a, 5, 7);
		mc.printStr(a);
		
		cout<<(int)'e'<<endl;
		cout<<"查找字符:";
		cout<<mc.findStr(a, 101)<<endl;
		
		cout<<"子串位置:";
		cout<<mc.strIndex(a, c)<<endl;
		
		cout<<"大写转换:";
		mc.toUpper(c);
		mc.printStr(c);
		
		
		cout<<"整数转换为字符串:";
		char* t = new char[20];
		mc.itoaTest(324344445, t);
		mc.printStr(t);
		cout<<(char)(3+'0')<<" "<<(int)'0'<<endl;//输出3 48
		
		
		cout<<"字符串转换为整数:";
		char t[] = {' ','-','3','4','5','2','9','\0'};
		cout<<mc.atoiTest(t)<<endl;
		cout<<'3'-'0'<<endl;
		*/
		
		cout<<"回文字符串判读:";
		char s[20] ="1234554321";
		if(mc.isPalindrome(s))
    {
      cout<<"True"<<endl;
    }else{
      cout<<"Fasle"<<endl;
    }
  }catch(char const *s){
 		cout<<s<<endl;
  }
	
	return 0;
}

 3.几个操作

 

#include <iostream>
#include <cstring>
using namespace std;

bool isDigit(const char ch){
	if(ch >= '0' && ch <= '9') return true;
	return false;
}

//计算连续数字的个数,如ak123x5612393837?3043gef435,将其存入数组a中a[] = {123,56,123,43,43}
int countInt(const string s, string* result){
	int count = 0;												//查找到的字符串个数
	int i=0,temp=11;											//temp暂存,上一个数字(注:数字是从0~9故而这里设为11)
	string str = "";											//临时存储,递增字符串(如123,54)
	const char* c = s.c_str();						//转换为char数组
	while(i < s.size()){
		char a = c[i];
		//-----------------循环处理连续数字字符串--------------------------------------
		//判读是不是数字,如果是数字则要循环判段是否顺序递增或递减
		while(isDigit(a)){
			int k = a-'0';
			if(str.size() == 0){ 									//1.如果刚开始,就直接添加到str
				str.append(sizeof(char),a);
			}else if(k == temp+1 || k == temp-1){	//2.如果不是第一个,而且是下一个数字,则添加到str
				str.append(sizeof(char),a);
			}else if(str.size() == 1){						//3.如果既不是第一个也不是连续的数组,置空并重新开始往str添加,注:顺序不能变,代表了判读的顺序
				//restart again
				str = "";
				str.append(sizeof(char),a);
			}else{																//4.如果str个数>1,而后面也没有连续的数字了,就放入result数组,并重新继续开始往str添加
				*result++ = str;
				count++;
				//restart again
				str = "";
				str.append(sizeof(char),a);
			}
			a = c[++i];
			if(!isDigit(a)){ 											//如果非数字,看是否满足放入result的条件,如果满足存入,否则跳出循环
				if(str.size() > 1){
					*result++ = str;
					count++;
					str = "";
					temp = 11;
				}
				break;
			}
			temp = k;
		}
		i++;
	}
	return count;
}

//求最长重复子串
int longestString(const string str){
	const char* s = str.c_str();
	int n = str.size();
	int index = 0, max = 0;
	int length = 1, i=0,start=0;
	while(i<n-1){
		if(s[i] == s[i+1]){
			length++;
		}else{
			if(max < length){
				max = length;
				index = start;
			}
			length = 1;
			start = i;	
		}
		i++;
	}
	cout<<"最长子串长度为:"<<max<<", 位置:"<<index+1<<endl;
	return max;
}

bool isSign(const char ch){
	if(ch == ',' || ch == '.' || ch == '?' || ch == '!' || ch == '"' || ch == '\'' || ch == '-' || ch == ' ') return true;
	return false;
}

bool isSpicial(const char ch){
	if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')) return false;
	return true;
}

//(文章的处理)将字符串中的特殊字符用空格代替(假设现在只含有,.?"!'-),若是多个空格,则用一个空格代替
void clearString(string str, char* result){
	const char* s = str.c_str();
	int len = str.size(), temp = 0;
	for(int i=0; i<len; i++){
		if(!isSpicial(s[i])){ //如果是字母或数字不处理
			*result++ = s[i];		
		}else{																
			//如果是特殊字符则跳过
			while(i<len && isSpicial(s[i])){
				i++;
			}
			//特殊字符以空格取代
			*result++ = ' ';
			i--;//减去一个,因为for循环开始循环之前要i++
		}
	}
}

int main(){
	/*
	string s = "ak123x5612d393837?3043gef435";
	string* a = new string[s.size()];
	int count = countInt(s,a);
	cout<<count<<endl;
	for(int i=0; i<count; i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	delete[] a;
	
	//最长子串
	string m = "4444fdasdfdrekkkkkkkkfdeeesfs";
	longestString(m);
	*/
	string k = "What is it? she asked   joyfully. Scarlett! 43 44  55ffg  She was:  Bitterly disappointed.";
	char* result = new char[k.size()];
	clearString(k, result);
	for(int i=0; i<k.size(); i++){
		cout<<result[i];
	}
	cout<<endl;
	delete[] result;
	return 0;
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics