(纯干货建议收藏)大型字符串模拟-超强超全函数技巧总结

这篇文章将会总结一些处理字符串、进制转换等等的常见的、非常有用的技巧和函数。后续会随时更新本文章,希望大家收藏、留言,一起学习进步!

对于特别简单的函数,就不写函数的详细原型啦!

具体包含四部分,可以根据目录去寻找:
1.char*函数       2.string函数    3.数符转换和进制转换  4.字符串函数优化(kmp替换string find,字符串哈希部分替换string substr)

5.位运算技巧 

6.按空格分割字符串

目录

char*函数

strlen函数:

strcmp函数:

strcat函数:

strcpy函数:

memset函数:

cin.getline函数:

读取char*时的下标问题

char*转string

string函数

size/length函数

push_back()与insert()函数

compare函数/append函数

erase函数

replace函数

string转char*

find函数

substr函数

数符转换和进制转换

sprintf函数

itoa/atoi

进制转换补充

字符串函数优化

位运算技巧

字符串按空格分割


char*函数

strlen函数:

求一个char数组的长度,

char str[10]
scanf("%s",str);
int len=strlen(str);
cout<

strcmp函数:

比较两个char数组的字典序,

char a[6]="a"
char b[6]="ab"
char c[6]="ac"
cout<

strcat函数:

连接两个char数组,

char a[6]="ab"
char b[6]="bc"
strcat(a,b)
cout<

strcpy函数:

把一个char数组复制到另一个上面,

char a[6]="ab"
char b[6]="bc"
strcpy(a,b)
cout<

memset函数:

初始化数组,  int数组也可以用

char a[100];
memset(a,'0',sizeof a);

cin.getline函数:

读取一行字符,包括空格,遇到换行符终止,丢弃换行符,

第一个参数:数组名,第二个参数:最多输入的字符数(注意字符串后面有一个空字符,所以一般这个参数比实际最大长度多1,比如读取abcd就写5)

int a[100];
cin.getline(a,100);//最多输入99个字符,即(0,99);
cout<

还有cin.get函数可以读取一行,但是对于读取一行的函数就掌握getline就够用了!比如下面这段代码换成get就会出问题


while(n--)
{
	char a[100];
	cin.getline(a,100)//最多输入99个字符,即(0,99);
	cout<

读取char*时的下标问题

如果想让读取到的char*下标从1开始,cin,scanf,getline都支持下面这种写法,string就不支持

    char a[10];
//	cin>>a+1;
//	scanf("%s",a+1);
	cin.getline(a+1,10);
	cout<

char*转string

方法非常简单,直接让一个char*赋值给string即可

char a[100]="anc";
string b=a;
cout<

string函数

包含STL神器之一:string 的各种常用函数,头文件皆为

size/length函数

返回string长度

string a="123";
cout<

push_back()与insert()函数

前者:向字符串尾端插入一个字符

后者:下面展示常用的,当然还有别的方法,只不过可以由最基本的转换而来

string a="123";
string b="56";
char c='7';
a.push_back('4');
cout<

compare函数/append函数

建议直接用< > == 和 +=符号替代

erase函数

常用来删除一个区间内的字符,区间左闭右开

string str="123456";
str.erase(1,4);
cout<

replace函数

常用来把str的某一个区间替换成重复的单个字符或者整个其它字符串

下面展示几种常用的写法

string a="123456";
string b="789";
char c='0'
a.replace(0,5,b);//a="7896"  把a的[0,5)变成b
a.replace(0,2,3,c);//a="00096"   把a从下标0开始往后的2个字符替换成3个字符c

string转char*

直接用c_str()即可

char a[100];
string b="123";
a=b.c_str();
//也可以这样:scanf("%s",b.c_str());

find函数

模式匹配函数,直接放例子,通俗易懂

string a="123123";
cout<

substr函数

str.substr(pos,length)从pos开始往后截取长度为length的子串并返回

string a="1234";
string b=a.substr(2,2);//b="34"

数符转换和进制转换

本部分将会介绍整型和字符串常用的转换方法,由于这个转换常常可以伴随进制转换,所以放在一起总结,这也是字符串模拟题目中常常考察的技能!!!

sprintf函数

把一个格式化字符串,写入字符数组,返回写入数组的总字符数,如果失败,返回负数

举例:

char a[100];
int b=5;
sprintf(a,"1234%d",b);//a="12345"

itoa/atoi

itoa用于将十进制整数变为任意进制的字符数组形式

atoi用于将字符数组变为十进制整数(不支持类型转换)

详见:atoi itoa简介

进制转换补充

看到这里,可能会问:那如何把a进制整数转为b进制整数呢?答案是c++没有这个库函数,所以需要自己写一个函数,先把a进制转10进制,再把10进制转b进制

同理,c++也没有把一个a进制字符串变为十进制整数的函数,需要麻烦自己写了

字符串函数优化

find函数虽然好用,但是时间上不如kmp算法,所以当写一个题目用findTLE的使用,换成kmp吧,下面是acwing算法基础课的kmp板子:

#include 
using namespace std;
const int N = 100010, M = 1000010;
int n, m;
int ne[N];
char s[M], p[N];
int main()
{
    cin >> n >> p + 1 >> m >> s + 1;
    for (int i = 2, j = 0; i <= n; i ++ )
    {
        while (j && p[i] != p[j + 1]) j = ne[j];
        if (p[i] == p[j + 1]) j ++ ;
        ne[i] = j;
    }
    for (int i = 1, j = 0; i <= m; i ++ )
    {
        while (j && s[i] != p[j + 1]) j = ne[j];
        if (s[i] == p[j + 1]) j ++ ;
        if (j == n)
        {
            printf("%d ", i - n);
            j = ne[j];
        }
    }
    return 0;
}

再来说substr,比如下面这种题(来自acwing算法基础课),第一反应可能是用substr,但可能会TLE

(纯干货建议收藏)大型字符串模拟-超强超全函数技巧总结_第1张图片

所以在此放一下acwing算法基础课字符串哈希的板子,大家触类旁通,在某种情况下可以参考

#include
using namespace std;
const int N=100010,P=131;
typedef unsigned long long ULL;
char str[N];
ULL p[N],h[N];
ULL get(int l,int r)
{
    return h[r]-h[l-1]*p[r-l+1];
}
int main()
{
    int n,m;
    cin>>n>>m;
    getchar();
    for(int i=1;i<=n;i++)scanf("%c",&str[i]);
    p[0]=1;
    for(int i=1;i<=n;i++)
    {
        h[i]=h[i-1]*P+str[i];
        p[i]=p[i-1]*P;
    }
    while(m--)
    {
        int l1,r1,l2,r2;
        scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
        if(get(l1,r1)==get(l2,r2))cout<<"Yes"<

位运算技巧

对于二进制字符串模拟这种题,比如csp第30次认证第3题,很多时候用到位运算的技巧。下面是链接

csp30次认证第3题

x&-x:可以求x最低位的一个1出现在哪一位

比如100011算完就是000001

10010算完就是00010

a>>b&1:检查a的第b位(最低位是0)是否为1

a&1==1:奇数

a&1==0:偶数

二进制“拼接”:

比如两个二进制数100和010想变成100010,只需让100左移3然后加上010即可

二进制“截取”:

比如10101想求中间的三位数“010”,首先令a=10101   a>>=1  b=1<<3  c=a-b c即为答案

~i:判断i是否为0

由此可以发现如果可以灵活使用位运算,很多时候处理二进制数的时候可以迎刃而解

字符串按空格分割

像第三次ccfcsp的第三题:csp3次认证第3题就会常常用到这种分割技巧,方法在之前的文章中已经讲过,给出连接如下:

stringstream字符串分割、字符串拼接

你可能感兴趣的:(算法综合,C++,超强总结性干货文章,c++,开发语言,算法)