【Jason's_Knowledge】算法竞赛中的字符与字符串
来源:互联网 发布:易语言软件版本 编辑:程序博客网 时间:2024/06/07 01:58
算法竞赛中的字符与字符串
鄙人才疏学浅,还望各位前辈批评指正,万分感谢。
为了不至于混淆,我们将C语言中的字符与字符串和C++语言中的字符与字符串分开来讨论。在算法竞赛中,为了保证程序执行的时间效率,通常我们使用C语言的字符与字符串,以下我们先着重讲解C语言中的字符与字符串。
一、C语言中的字符与字符串
1.字符
字符数据是使用单引号括起来的一个字符。例如:’A’ , ’a’ , ’=’ , ’1’均为合法的字符型数据。
转义字符是一种特殊的字符型数据,转义字符以反斜线’\’开头,后跟一个或几个字符。转义字符具有特定的含义,不同于字符原有的意义,故称“转义”字符。例如:’\n’即为一个转义字符,它的意义是“回车换行”。
字符仅占一个字节的内存空间。
2.字符串
字符串数据是使用双引号括起来的一个字符序列。例如:”Doris” , ”Jason” , ”#007”均为合法的字符串数据。
字符串占用的内存空间字节数为:字符串所含字符数量加1(亦即字符串的长度)。
字符串结束标志为’\0’(ASCII码为0)。
从上面我们清楚,’a’与”a”意义是不同的,一个为字符,一个为字符串。他们在内存中的存储情况如下:
’a’在内存中占一个字节,可表示为:
”a”在内存中占两个字节,可表示为:
3.字符变量与字符串变量的定义以及初始化
(1) 字符变量的定义以及初始化形式如下
char 变量名; 例如:
char a;
char 变量名=’字符’; 例如:
char a=’x’;
(2) 字符串变量的定义以及初始化形式如下
在C语言中没有相应的字符串变量,也就是说不存在这样的关键字,将一个变量声明为字符串。
但是通常可以用一个字符数组来存放一个字符串。
char 变量名[字符串长度]; 例如:
char a[100];
『在更进一步的讨论字符串变量的初始化之前,我们先来回顾一下一维数组与二维数组初始化的内容。』
为了方便理解,我们一下均举例讨论,不再有任何形式化的描述。
1.一维数组的初始化
如:
int a[10]={1,2,3,4,5,6,7,8,9,10};
若给全部元素赋值,则在数组说明中,可以不给出数组元素的个数。
如:
int a[]={1,2,3,4,5,6,7,8,9,10};
2.二维数组的初始化
如:
int a[2][3]={{1,2,3},{4,5,6}};
也可以:
int a[2][3]={1,2,3,4,5,6};
若给全部元素赋初值,则在数组说明中,可以不给出第一维的长度。
如:
int a[][3]={{1,2,3},{4,5,6}};
也可以:
int a[][3]={1,2,3,4,5,6};
注意:数组类型指的是数组所包含的元素的类型,而不是数组名的类型,数组名永远是一 个指针,指向第一个元素的地址,即数组首地址。
所以,可以说字符数组同普通数组几乎一样。
我们先来讨论字符数组的初始化。
明确了上面的概念后,我们很容易的就能得出字符数组的初始化方式。
如:
char c[8]={’a’,’b’,’c’,’d’,’e’,’f’,’g’,’h’};
也可以:
char c[]={’a’,’b’,’c’,’d’,’e’,’f’,’g’,’h’};
其中:
c[0]=’a’; c[1]=’b’; c[2]=’c’; c[3]=’d’; c[4]=’e’ c[5]=’f’; c[6]=’g’; c[7]=’h’;
现在我们来讨论字符串的初始化。
字符数组与普通数组的不同在于,由于规定字符数组可以存放一个字符串,那么我 们可以这样初始化一个字符串:
如:
char c[]={”Jason”};
也可以:
char c[]=”Jason”;
亦可使用字符数组的复制方式:
char c[]={’J’,’a’,’s’,’o’,’n’};
但这里要着重注意的是:在这里,我们想为c[]赋值的数据是字符串而非字符数组,虽然说这在物理形式上是没有任何区别的,但是从逻辑的角度上来看,我们定义字符数组
char c[]={’J’,’a’,’s’,’o’,’n’};
与定义字符串
char c[]={’J’,’a’,’s’,’o’,’n’};
的区别在于,字符数组是
char c[5]={’J’,’a’,’s’,’o’,’n’};
而字符串是
char c[6]={’J’,’a’,’s’,’o’,’n’,’\0’};/*即*/ char c[6]={”Jason”};/*亦即*/ char c[6]=”Jason”;
可见,系统编译时会在字符串初始化时自动为之添加字符串结束符’\0’。所以用字符串方式赋值比用字符逐个赋值要多占一个字节, 多占的这一字节用于存放字符串结束标志'\0'。
为了不过分的纠结于初始化字符串的长度问题,我们通常使用如下的定义方式:
char c[]=”Jason”;
另外,我们讨论一种特殊的字符串的定义与初始化方式(为方便理解,同字符数组对比理解):
使用字符数组的情况如下:
char c[]=”Jason”;
使用字符指针的情况如下:
char* c=”Jason”;
也可以:
char* c;c=”Jason”;
但在c同c++混用的算法竞赛中这是很不安全的,所以我们通常会看见这样的形式:
const char* c=”Jason”;//(它经常出现在对常量字符串的定义中)
或是这样的形式(他定义了一个指向类型为字符串数据的指针的数组):
const char* c[]={”Jason”,”Doris”,”Win”};
4.字符变量与字符串变量的输入输出
(应该注意,以下有关字符变量与字符串变量的输入输出函数均包含在头文件<cstdio>当中。)
(1) 字符变量的输入输出
char ch;
第一种方式:
scanf(”%c”,&ch);printf(”%c”,ch);
第二种方式:
ch=getchar();putchar(ch);
对于输出方式我们没有什么需要注意的,但是对于这两种输入方式我们需要讨论一下他们的区别。
(I) scanf(”%c”,&ch); 以Space、Enter、Tab结束一次输入,但是不会舍弃最后的结束符(这里的结束符号是指Space、Enter、Tab)(即回车符会残留在缓冲区中);
(II) ch=getchar(); 以Enter结束输入,也不会舍弃最后的回车符;
举个例子:
#include <cstdio> using namespace std;int main() { char ch1, ch2; scanf("%c", &ch1); scanf("%c", &ch2); printf("%d %d\n", ch1, ch2); return 0; }
或者是:
#include <cstdio> using namespace std;int main() { char ch1, ch2; ch1 = getchar(); ch2 = getchar(); printf("%d %d\n", ch1, ch2); return 0; }
假若输入’a’并敲击回车,则程序直接输出97 10。
这是因为scanf()和getchar()函数是从输入流缓冲区中读取的,而并非从键盘(也就是终端)缓冲区读取。由于读取是因为遇到回车(’\n’)才结束的,并且这个’\n’会被一起读入输入流缓冲区中,所以第一次接受输入并取走字符之后会留下字符’\n’,这样第二次的读入函数就会直接从缓冲区中把’\n’取走。显然,这样的读取是成功的,它不会再从终端读取!这就是为什么这个程序只执行了一次输入操作(对于计算机来说的话,换行符也是一个输入,只执行一次输入操作仅仅是由于人的惯性思维所造成的)就结束的原因。
所以在使用scanf()或getchar()函数输入数据的时候一定要进行特判。
(2) 字符串变量的输入输出
char str[100];//或者是char* str;
第一种方式:
scanf(”%s”,str);printf(”%s”,str);
第二种方式:
gets(str);puts(str);
同样,我们仅对于这两种输入方式讨论一下他们的区别。
(I) scanf(”%s”,str); 以Space、Enter、Tab结束一次输入,并舍弃最后的结束符(这里的结束符是指Space、Enter、Tab)。
(II) gets(str); 以Enter结束输入(空格不结束),接受空格,并舍弃最后的回车符。
注意:在使用scanf(”%s”,str); 或printf(”%s”,str);输入输出字符串时,str前面并没有添加&符号。这是由于 scanf() 和 printf() 函数有一种占位符”%s”可以用作整体的输入输出字符数组,但是并没有一个特定的占位符支持 int 等其他数组整体数组输出。
5.字符串变量的重要操作函数
(应该注意,以下有关字符串变量的操作函数均包含在头文件<cstring>当中。)
1.strcmp(str1,str2); 比较str1与str2是否相等。
返回值: ==0 相等;
<0 str1<str2;
>0 str1>str2。
2.strlen(str); 求字符串str的长度。(不含字符串结束标志’\0’)
返回值: 字符串str的长度。
3.strcpy(str1,str2); 清空str1,并将str2赋值到str1中去。相当于赋值操作。
返回值:str1首地址。
4.strcat(str1,str2); 把str2中的字符串连接到str1 中的字符串的后面,并删去str1后的结束标志”\0”。
返回值:str1首地址。
二、C++语言中的字符与字符串
由于C++语言中的字符及字符数组与C语言中的没有任何差别,故我们只讨论C++语言中的字符串,即string类。(所有有关操作均包含在头文件<string>当中)
每一个string并非语言本身所特有,他其实是一个类,每当使用string定义一个字符串变量,就相当于声明了一个string对象。所以,从某种意义上讲,string相对于C语言中的字符串是十分低效的(不针对工程方面的程序设计),所以在算法竞赛中可以适当的使用它并提高代码编写效率,但是请不要滥用。
在此我就虎头蛇尾一下,简短的介绍一下string类的一点常用方法。
1.定义及初始化
string str1;string str2=”Jason”;
2.赋值
str1=”Doris”;str1[2]=’x’;//(注意必须为单引号)
3.输入输出
无法使用头文件<cstdio>中的输入输出函数,仅允许使用<iostream>中的cin、cout操 作,如下。
cin>>str1;cout<<str1;
4.操作
(1)字符串的比较,直接使用比较运算符即可,如:<等,相当于C语言的strcmp函数。
(2)字符串的链接,直接使用str1=str1+str2,相当于C语言的strcat函数。
(3)字符串的拷贝,直接使用str1=str2,相当于C语言的strcpy函数。
(4)字符串的长度,直接使用str1.size()或str1.length()(二者完全一样),相当于C语 言的strlen函数。
5.注意
string类声明的对象字符串,没有结束标志’\0’。
- 【Jason's_Knowledge】算法竞赛中的字符与字符串
- 【Jason's_Knowledge】算法竞赛中的快速排序及其应用
- 【Jason's_Knowledge】算法竞赛中的递归与迭代及其延伸内容简述
- 【Jason's_Knowledge】自动机理论简述
- jason与字符串的转换
- 【Jason's_Knowledge】【不定期更新】琐碎知识点及注意事项总结
- 算法-删除字符串中的公共字符
- 算法与数据结构面试题(19)-统计字符串中的字符个数
- c语言中的字符数组与字符串
- c语言中的字符数组与字符串
- c语言中的字符数组与字符串
- C语言中的字符数组与字符串
- c语言中的字符数组与字符串
- c语言中的字符数组与字符串
- c语言中的字符数组与字符串
- C语言中的字符数组与字符串
- 算法竞赛中的输入输出框架
- 算法竞赛中的输入输出框架
- 根据文件列表,复制文件和路径
- Codeforces 493D Vasya and Chess(规律)
- Reahat5.5安装jdk、tomcat并部署Java项目
- 励志与成才才是大学的主旋律
- 关于if else 与switch的效率问题
- 【Jason's_Knowledge】算法竞赛中的字符与字符串
- 百度地图上一些常用的接口,js调用
- 规划问题
- POJ 2533 Longest Ordered Subsequence
- Codeforces 493E Vasya and Polynomial(数学)
- 给winpe添加explorer教程(上):基础知识及explorer的初步加入
- C#(.net) MySql数据库链接工具类
- No.1 iOS---UI学习第一天(笔记)(以及为什么模拟器上不显示我们添加的控件的解决办法)
- 很有用的快捷键