算法学习笔记(C++)——字符串处理

算法学习笔记(C++)——字符串string处理

string基础知识

  • 为使用string标准模板,需要添加头文件# include
  • 关于其初始化,可直接使用字符串给变量赋值
string str = "hello world";
// or
string str = str + " !!!";
  • 关于其长度,可以使用size()和length()两种方法
  • 关于其访问,有两种方式:下标访问和迭代器访问
    (1)下标访问:
string str = "hello world";
for (int i=0; i<str.size(); ++i){
    
    
	printf("%c", str[i]);
}

(2)迭代器访问

string str = "hello world";
for (string::iterator it = str.begin(); it !=str.end(); ++it){
    
    
	printf("%c", *it);
}
  • 关于对string中的元素进行操作,包括

(1)在指定位置插入insert()

str.insert(index, str);
第一个参数为插入的位置index
第二个参数为插入的字符串

(2)在指定位置删除 erase()
str.erase(first_char, length_of_erase);
第一个参数为删除的开始位置index
第二个参数为删除字串的长度,default为删除至string末端

(3)清空字符串clear()
无参数

  • 关于字符串参与的运算
    字符串加法表示连字符串相连
    字符串的"==", “<=”, ">"这类运算,是基于字典序进行大小比较的

  • 关于其他的一些常用函数
    (1)find()
    在字符串中寻找特定的字符或字符串,找到则返回相应的下标,否则返回string::npos(int类型接收的情况下,为-1)

string渗透入= "hello world";
int found = str.find("world");
if(found != string::npos){
    
    
	cout << found << endl;
}
found = str.find('.');


(2)substr()
str.substr(begin_index, length)
第一个参数为开始位置
第二个参数为字符串总长度

string str1 = "we think in generalities";
string str2 = str1.substr(3, 5);

字符串应用实例

注:字符串应用过程中,常涉及边界问题
且,读入string过程中,若字符串中间包含空格,则不能再用cout和scanf进行读取,会在空格处终止字符串的load,可以用getline避免读取中断

题目:
密码加密问题:
对于明文中的A~Z的每个字符,用字母表中后5位所对应的字符代替,就能够得到密文,如A->F,对于明文中的V~Z(最后五个字符)则在密文中对应A~Z。
现需要将密文转换为明文

输入格式:
每一行密文的前一行为START,后一行为END,最终读取到ENDOFINPUT时结束程序。

输出格式为若干行,每行一段明文。

# include <string>
# include <cstdio>
# include <iostream>

using namespace std;

int main(){
    
    
	string str;
	// the first line, deciding a new case of the end of code
	while(getline(cin, str)){
    
    
		if (str == "ENDOFINPUT"){
    
    
			break;
		}
		// text which is encoded
		getline(cin, str);
		for (int i=0; i<str.size(); ++i){
    
    
			if ( 'A' <= str[i] && str[i] <= 'Z'){
    
    
				str[i] = (str[i] - 5 + 26 - 'A') % 26 + 'A';
			}
		}
		string str1;
		// eat the string "END"
		getline(cin, str1);
		cout << str << endl;
	}
	return 0;
}

在这里插入图片描述


统计一个给定字符串中指定的字符出现的次数

输入格式:
每个测试样例包括两行,第一行为长度不超过5的字符串,第二行为长度不超过80的字符串(包含空格,即空格也是可能被要求统计的字符)当读取到‘#’时,输入结束

输出格式:
对每个测试样例,统计第一行中字符串的每个字符在第二行的字符串中出现的次数,并按照如下格式输出。
c0 n0
c1 n1
c2 n2

# include <cstdio>
# include <iostream>
# include <string>
# include <cstring>
using namespace std;
int number[128];

int main(){
    
    
	// record appearing times for every char
	string str1;
	string str2;
	while (getline(cin, str1)){
    
    
		if (str1=="#"){
    
    
			break;
		}
		// initial the array
		memset(number, 0, sizeof(number));// sizeof() returns how many bytes the array has
		getline(cin, str2);
		// count appearing times
		for (int i=0; i<str2.size(); ++i){
    
    
			number[str2[i]] += 1;
		}
		for (int i=0; i<str1.size(); ++i){
    
    
			printf("%c %d \n", str1[i], number[str1[i]]);
//			cout << str1[i] << " " << str2[str1[i]] << endl;
		}	
	}
	return 0;
}

在这里插入图片描述

字符串匹配问题——KMP算法

对于text字符串和pattern字符串的匹配问题,有一种高效的KMP算法:
其核心为,在模式串发生失配时,并不是从下一个字符串开始,从头开始重新匹配,而是利用已有的信息,跳过一些不可能成功匹配的位置,以便尽量减少模式串和珠串的匹配次数,快速完成匹配任务。

关于KMP算法的时间复杂度:
只需要遍历一遍模式串即可获得next表,使用next表遍历以便文本串即可获得字符串的匹配情况,故KMP算法的时间复杂度为O(m+n)


样例:
计算text文本串中pattern成功匹配的次数

# include <cstdio>
# include <string>
# include <iostream>

using namespace std;
const int MAXN = 100;

int nextTable[MAXN];


void GetNextTable(string pattern){
    
    
	int m = pattern.size();
	// initial
	memset(nextTable, 0, sizeof(nextTable));
	int j = 0;
	nextTable[j] = -1;
	int i = nextTable[j];
	while (j<m){
    
    
		if(i==-1 || pattern[i]==pattern[j]){
    
    
			++i;
			++j;
			nextTable[j] = i;
		}
		else{
    
    
			i = nextTable[i];
		}
	}
	return ;
}

int KMP(string pattern, string text){
    
    
	// the number of pattern appears
	int number = 0;
	int m = pattern.size();
	int n = text.size();
	int j = 0; // match with pattern
	int i = 0; // match with text
	while (i < n){
    
    
		if (j==-1 || text[i]==pattern[j]){
    
     	// no error just now
			++i;
			++j;			
		}
		else{
    
    								// error in match
			j = nextTable[j]; 
		}
		if (j == m){
    
    						// successfully matched
			++number;
			j = nextTable[j];
		}
	}
	return number;
}


int main(){
    
    
	int casenumber;
	cin >> casenumber;
	while (casenumber--){
    
    
		string pattern;
		string text;
		cin >> pattern >> text;
		// get the next table
		GetNextTable(pattern);
		// KMP algorithm
		cout << KMP(pattern, text);
	}
	return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_53327618/article/details/124517439
今日推荐