本次讲课讲全面介绍字符串以及如何使用字符串解决具体问题。

一、什么是字符串

1.如何存储字符串

平时我们使用的变量有很多,int代表整型变量,double代表浮点型变量,char代表字符型变量,那么对于一个字符串例如“Hello World!”应该如何存储并操作呢。

在C语言里,我们可以char数组进行存储,例如:

 char str1[] = "Hello World!";
char* str2 = "Hello World!";
char str3[] = "Hello World!";

对str1、2、3进行输出都为“Hello World!”,这三种方式构造一个字符串的区别有哪些?我们输出他们的空间长度(注意是占用的空间长度而不是字符串长度)。

     int len1 = sizeof(str1)/sizeof(char);
int len2 = sizeof(str2)/sizeof(char);
int len3 = sizeof(str3)/sizeof(char);
printf("%d\n%d\n%d\n",len1,len2,len3);
结果为:13
    4
    20

(此处应对上诉结果进行解释说明 ==)

既然字符串可以存储在一个字符数组里面,那么如何对字符串进行操作想必也就非常清楚了。需要注意的是,对于计算机可以字符和一个整型变量没有任何区别,它们都是数据,所以对整型变量可以做的操作都可以对一个字符进行同样的操作。

2.ASCII编码

众所周知字符在C/C++里面是以ASCII码的形式存储在计算机中,既然字符串是存储在字符数组里面的,其实也就是多个字符的一个有序集合。它也遵守和字符同样的的规则,例如'A'的ASCII码为65,如果我们进行下列语句

 char ch = 'A';
if(ch == 'A'){
ch = ch + ;
}
else {
ch = ch - ;
}

那么这里ch的值应该变成多少了呢?此时的ch又代表哪个字符呢?

3.std::string

是不是没见过这是什么东西,它其实就是character string(字符串),这是一个C++的语句,意思就是调用std(标准命名空间)里面的string类,可能你也已经猜到了string是用来干什么的,是的它可以直接定义一个字符串变量,并且能够直接对串进行操作。

什么意思呢?我们既然已经能够用字符数组存储字符串了,为什么还需要多个string呢,因为我们前面说了字符串数组相当于一个字符的有序集合,归根到底还都是单个字符,而字符串变量string才是真正的字符串,它可以直接对串操作,例如下列语句:

std::string str = "Hello";
str += " World";
str += "!";

如果仅仅只是这样,那么string并不显得强大,事实上string支持下面的功能

我是传送门:string的用法

但是值得注意的是,string是c++语言的东西,在c语言中并不能使用,而且string只能通过cin流进行读入操作,同样可以使用下标对string字符串进行每一位的访问以及操作。

C++也还有很多C语言没有的容器,通过这些容器对做题有很大帮助,而且这些容器对于一个ACMer来说是必须要掌握的,详情请戳:

STL容器(Stack, Queue, List, Vector, Deque, Priority_Queue, Map, Pair, Set, Multiset, Multimap)

二、字符串操作

1.空格、换行符

我们知道使用scanf("%s",s);读入一个字符串遇到空格和换行符自动跳出,但是对于一个字符串不可能都没有空格以及换行呀,如果是需要读入一个句子那该怎么办呢,对于C语言,我提供了下列几种方法供参考

 //方法一——判断是否为空格选择继续读入还是跳出
char s[],ch;
scanf("%s",s);
ch = getchar();
while(ch == ' '){
int len = strlen(s);
s[len] = ' ';
scanf("%s",s+len+);
ch = getchar();
} //方法二——利用格式符%[]设置结束符
char s[];
scanf("%[^\n]",s); //方法三——利用不安全的gets进行读入
char s[];
gets(s);

三种方法都可以进行读入以换行符为结束符带有空格的字符串,但是我推荐最好使用第一种,为什么?

(此处应对上述进行解释说明)

在C++语言中,想要读入这样的串,我也同样提供几种方法供参考

 //方法一——使用cin流对字符串进行读入
char s[];
cin.getline(s,); //方法二——使用getline进行string类读入
string s;
getline(cin,s);

下面以一个例题为例,对字符串的具体操作进行讲解

题目链接:http://120.78.128.11/Problem.jsp?pid=1716

下面我贴出C语言和C++语言的代码

C语言:

 #include <stdio.h>
#include <string.h>
char s1[],s2[]; void read(char *s){
int ch;
scanf("%s",s);
ch = getchar();
while(ch == ' '){
int len = strlen(s);
s[len] = ' ';
scanf("%s",s+len+);
ch = getchar();
}
} int main(){
int t;
scanf("%d",&t);
while(t--){
read(s1),read(s2);//读入字符串
int len1 = strlen(s1),len2 = strlen(s2);
int flag = -,i,j;
for(i = ; i < len1; i++){
if(s1[i] == s2[]){
for(j = ; j < len2; j++){
if(j == len2- && s1[i+j] == s2[j])
flag = i+;
if(s1[i+j] != s2[j])
break;
}
}
}
printf("%d\n",flag);
}
return ;
}

C++语言:

 #include <bits/stdc++.h>
using namespace std; string s1,s2; int main(){
int t;
cin>>t;
cin.get();
while(t--){
getline(cin,s1),getline(cin,s2);
int pos = s1.find(s2);
cout << (pos==-?-:pos+) << endl;
}
return ;
}

这也是为什么要用C++的原因,C++内置函数以及操作实在是太强大了,两个C中较为冗长的函数在C++中都只要用一句便实现了。

另一个例题:http://120.78.128.11/Problem.jsp?pid=1924

C语言代码:

 #include <stdio.h>
#include <string.h>
char s[]; void read(char *s){
int ch;
scanf("%s",s);
ch = getchar();
while(ch == ' '){
int len = strlen(s);
s[len] = ' ';
scanf("%s",s+len+);
ch = getchar();
}
} int main(){
int t,i;
scanf("%d",&t);
while(t--){
read(s);
int len = strlen(s);
for(i = ; i < len; i++){
if(i == ){
putchar(s[i]-);
}
if(s[i] == ' '){
putchar(s[i+]-);
}
}
puts("");
}
return ;
}

C++代码:

 #include <bits/stdc++.h>
using namespace std; string s; int main(){
int t;
cin>>t;
cin.get();
while(t--){
getline(cin,s);
int len = s.size();
cout << char(s[]-);
for(int i = ; i < len; i++){
if(s[i] == ' ')
cout << char(s[i+]-);
}
cout << endl;
}
return ;
}

2.字符串比较

我们知道可以通过一位一位的模拟进行字符串比较,但要是两个字符串都很长怎么办,我们容易得出暴力方法进行匹配的时间复杂度为O(n*m),n和m就是两个字符串的长度,通过一些算法我们可以进行匹配优化,例如我们可以利用KMP算法在O(n+m)的时间复杂度内进行匹配。

下面是KMP的算法讲解

我是传送门:KMP算法

传送门:KMP例题

ACM讲课之字符串的更多相关文章

  1. 【ACM】poj_3981_字符串替换_201307271019

    字符串替换Time Limit: 1000MS  Memory Limit: 65536K Total Submissions: 8447  Accepted: 3988 Description 编写 ...

  2. 【好好补题,因为没准题目还会再出第三遍!!】ACM字符串-组合数学(官方题解是数位DP来写)

    ACM字符串 .长度不能超过n .字符串中仅包含大写字母 .生成的字符串必须包含字符串“ACM”,ACM字符串要求连在一块! ok,是不是很简单?现在告诉你n的值,你来告诉我这样的字符串有多少个 输入 ...

  3. 回归——继续我的ACM之路!!

    回归啦~~18年省赛结束后第一次参赛拿到了省级银牌对我是一个很大的鼓励,这是所感兴趣的事,我能做的不错,也就不愧于心了. 修整了两周多左右,建了建模,和阔爱的对象狂了两周,终于要静下来了,静下来一想, ...

  4. Text Reverse

    Text Reverse Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  5. NWU现场赛——解题报告

    负二进制转换 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Problem Desc ...

  6. KMP(梅开三度之数据结构详解版

    前言 KMP算法是一种字符串匹配算法,其重中之重是next数组的构建,其代码的简洁与神奇使其广受关注. 但不难发现,acm中学到的KMP和数据结构里面学到的KMP并不一样o(︶︿︶)o 之前我写过ac ...

  7. ACM字符串输入问题

    坑死了..竟然被这个问题困扰了大半个学期,今天搜来翻去终于弄明白了一些,以后固定用这几种用法好了不然总出错QAQ实际测试例子就没放了,死记这里就够用了T-T 概念: gets()函数:用来从标准输入设 ...

  8. 2017 ACM 字符串的本质

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2017 思路:思考字符串和数字的本质区别是什么. 今天先是试着做了一个完全背包的题目,发现自己还是不会做,弄 ...

  9. 牛客网暑期ACM多校训练营(第三场) E Sort String 哈希处理字符串(模板)

    链接:https://www.nowcoder.com/acm/contest/141/E来源:牛客网 Eddy likes to play with string which is a sequen ...

随机推荐

  1. 使用 .NET CORE 创建 项目模板,模板项目,Template

    场景:日常工作中,你可能会碰到需要新建一个全新的解决方案的情况(如公司新起了一个新项目,需要有全新配套的后台程序),如果公司内部基础框架较多.解决方案需要DDD模式等,那么从新起项目到各种依赖引用到能 ...

  2. serverless在微店node领域的探索应用

    背景 目前微店中台团队为了满足公司大部分产品.运营以及部分后端开发人员的尝鲜和试错的需求,提供了一套基于图形化搭建的服务端接口交付方案,利用该方案及提供的系统可生成一副包含运行时环境定义可立即运行的工 ...

  3. 为什么选择B+树作为数据库索引结构?

    背景 首先,来谈谈B树.为什么要使用B树?我们需要明白以下两个事实: [事实1] 不同容量的存储器,访问速度差异悬殊.以磁盘和内存为例,访问磁盘的时间大概是ms级的,访问内存的时间大概是ns级的.有个 ...

  4. mysql数据库磁盘空间被撑爆,创建定时任务定期释放资源

    问题描述: 这是我在工作中遇到的一个问题,目前只发现mysql数据库存在该问题,Oracle和gaussDB未发现磁盘空间被占满的情况,部署堆栈服务的时候抛出了写入数据库表失败的问题,经排查,在数据库 ...

  5. 由group by引发的sql_mode的学习

    前言 在一次使用group by查询数据库时,遇到了问题.下面先搭建环境,然后让问题复现,最后分析问题. 一 问题复现 mysql版本 建表插入数据 表的结构 现在问题来了:我想查询上面表中每个部门年 ...

  6. IoT时代:Wi-Fi“配网”技术剖析总结

    导读 近年来,物联网市场竞争激烈,从物联网平台厂商,设备生产商,到服务提供商,都在涌入这片红海.预计到2020年,全球联网设备数量将达到260亿个,年复合增长率达到20%:全球联网设备带来的数据将达到 ...

  7. React 现代化测试

    测试的动机 测试用例的书写是一个风险驱动的行为, 每当收到 Bug 报告时, 先写一个单元测试来暴露这个 Bug, 在日后的代码提交中, 若该测试用例是通过的, 开发者就能更为自信地确保程序不会再次出 ...

  8. Flink中watermark为什么选择最小一条(源码分析)

    昨天在社区群看到有人问,为什么水印取最小的一条?这里分享一下自己的理解 首先水印一般是设置为:(事件时间 - 指定的值)  这里的作用是解决迟到数据的问题,从源码来看一下它如何解决的 先来看下wind ...

  9. 牛客网2016.4.11(两个数相加为sum/计数一个int型的二进制有多少个1/二叉树是否左右对称)

    求最小的两个数相加为sum //求最小的两个数相加为sum public ArrayList<Integer> FindNumbersWithSum(int [] array,int su ...

  10. 亲,麻烦给个五星好评!—RatingBar

    引言 上一篇的CheckBox已经让大家越来越接近实战演练了,本章我们继续分享干货给大家,今天介绍一个实用的UI控件RatingBar(星级评分条),对于使用过电商APP(某东,某宝等)的小伙伴们来说 ...