字符串专题

1.1 字符串的旋转

题目描述:

将前部的字符子串整体移到字符串的尾部 (abcdef->defabc)

算法思想:

1、采用暴力的解法,每次移动一个字符到末尾,那么一次操作需要移动n个字符(n为字符串长度),若子串长度设为m,共需进行m*n次移位操作。则时间复杂度为O(mn),空间复杂度为O(1)

void LeftShiftOne(char *s, int n){
	char first_word = s[0];
	for(int i = 1; i < n; i++ ){
		s[i-1] = s[i];
	}
	s[n-1] = first_word;
}

void LeftRotateString(char *s, int m){
	while(m--){
		LeftShiftOne(s, 10);
	}
}

2、新时代优秀青年肯定不能使用这种简单低效的解法。于是考虑先将需要移动的子串和剩余子串分别进行反转,再进行整体反转(三步反转法:1、分块 2、子串反转 3、整体反转)

void ReverseString(char*s, int from, int to){//字符串反转算法,切记不要将字符串拆开分别存在数组中,直接用字符指针操作字符串,方便快捷
	char temp;
	while(from < to){
		temp = s[from];
		s[from++] = s[to];
		s[to--] = temp;
	}

}
int main(){
	char text[] = "worldhello";
	ReverseString(text, 0, 4); //三次反转操作
	ReverseString(text, 5, 9);
	ReverseString(text, 0, 9);
	printf("%s", text);
	return 0;
} 


1.1.3 单词翻转

 题目描述:

翻转句子中单词的顺序,要求单词内字符的顺序不变。例:输入“I am a student.”输出“student. a am I”

算法思想:

做字符串反转,先考虑子串反转,再考虑整个字符串反转。 反转函数要牢记。

void ReverseString(char*s, int from, int to){
	char temp;
	while(from < to){
		temp = s[from];
		s[from++] = s[to];
		s[to--] = temp;
	}
}
int main(){
	char text[] = "I am a student.";
	int from(0), to;
	for(int i = 0; i < 15; i++){
		if(text[i] == ' '){
			to = i-1;
			ReverseString(text, from, to);
			from = i+1;
		}
	}
	ReverseString(text, 0, 14);
	printf("%s", text);
	return 0;
} 


1.2 字符串的包含

 题目描述:

给定长串a和短串b,请快速判断短串b中的字符是否都在长串a中

算法思想:

1、排序后轮询。先对a、b字符串进行排序,依次将b中的每个字符和a中的每个字符进行比较,如果不同,输出false,否则输出true

两次排序分别需要O(mlogm)+O(nlogn),线性扫描需要O(m+n)

bool StringContain(string &a, string &b){
	sort(a.begin(), a.end());
    sort(b.begin(), b.end());
    int i,j = 0;
    for(; j < b.length(); ){
    		if(b[j] == a[i])
    		  j++;
    		else if(i < a.length()){
    			 i++;
			}
    		      
    		     else
    		       return false;  		    
	}
	return true;
}

2、素数相乘。素数有一个特别的性质:只能被1和自身整除。用26个素数代表26个字母,进行a字符串的素数相乘操作,再将b字符串对应的素数作为除数,如果相除有余数,输出false,否则输出ture

bool StringContain(string &a, string &b){
	const int p[26] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101};
	int count_a= 1, temp;
	for(int i =0; i < a.length(); i++)
		count_a *= p[a[i]-'A'];
	for(int i = 0; i < b.length(); i++)
		if(count_a % p[b[i]-'A'])
		    return false;
	return true;
}

但是,素数相除极易导致整数溢出(超过long long),所以该方法看似可行,实则不可行

3、

猜你喜欢

转载自blog.csdn.net/qq_28038873/article/details/79972497
今日推荐