《算法笔记》2.5数组

这篇博客主要介绍了C语言中的一维数组、冒泡排序算法、memset函数的使用,以及字符数组和字符串处理的相关知识。文章通过实例解析了冒泡排序的原理和注意事项,强调了大数组应在主函数外部定义以避免栈溢出。同时,讲解了字符数组的结束标识''的重要性,以及如何正确使用getchar和putchar。最后,列出了2.5章节的练习题目,涵盖数组操作、排序和字符串处理等主题。
摘要由CSDN通过智能技术生成

一、学习概览

数组
地址连续
元素集合
下标
2.5数组
2.5.1一维数组
2.5.2冒泡排序
最基础的排序算法
本质是交换
比较次数
2.5.3二维数组
2.5.4memset
对数组中每一个元素赋相同的值
要加string.h
相比fill执行速度快
此外还有fill函数
6.9
2.5.5字符char数组
1.字符数组的初始化
2.字符数组的输入输出
3.字符数组的存放方式
2.5.6string.h头文件
2.5.7sscanf与sprintf
sscanf=string+scanf
sprintf=string+printf

2.5.1一维数组

  1. 数组:长度为n,下标为0~(n-1)。
  2. 只要赋初值,没被赋值的默认初值为0;若未初始化,每个元素会是一个随机数。
  3. 给整个数组赋初值0:
    int a[10]={0};
    int a[10]={};
    //或者memset函数
  1. 递推:根据一些条件,不断让后一位的结果由前一位或前若干位计算得来。
递推
顺推
逆推

2.5.2冒泡排序

  1. 冒泡排序的比较次数:(假设排序的数字数为n)1+2+…+(n-1)
  2. 特别提醒:如果数组大小较大(大概10^6级别),则需要将其定义在主函数外面,否则会使程序异常退出,原因是函数内部申请的局部变量来自系统栈,允许申请的空间较小;而函数外部申请的全局变量来自静态存储区,允许申请的空间较大。

2.5.4memset

  1. memset函数:初学者只建议赋0或-1。其他用fill。

2.5.5字符char数组

  1. 字符数组就是char数组。
2.字符数组的输入输出
1.scanf输入-printf输出
2.2.2
2.getchar输入-putchar输出
单个字符2.2.3
3.gets输入-puts输出
字符串
  1. 对于scanf输入-printf输出,只有%c格式能够识别空格+换行并将其输入,%s格式以及其他(如%d)通过空格/换行来识别一个字符串的结束。
  2. 对于getchar输入-putchar输出,不需要格式控制符(都是char类型元素)。遇到换行/空格也会输出。
     getchar(); 
     putchar('\n');
  1. gets识别换行符\n作为输入结束——scanf完一个整数后,如果要使用gets,需要先用getchar接收整数后的换行符。puts输出字符串后,会紧跟一个换行。

  2. 输入输出的真正含义是:输入输出并存起。

  3. 空字符\0——表示存放的字符串的结尾。在使用gets或scanf时自动添加至末尾,并占用一个字符位,puts和printf通过识别\0来输出
    特别提醒1:①字符数组的长度>=实际存储字符串的长度+1;②只有char型数组末尾需要加\0,int型不需要;③\0和空格不同,\0的ASCII码是0(空字符NULL),空格的ASCII码是32。
    特别提醒2:如果不是使用scanf的%s格式或gets函数输入字符串(例如使用getchar),一定要在输入的每个字符串后加“\0”,否则printf和puts会因无法识别字符串末尾而输出一大堆乱码。见代码2.27

  4. ASCII ((American Standard Code for Information Interchange): 美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准ISO/IEC 646。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符 [1] 。
    ASCII码

2.5.6string.h头文件

  1. string.h包含的用于字符数组的函数:(使用时要在程序开头加上string.h)
    ①strlen()
    ②strcmp()
    字典序(a<b<c<…<z)。若str1<str2,返回负整数;str1==str2,返回0;str1>str2,返回正整数。
    ③strcpy()
    str2复制给str1,“复制”包括结束符\0
    ④strcat()
    str2接到str1后面
    #include <string.h>
    int len=strlen(str); //得到字符数组中第一个\0前的字符的个数
    
    int cmp=strcmp(str1,str2);//返回两个字符串大小的比较结果
    if(cmp<0) printf("str1<str2\n");   
    else if(cmp>0) printf("str1>str2\n");   
    else printf("str1==str2\n");
    
    strcpy(str1,str2);//把一个字符串复制给另一个字符串
    
    strcat(str1,str2);//把一个字符串接到另一个字符串后面

2.5.7sscanf与sprintf

  1. scanf与printf的另一种写法:(scanf从左至右,printf从右至左)
   scanf("%d",&n);
   scanf(screen,"%d",&n);
   printf("%d",n);
   printf(screen,"%d",n); //screen是屏幕
  1. sscanf与sprintf:(sscanf从左至右,sprintf从右至左。注意代码行2与行4的区别。)
   sscanf(str,"%d",&n);
   printf("%d",n); //初始化str,写到n里
   sprintf(str,"%d",n); //字符数组str
   printf("%d",str); //初始化n,写到str里
  1. sscanf还支持正则表达式。
    正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE)。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。许多程序设计语言都支持利用正则表达式进行字符串操作

二、代码分析

2.23 冒泡排序

#include <stdio.h>
int main(){
	int a[10]={3,1,4,5,2};
	for(int i=1;i<=4;i++){ //进行n-1趟
	//第i趟从a[0]到a[n-i-1]都与它们下一个数比较 
		for(int j=0;j<5-i;j++){
			if(a[j]>a[j+1]){ //如果左边的数更大,则交换a[j]和a[j+1] 
				int temp=a[j];
				a[j]=a[j+1];
				a[j+1]=temp;
			}		
    	}
    }
    for(int i=0;i<5;i++){
    	printf("%d",a[i]);
	}
	return 0;
}

2.23

思考:

把i打成了1。

2.24 三维数组自增1

三维数组

#include <stdio.h>
int main(){
	int a[3][3][3];
    for(int i=0;i<3;i++){
    	for(int j=0;j<3;j++){
    		for(int k=0; k< 3; k++){
    			scanf("%d",&a[i][j][k]); //输入三维数组a的元素
    			a[i][j][k]++; //自增 
			}
		}
	}
	for(int i=0;i<3;i++){
    	for(int j=0;j<3;j++){
    		for(int k=0; k< 3; k++){
    			printf("%d\n",&a[i][j][k]); //输出三维数组a的元素
			}
		}
	}
	return 0;
}

2.24
这…什么鬼

2.25 memset函数

#include <stdio.h>
#include <string.h>
int main(){
    int a[5]={1,2,3,4,5};
    //赋初值0
    memset(a, 0, sizeof(a));
    for(int i=0;i<5;i++){
        printf("%d", a[i]);
    }
    printf("\n");
    //赋初值-1
    memset(a,-1, sizeof(a));
    for(int i=0;i<5;i++){
    	printf("%d", a[i]);
	}
	printf("\n");
    return 0;
}

2.25
把-1改成1后:

#include <stdio.h>
#include <string.h>
int main(){
   int a[5]={1,2,3,4,5};
   //赋初值1
   memset(a,1, sizeof(a));
   for(int i=0;i<5;i++){
   	printf("%d", a[i]);
   }
   printf("\n");
   return 0;
}

把1改成-1后

2.26 getchar与putchar

#include <stdio.h>
int main(){
   char str[5][5];
   for(int i=0;i<3;i++){
   	for(int j=0;j<3;j++){
   		str[i][j]=getchar();
   	}
   	getchar(); //这句是为了把输入中每行末尾的换行符吸收掉
   } 
   for(int i=0;i<3;i++){
   	for(int j=0;j<3;j++){
   		putchar(str[i][j]);
   	}
   	putchar('\n');
   }
   return 0;
}

不加行8:

在这里插入图片描述
2.26

不加行14:

2.26

完整结论:

2.26

2.27 使用getchar,每个字符串后要加“\0”

#include <stdio.h>
int main(){
	char str[15];
	for(int i=0;i<5;i++){
		str[i]=getchar();
	} 
	puts(str);
	return 0;
}

2.27
不加也没有乱码呢。
2.27

三、2.5练习

A 习题6-4 有序插入

B 习题6-5 数组元素逆置

C 习题6-6 杨辉三角

D 习题6-12 解密

E 习题6-13 字符串比较

F 例题6-1 逆序输出数组元素

G 例题6-2 数组求解Fibonacci数列问题

H 例题6-3 冒泡排序

I 例题6-4 矩阵转置

J 例题6-9 字符串求最大值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值