【以下就是关于数组的所有内容,如果您觉得这篇文章很好,请打赏一点心意,谢谢大家的支持】
第一节 一维数组
一、为什么要为什么要使用数组
通过前面几章的学习,我们已经可以编写程序来解决各种相当复杂的问题了,但是当需要处理的数据比较多时,仅依靠前面的知识是不够的,即使简单的问题也可能需要比较复杂的程序来处理。请看下面的例子:
例题:输入50个学生的某门课程的成绩,打印出低于平均分的学生序号与成绩。
【分析】在解决这个问题时,虽然可以通过一个变量来累加读入的50个成绩求出学生的总分,进而求出平均分。但因为只有读入最后一个学生的分数后才能求得平均分,并且要求打印出低于平均分的学生序号和成绩,故必须把50个学生的成绩都保留起来,然后逐个和平均分比较,把低于平均分的成绩打印出来。如果,用简单变量a1,a2,…,a50存储这些数据,要用50个变量保存输入的数据,程序片断如下:
cin>>a1>>a2>>…>>a10;
…
cin>>a41>>a42>>…>>a50;
注意,如果真正要像上面这样编写程序,则上面的所有省略号必须用完整的语句写出来。可以看出,这样的程序是多么繁琐。如果说处理的数据规模达到成千上万,上面的例子单单读入就会异常复杂,电脑的优势没有得到体现。
从以上的讨论可以看出,如果只使用简单变量处理大量数据,就必须使用大量只能单独处理的变量,即使是简单问题也需要编写冗长的程序。
选手们可能已经看出,我们需要把一大批具有相同性质的数据组合成一个新类型的变量,可以用简单的程序(比如循环50次)对这个新变量的各个分量进行相同的处理,每个分量仍然保留单个变量的所有性质(在上面的例子中,各分量是整型变量或实型变量的性质)。
如果能像数学中使用下标变量ai形式表示这50个数,则问题就容易实现。在C++语言中,具有下标性质的数据类型是数组。如果使用数组,上面的问题就变得十分简单、清晰。例如,读入50个学生的成绩,只需写如下语句即可:
for (int i=1;i<=50;++i) cin>>a[i];
在这里引用了带下标的变量(分量变量称为数组元素)a[i]来代替a1,a2…,a50,方括号中的i称为下标,当循环变量i=1时a[i]就是a[1];当i=2时a[i]就是a[2]……;当i=50时a[i]就是a[50]。输入的时候,让i从1变化到50,循环体内输入语句中的a[i]也就分别代表了a1,a2…,a50这50个带下标的变量。这样上述问题的程序可写为:
int tot = 0; // tot存储50个学生的总分 for (int i=1;i<=50;++i) // 循环读入每一个学生的成绩,并把它累加到总分中 { cin>>a[i]; tot+=a[i]; } float ave= tot/50; //计算平均分 for (int i=1;i<=50;++i) if (a[i]<ave) cout<<"No. "<<i<<" "<<a[i]; //如果第i个同学成绩小于平均分,则将输出这个学生的序号和成绩。
要在程序中使用下标变量,必须先说明这些下标变量的整体为数组,即数组是若干
个同名(如上面的下标变量的名字都为a)下标变量的集合,这些变量的类型全部一致。
二、一维数组的定义
当数组中每个元素只带有一个下标时,我们称这样的数组为一维数组。
数组的定义格式如下:
类型标识符 数组名[常量表达式]
说明:
①数组名的命名规则与变量名的命名规则一致。
②常量表达式表示数组元素的个数。可以是常量和符号常量,但不能是变量。 例如:
int a[10]; //数组a定义是合法的
int b[n]; //数组b定义是非法的
其中,a是一维数组的数组名,该数组有10个元素,依次表示a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]需要注意的是:a[10]不属于该数组的空间范围。当在说明部分定义了一个数组变量之后,C++编译程序为所定义的数组在内存空间开辟一串连续的存储单元,每个数组第一个元素的下标都是0,因此第一个元素为第0个数组元素。例如:上例中的a数组在内存的存储如表所示:
a数组共有10个元素组成,在内存中10个数组元素共占10个连续的存储单元。a数组最小下标为0,最大下标9。按定义a数组所有元素都是整型变量。
三、一组数组的引用
通过给出的数组名称和这个元素在数组中的位置编号(即下标),程序可以引用这个数组中的任何一个元素。
一维数组元素的引用格式:
数组名[下标]
例如:若i、j都是int型变量,则
a[5]
a[i+j]
a[i++]
都是合法的元素。
说明:
(1)下标可以是任意值为整型的表达式,该表达式里可以包含变量和函数调用。引用时,下标值应在数组定义的下标值范围内。
(2)数组的精妙在于下标可以是变量,通过对下标变量值的灵活控制,达到灵活处理数组元素的目的。
(3)C++语言只能逐个引用数组元素,而不能一次引用整个数组。
(4)数组元素可以像同类型的普通变量那样使用,对其进行赋值和运算的操作,和普通变量完全相同。 例如: c[10]=34;实现了给c[10]赋值为34。
四、一维数组的初始化
数组的初始化可以在定义时一并完成。格式:
类型标识符 数组名[常量表达式]={值1,值2,…}
例如:
int a[5]={1,2,3,4,5}
说明:
(1)在初值列表中可以写出全部数组元素的值,也可以写出部分。例如,以下方式可以对数组进行初始化:
int x[10]={0,1,2,3,4};
该方法仅对数组的前5个元素依次进行初始化,其余值为0。
(2)对数组元素全部初始化为0,可以简写为:{}。
例如:
int a[5]={}; 将数组a的5个元素都初始化为0。
【说明】 程序1、程序2和程序3的区别在于数组定义在int main()之外与之内,程序1中数组定义放在int main()之外,其初始值是0值。程序2中数组定义放在int main()之内,其初始值是随机的。程序2中数组定义放在int main()之内,只给a[0]、a[1]赋初值,但后面的a[2]~a[4]元素自动赋0值。
五、数组越界
C++语言规定,使用数组时,要注意:
(1)、数组元素的下标值为非负整数。
(2)、在定义元素个数的下标范围内使用。
然而,当在程序中把下标写成负数、大于数组元素的个数时,程序编译的时候是不会出错的。例如:
int a[10];
a[-3]=5;
a[20]=15;
a[10]=20;
int k=a[30]
这些语句的语法是正确的,能够通过程序的编译。然而,它们要访问的数组元素并不在数组的存储空间的,这种现象叫数组越界。例如下面程序:
#include<iostream> using namespace std; int main() { int a[5]; for (int i=0;i<=10;i++) { a[i]=i; cout<<a[i]<<" "; } return 0; }
【说明】
该程序能够通过编译,也能运行出结果,程序的问题是定义a[5],使用时数组下标超过了4。C++语言中,数组越界访问系统时不一定会给出任何的提示,也就是说,程序可以超出数组边界进行读/写,从而造成内存的混乱。
数组越界是实际编程中常见的错误,而且这类错误往往难以捕捉。因为越界语句本身并不一定导致程序立即出错,可能在遇到某些数据时才导致错误,有时由于越界,意外地改变了变量或指令,导致在调试器里调试的时候,程序不按照应当的次序运行的怪现象。
六、一维数组的应用
例5.1
题目:
输入n个数,要求程序按输入时的逆序把这n个数打印出来,已知整数不超过100个。也就是说,按输入相反顺序打印这n个数。
【分析】
我们可定义一个数组a用以存放输入的n个数, 然后将数组a中的内容逆序输出。
答案:
#include<bits/stdc++.h>//bits/stdc++.h,万能头代码
using namespace std;
/*
1.首先我们要定义一个数组a和两个变量n,x
2.然后用while循环输入数组a
3.随后用for循环倒序输出数组a
4.最后代码结束return 0
*/
int a[1000],x,n;//定义a数组和x,n变量。注意:在main函数的外面时,初始值为0。a数组可以定大一点
int main(){//定义main函数
while(cin>>a[n]){//while循环
cin>>a[n++]=x;//输入数组a相当cin>>a[n]=x;n++;
}
for(int i=0;i<n;i++){//for循环
cout<<a[n-i];//输出a数组中的地n-i项,倒序输出
}
return 0;//代码结束
}
【说明】:
语句int a[100]声明了一个包含100个整型变量的数组,它们是:a[0],a[1],a[2],…,a[99]。注意,没有a[100]。在上述程序中,数组a被声明在main函数的外面。只有放在外面时,数组a才可以开得很大;放在main函数内时,数组稍大就会异常退出。它的道理将在后面讨论,只需要记住规则即可。
数组不能够进行赋值操作:如果声明的是int a[MAXN],b[MAXN],是不能赋值b=a的(Pascal语言可以的)。如果要从数组a复制k个元素到数组b,可以这样做:memcpy(b,a,sizeof(int)*k)。当然了,如果数组a和b都是浮点型的,复制时要写成memcpy(b,a,sizeof(double)*k)。如果需要把数组a全部复制到数组b中,可以写得简单一些:memcpy(b,a,sizeof(a))。使用memcpy函数要包含头文件cstring。
例5.2
题目:
将a数组中第一个元素移到数组末尾,其余数据依次往前平移一个位置。
【分析】
为完成题目所要求的操作,其算法应该包括以下几个主要步骤:
①把第一个元素的值取出放在一个临时单元 temp中;
②通过 a[2]→a[1], a[3]→a[2], a[4]→a[3],……, a[n]→a[n-1],实现其余元素前移
答案:
#include<iostream>
#include<iomanip> //调用setw函数需注明使用该库
const int n=10;
using namespace std;
int a[n],temp;
int main()
{
cout<<"read "<<n<<" datas"<<endl;
for (int i=0; i<n; ++i) cin>>a[i];
temp=a[0];
for (int i=0; i<n-1; ++i) a[i]=a[i+1];
a[n-1]=temp;
cout<<"Result:"<<endl;
for (int i=0; i<n; ++i) cout<<setw(3)<<a[i]; //setw函数控制输出场宽
return 0;
}
运行结果 :
read 10 datas: | Result: |
1 2 3 4 5 6 7 8 9 10 | 2 3 4 5 6 7 8 9 10 1 |
例5.3
题目:
宾馆里有一百个房间,从1-100编了号。第一个服务员把所有的房间门都打开了,第二个服务员把所有编号是2的倍数的房间“相反处理”,第三个服务员把所有编号是3的倍数的房间作“相反处理”…,以后每个服务员都是如此。当第100个服务员来过后,哪几扇门是打开的。(所谓“相反处理”是:原来开着的门关上,原来关上的门打开。)
【分析】
此题较简单,用a[1],a[2],…,a[n]表示编号为1,2,3,…,n的门是否开着。模拟这些操作即可,参考程序如下:
答案:
#include<cstdio>
#include<cstring>
#define MAXN 100+10
int a[MAXN];
int main()
{
int n,k,first=1;
memset(a,0,sizeof(a));
for (int i=1;i<=100;++i)
for (int j=1;j<=100;++j)
if (j%i==0) a[j]=!a[j];
for (int i=1;i<=100;++i)
if (a[i])
{
if(first) first=0;
else printf(" ");
printf("%d",i);
}
printf("\n");
return 0;
}
运行结果:
1 4 9 16 25 36 49 64 81 100
【说明】:
memset(a,0,sizeof(a))的作用是把数组a清零,它在cstring中定义。虽然也能用for循环完成相同的任务,但是用memset又方便又快捷。另一个技巧在输出:为了避免输出多余空格,设置了一个标志变量first,可以表示当前要输出是否为第一个。第一个变量前不应该有空格,但其他都有
第二节 二维数组
一、二维数组的定义
当一维数组元素的类型也是一维数组时,便构成了“数组的数组”,即二维数组。二维数组定义的一般格式:
数据类型 数组名[常量表达式1] [常量表达式2] ;
例如:int a[4][10]; a数组实质上是一个有4行、10列的表格,表格中可储存40个元素。第1行第1列对应a数组的a[0][0],第n行第m列对应数组元素a[n-1][m-1]。 说明:当定义的数组下标有多个时,我们称为多维数组,下标的个数并不局限在一个或二个,可以任意多个,如定义一个三维数组a和四维数组b:
int a[100][3][5];
int b[100][100][3][5];
多维的数组引用赋值等操作与二维数组类似。
二、二维数组元素的引用
二维数组的数组元素引用与一维数组元素引用类似,区别在于二维数组元素的引用必须给出两个下标。
引用的格式为:
<数组名>[下标1][下标2] 说明:显然,每个下标表达式取值不应超出下标所指定的范围,否则会导致致命的越界错误。
例如,设有定义:int a[3][5];
则表示a是二维数组(相当于一个3*5的表格),共有3*5=15个元素,它们是:
a[0][0] a[0][1] a[0][2] a[0][3] a[0][4]
a[1][0] a[1][1] a[1][2] a[1][3] a[1][4]
a[2][0] a[2][1] a[2][2] a[2][3] a[2][4]
因此可以看成一个矩阵(表格),a[2][3]即表示第3行第4列的元素。
三、二维数组的初始化
二维数组的初始化和一维数组类似。可以将每一行分开来写在各自的括号里,也可以把所有数据写在一个括号里。
例如:
int direct[4][2] = { {1,0},{0,1},{-1,0},{0,-1}}
int direct[4][2] = {1,0,0,1,-1,0,0,-1} //尽量不要用
四、二维数组程序设计
例5.8
题目:
设有一程序
程序的输入: | 程序的输出: |
2 1 3 | 2 3 1 |
3 3 1 | 1 3 2 |
1 2 1 | 3 1 1 |
答案:
#include<cstdio>
#include<iostream>
#include<iomanip>
const int n=3;
using namespace std;
int a[n+1][n+1];
int main()
{
for (int i=1; i<=n; ++i)
{
for (int j=1; j<=n; ++j)
cin>>a[i][j];
}
for (int i=1; i<=n; ++i)
{
for (int j=1; j<=n; ++j)
cout<<setw(5)<<a[j][i];
cout<<endl;
}
return 0;
}
例5.9
题目:
已知一个6*6的矩阵(方阵),把矩阵二条对角线上的元素值加上10,然后输出这个新矩阵。
【分析】
矩阵即表格,是一个二维数组,有6行6列共36个元素,每个矩阵都有二条对角线,本题难点在于对角线的元素怎么确定。
答案:
#include<iostream>
#include<iomanip>
using namespace std;
int a[7][7];
int main()
{
for (int i=1; i<=6; ++i) //输入矩阵元素
for (int j=1; j<=6; ++j)
cin>>a[i][j];
for (int i=1; i<=6; ++i) //更改对角线上元素的值
for (int j=1; j<=6; ++j)
if ((i==j)||(i+j==7)) a[i][j]+=10; //寻找对角线的特征
for (int i=1; i<=6; ++i) //输出6行6列的矩阵元素
{
for (int j=1; j<=6; ++j)
cout<<setw(5)<<a[i][j]; //setw(5) 是 iomanip 头文件中的操作符,它的作用是设置输出的宽度为5个字符的宽度。如果输出内容的宽度小于5个字符,会在左边填充空格(默认是右对齐)。
cout<<endl;
}
return 0;
}
例5.10
题目:
大部分元素是0的矩阵称为稀疏矩阵,假设有k个非0元素,则可把稀疏矩阵用K*3的矩阵简记之,其中第一列是行号,第二列是列号,第三列是该行、该列下的非元素的值。如:
0 0 0 5 写简记成: 1 4 5 //第1行第4列有个数是5 0 2 0 0 2 2 2 //第2行第2列有个数是2 0 1 0 0 3 2 1 //第3行第2列有个数是1 试编程读入一稀疏矩阵,转换成简记形式,并输出。
【分析】
本题中需要解决的主要问题是查找非零元素并记忆位置。将原始矩阵存于数组a。转换后的矩阵存于数组b,当然b数组的行数可以控制在一个小范围内
答案:
#include<bits/stdc++.h>
using namespace std;
const int n=3,m=5;
int main(){
int a[n+1][m+1],b[101][4],k=0;
for(int i=1; i<=n; ++i){ //矩阵初始
for(int j=1; j<=m; ++j){
cin>>a[i][j];
}
for (int i=1; i<=n; ++i){
for (int j=1; j<=m; ++j){
if (a[i][j]!=0){ //找到非零值,存储
++k;
b[k][1]=i;
b[k][2]=j;
b[k][3]=a[i][j];
}
}
}
}
for (int i=1; i<=k; ++i){ //输出
for (int j=1; j<=3; ++j){
cout<<setw(3)<<b[i][j];
cout<<endl;
}
return 0;
}
运行结果:
输入: | 输出: |
0 0 0 0 5 | 1 5 5 |
0 0 4 0 0 | 2 3 4 |
1 0 0 0 1 | 3 1 1 |
3 5 1 |
第三节 字符数组和字符串类型
无论数组的下标有几个,类型如何,但数组中全体元素的类型必须相同。数组元素的类型可以是任何类型,当它是字符型时,我们称它为字符数组。由于字符数组与字符类型的应用是计算机非数值处理的重要方面之一,所以我们把它们两个放在一起进行讨论。
下面我们举例说明字符数组的应用。
一、字符类型
字符类型为由一个字符组成的字符常量或字符变量。
字符常量定义:
const
字符常量=‘字符’
字符变量定义:
char 字符变量;
字符类型是一个有序类型, 字符的大小顺序按其ASCⅡ代码的大小而定。
例5.14
题目:
按字母表顺序和逆序每隔一个字母打印。即打印出:
a c e g i k m o q s u w y z x v t r p n l j h f d b
答案:
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
for (char letter='a'; letter<='z'; letter+=2)
cout<<setw(3)<<letter;
cout<<endl;
for (char letter='z'; letter>='a'; letter-=2)
cout<<setw(3)<<letter;
return 0;
}
【说明】
程序中,我们利用了字符类型是顺序类型这一特性,灵活利用字符变量当作循环变量,使程序处理起来比较直观。
二、字符数组
字符数组是指元素为字符的数组。字符数组是用来存放字符序列或字符串的。字符数组也有一维、二维和三维之分。
1、字符数组的定义格式
字符数组定义格式同于一般数组,所不同的是数组类型是字符型,第一个元素同样是从ch1[0]开始,而不是ch1[1]。具体格式如下:
[存储类型] char 数组名[常量表达式1]…
例如:
char ch1[5]; //数组ch1是一个具有5个字符元素的一维字符数组
char ch2[3][5]; //数组ch2是一个具有15个字符元素的二维字符数组
2.字符数组的赋值
字符数组赋值类似于一维数组,赋值分为数组的初始化和数组元素的赋值。初始化的方式有用字符初始化和用字符串初始化两种,也有用初始值表进行初始化的。
(1).用字符初始化数组
例如:
char chr1[5]={‘a’,‘b’,‘c’,‘d’,‘e’};
初始值表中的每个数据项是一个字符,用字符给数组chr1的各个元素初始化。当初始值个数少于元素个数时,从首元素开始赋值,剩余元素默认为空字符。
字符数组中也可以存放若干个字符,也可以来存放字符串。两者的区别是字符串有一结束符(‘\0’)。反过来说,在一维字符数组中存放着带有结束符的若干个字符称为字符串。字符串是一维数组,但是一维字符数组不等于字符串。
例如:
char chr2[5]={‘a’,‘b’,‘c’,‘d’,‘\0’}; 即在数组chr2中存放着一个字符串“abcd”。
(2).用字符串初始化数组 用一个字符串初始化一个一维字符数组,可以写成下列形式: char chr2[5]=“abcd”;
使用此格式均要注意字符串的长度应小于字符数组的大小或等于字符数组的大小减1。同理,对二维字符数组来讲,可存放若干个字符串。可使用由若干个字符串组成的初始值表给二维字符数组初始化。
例如:char chr3[3][4]={“abc”,“mno”,“xyz”};在数组ch3中存放3个字符串,每个字符串的长度不得大于3。
(3).数组元素赋值
字符数组的赋值是给该字符数组的各个元素赋一个字符值。
例如:
char chr[3];
chr[0]=‘a’; chr[1]=‘b’;chr[2]=‘c’;
对二维、三维字符数组也是如此。当需要将一个数组的全部元素值赋予另一数组时,不可以用数组名直接赋值的方式,要使用字符串拷贝函数来完成。
(4).字符常量和字符串常量的区别
①两者的定界符不同,字符常量由单引号括起来,字符串常量由双引号括起来。
②字符常量只能是单个字符,字符串常量则可以是多个字符。
③可以把一个字符常量赋给一个字符变量,但不能把一个字符串常量赋给一个字符变量。
④字符常量占一个字节,而字符串常量占用字节数等于字符串的字节数加1。增加的一个字节中存放字符串结束标志‘\0’。例如:字符常量‘a’占一个字节,字符串常量“a”占二个字节。
三、字符串的输入与输出
字符串可以作为一维字符数组来处理,那么字符串的输入和输出也可以按照数组元素来处理,本节不再做介绍。本节仅介绍将字符串作为一个整体进行输入和输出的语句。
1、输入
从键盘输入一个字符数组可以使用scanf语句或gets语句。
(1)scanf语句
格式:scanf(“%s”,字符串名称);
说明:
①这里的字符串名称之前不加&这个取地址符。例如:scanf(“%s”,&s1)是错误的。
②系统会自动在输入的字符串常量后添加‘\0’标志,因此输入时,仅输入字符串的内容即可。
③输入多个字符串时,以空格分隔。
例如:scanf(“%s%s%s”,s1,s2,s3);从键盘分别输入Let us go,则三个字符串分别获取了三个单词。反过来可以想到,如果仅有一个输入字符串名称的情况下,字符串变量仅获取空格前的内容。
例如:scanf(“%s”,s1);从键盘分别输入Let us go,则仅有第一个单词被获取,即s1变量仅获取第一个单词Let。
(2)gets语句
格式:gets(字符串名称);
说明: 使用gets只能输入一个字符串。
例如:gets(s1,s2);是错误的。使用gets,是从光标开始的地方读到换行符也就是说读入的是一整行,而使用scanf是从光标开始的地方到空格,如果这一行没有空格,才读到行尾。
例如:scanf(“%s”,s1);gets(s2);对于相同的输入Hello World!。s1获取的结果仅仅是Hello,而s2获取的结果则是Hello World!
2、输出
向屏幕输出一个字符串可以使用printf语句或puts语句。
(1)printf语句
格式:printf(“%s”,字符串名称);
说明:
①用%s格式输出时,printf的输出项只能是字符串(字符数组)名称,而不能是数组元素。例如:printf(“%s”,a[5]);是错误的。
②输出字符串不包括字符串结束标志符‘\0’。
(2) puts语句
格式:puts(字符串名称);
说明:puts语句输出一个字符串和一个换行符。对于已经声明过的字符串a,printf(“%s\n”,a)和 puts(a)是等价的。
例5.15
题目:
在应用计算机编辑文档的时候,我们经常遇到替换任务。如把文档中的“电脑”都替换成“计算机”。现在请你编程模拟一下这个操作。
输入两行内容,第1行是原文(长度不超过200个字符),第2行包含以空格分隔的两个字符A和B,要求将原文中所有的字符A都替换成字符B,注意:区分大小写字母。
输入样例:
I love China. I love Beijing.
I U
输出样例:
U love China. U love Beijing.
【分析】
首先要将给定的原文保存在字符数组里。然后,在原文中,从头开始寻找字符A,找到一个字符A,便将其替换成字符B;继续寻找下一个字符A,找到了就替换,……,直到将原文都处理完。如下程序只能处理单个字符替换,无法处理单词替换,I U中间只能有一个空格。
答案:
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{ char st[200];
char A,B; int i,n=0;
while((st[n++]=getchar())!='\n'); //将原文存放在字符数组st中
A=getchar();getchar();B=getchar(); //读取A和B,中间getchar()读空格
for (i=0;i<n;i++)
if (st[i]==A) cout<<B;
else cout<<st[i];
cout<<endl;
return 0;
}
例5.16 过滤多余的空格【1.7编程基础之字符串23】
题目:
一个句子中也许有多个连续空格,过滤掉多余的空格,只留下一个空格。
输入:一行,一个字符串(长度不超过200),句子的头和尾都没有空格。
输出:过滤之后的句子。
样例输入: Hello world.This is c language.
样例输出: Hello world.This is c language.
【分析】
scanf只能一个一个读“单词”,不读空格,while (scanf("%s",&st)==1)的功能是循环读入数据,在读不到的时候停止循环。
答案:
#include<cstdio>
using namespace std;
char st[200];
int main()
{
while (scanf("%s",&st)==1)
printf("%s ",st); //%s 后要有一个空格,不能省略
return 0;
}
例5.17
题目:
C++中,一个字符串中的字符可以通过其对应的下标灵活使用。
答案:
#include<cstdio> // gets()调用cstdio库
#include<iostream>
#include<cstring> //strlen()调用cstring库
using namespace std;
int main(){
char st[100];
gets(st); //gets为专门读字符串的函数, 读取一行字符串
for (int i=0; i<strlen(st); ++i){ //输出st串中的第i个字符
cout<<st[i];
}
return 0;
}
五、字符串处理函数
系统提供了一些字符串处理函数,用来为用户提供一些字符串的运算。常用的字符串函数介绍如下。
函数格式 | 函数功能 |
strcat(字符串名1,字符串名2) | 将字符串2连接到字符串1后边,返回字符串1的值。 |
strncat(字符串名1,字符串名2,长度n) | 将字符串2前n个字符连接到字符串1后边,返回字符串1的值。 |
strcpy(字符串名1,字符串名2) | 将字符串2复制到字符串1后边,返回字符串1的值。 |
strncpy(字符串名1,字符串名2,长度n) | 将字符串2前n个字符复制到字符串1后边,返回字符串1的值。 |
strcmp(字符串名1,字符串名2) | 比较字符串1和字符串2的大小,比较的结果由函数带回; 如果字符串1>字符串2,返回一个正整数; 如果字符串1=字符串2,返回0; 如果字符串1<字符串2,返回一个负整数; |
strncmp(字符串名1,字符串名2,长度n) | 比较字符串1和字符串2的前n个字符进行比较,函数返回值的情况同strcmp函数; |
strlen(字符串名) | 计算字符串的长度,终止符’\0’不算在长度之内 |
strlwr(字符串名) | 将字符串中大写字母换成小写字母 |
strupr(字符串名) | 将字符串中小写字母换成大写字母 |
例5.18
题目:
对给定的10个国家名,按其字母的顺序输出。
答案:
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s[25];
int n;
cin>>n;
for (int i=1; i<=n; i++)
cin>>s[i];
for (int i=1;i<=n-1; i++){
int m=i;
for (int j=i+1; j<=n; j++){
if (s[j]<s[m])
m=j;
}
swap(s[m],s[i]);
}
for (int i=1; i<=n; i++)
cout<<s[i]<<endl;
return 0;
}
例5.19 字符串判等【1.7编程基础之字符串17】
题目:
判断两个由大小写字母和空格组成的字符串在忽略大小写,且忽略空格后是否相等。
【输入】
两行,每行包含一个字符串。
【输出】
若两个字符串相等,输出YES,否则输出NO。
【输入样例】
a A bb BB ccc CCC Aa BBbb CCCccc
【输出样例】
YES
答案:
#include<bits/stdc++.h>
using namespace std;
char s1[105],s2[105];
int l1,l2,i=0,j=0;
int main()
{
cin.getline(s1,105);
cin.getline(s2,105);
l1 = strlen(s1); l2 = strlen(s2);
while(i<l1||j<l2)
{
if(s1[i]==' ') //跳过第1串空格
i++;
else if(s2[j]==' ') //跳过第2串空格
j++;
else
{
if(s1[i]==s2[j]||s1[i]==s2[j]+32||s1[i]+32==s2[j]) //大小写判断
{
i++; j++;
}
else
{
cout<<"NO";
return 0;
}
}
}
cout<<"YES";
return 0;
}
例5.20 字符串移位包含问题【1.7编程基础之字符串19】
题目:
对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串。
给定两个字符串s1和s2,要求判定其中一个字符串是否是另一字符串通过若干次循环移位后的新字符串的子串。例如CDAA是由AABCD两次移位后产生的新串BCDAA的子串,而ABCD与ACBD则不能通过多次移位来得到其中一个字符串是新串的子串。
【输入】
一行,包含两个字符串,中间由单个空格隔开。字符串只包含字母和数字,长度不超过30。
【输出】
如果一个字符串是另一字符串通过若干次循环移位产生的新串的子串,则输出true,否则输出false。
【输入样例】
AABCD CDAA
【输出样例】
true
答案:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=61;
char s1[N],s2[N],x[N],t[N];
int l1,l2;
int main(){
scanf("%s%s",&s1,&s2);
if (strlen(s1)<strlen(s2)){ //将长度短的字符串作为预判断字串
strcpy(t,s1);
strcpy(s1,s2);
strcpy(s2,t); //将s1,s2互换
}
strcpy(x,s1);
if (strstr(strcat(s1,x),s2)==NULL){
printf("false\n"); //strstr(s1,s2)函数用于判断字符串s2是否是s1的子串
//如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL
}else{
printf("true\n");
}
return 0;
}
标签:题型,变量,字符,int,元素,附多道,第五章,数组,字符串
From: https://blog.csdn.net/m0_72568314/article/details/145230918