《算法笔记》学习笔记——2.5数组

前言 

        为准备大四华为笔试,决定使用学长推荐的《算法笔记》一书来学习,配套有《算法笔记·上机训练实战指南》,希望学习完此书,刷完力扣,能够通过笔试,为拿到大厂offer奠定基础💪

        此文为笔记系列第五篇。




我的笔记

        1.数组就是相同数据类型的变量组合在一起的集合,每个变量都有其存放地址,数组就是从某个地址开始连续若干个位置形成的元素组合;数组的大小必须为整数常量,不可为变量;数组长度为size,只能访问下标为0~size-1的元素;

        2.数组初始化,使用{a[0],a[1],a[2],a[3],...,a[n-1]}来给数组a[n]赋初值,可以只给部分数据赋初值,未被赋初值的元素一般默认初值为0;

        ①未赋初值,数组元素数值随机

        ②部分元素赋初值,未被赋初值元素默认为0

        ③a[n]={0}或a[n]={},数组元素均为0

        3.递推是指不断让后一位的结果由前一位或几位计算得到;递推可以分为顺推和逆推;

        4.在练习书中关于递推的示例时,发现自己一个认知方面的问题

        该示例是使用顺推,使后一个元素等于前一个元素的两倍,我一开始的代码如下:

#include <stdio.h>

int main() {
	int a[10];
	a[0] = 1;        //   给数组中某一个元素赋值,不用大括号,将数组某一元素当作一个变量就好
	for(int i = 1; i<=9; i++) {
		printf("a[%d] = %d\n", i, 2*a[i-1]);
	}
	return 0;
}

        编译运行后发现除a[1]数值正确外,别的都是随机值,后仔细思索,发现我并未将得到的a[1]存储在a[1]中,只是将a[0]的数值乘以2输出出来,所以调用得a[1]的值还是编译器给的随机初值,循环无法顺推下去!这就是我认知上的问题了,归根结底还是没有了解计算机的特性,还需进一步学习了解代码运行的深层逻辑。

        回到该问题,添加一行代码即可:

#include <stdio.h>

int main() {
	int a[10];
	a[0] = 1;
	for(int i = 1; i<=9; i++) {
		a[i] = 2 * a[i - 1];        //将结果保存到对应的元素中
		printf("a[%d] = %d\n", i, a[i]);
	}
	return 0;
}

        另外为满足书中示例的手动输入a[0],将代码进行修改:

#include <stdio.h>

int main() {
	int a[10];
//	a[0] = 1;
//	a[0] = getchar();        
// 此处注意,getchar()为输入单个字符,输入为1时,会识别为ASCII码,1对应的ASCII码为49,
// 所以后续调用a[0]的数值为49
	scanf("%d", &a[0]);
	printf("a[0] = %d\n", a[0]);
	for(int i = 1; i<=9; i++) {
		a[i] = 2 * a[i - 1];
		printf("a[%d] = %d\n", i, a[i]);
	}
	return 0;
}

        

        5. 在练习书中冒泡排序的代码时,我深刻认识到之前书中一句话,if语句中的大括号不要轻易去掉😅我是笨蛋

        另外,我本想自己根据冒泡排序的思想写出对应代码,但最终写出了选择排序的代码,还是对冒泡排序理解不到位。

#include <stdio.h>

int change(int *x, int *y) {
	int t;
	t = *x;
	*x = *y;
	*y = t;
}        
//此处本想尝试函数调用,结果始终调用不了,
//搜索看到选择排序代码,发现使用了指针,暂时不懂,学完回来再看。

int main() {
	
	int a[5] = {3, 1, 4, 5, 2};
	int t, i, j;
	for(i = 0; i < 4; i++) {
		for(j = i + 1; j <= 4; j++) {
			if(a[i]>a[j]) {
			change(&a[i],&a[j]);
//				t = a[i];
//				a[i] = a[j];
//				a[j] = t;        //change函数完全可以用这三行代码代替
			}
		}	
	}
	for(i = 0; i <= 4; i++) {
		printf("a[%d] = %d\n", i, a[i]);	
	}
	return 0;
}

重新学习冒泡排序思想:本质为交换

它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。(来源于菜鸟教程)

        我的思考过程:先写出走一趟的程序,然后再外套走多趟的程序

        遇到的问题:怎样确认已经排好序?

        解决方案:通过思考走一趟怎样停止,结合冒泡排序具体过程,即可明确。

#include <stdio.h>

int main() {
	int a[5] = {3, 1, 4, 5, 2};
	int i, t, j; 
	int len = 5;        //len代指数组长度
	for(i = 0; i < len; i++) {        //i代表趟数,一共需要走(len-1)趟
		for(j = 0; j + 1 < len - i; j++) {        //走一趟,就有一个数固定,不需要再被比较交换
			if(a[j]>a[j+1]) {
				t = a[j];
				a[j] = a[j+1];
				a[j+1] = t;        //此处可以换为上个代码中的change函数
			}
		}		
	}
	for(i = 0; i <= 4; i++) {
		printf("a[%d] = %d\n", i, a[i]);	
	}
	return 0;
}

        6.二维数组a[m][n]可以看作m个长度为n的一维数组,初始化与一维数组类似,例如:

   a[3][4] ={ {1,2,3,4},{5,6,7,8},{9,10,11,12}  } 输出后为:

   a[3][4] ={ {1,2,3},{},{9,10}  } 输出后为:

        二维数组输入输出需要挨个输入输出。

        7.memset函数 对数组中的每一个元素赋相同的值

        memset(数组名,值,sizeof(数组名))                 //开头加string.h头文件

        //建议只给数组赋值为0或-1;赋其他值,使用fill函数

        //memset中第三个注意不可以直接写数组a的长度,如5,否则数组值不全为0

#include <stdio.h>
#include <string.h>

int main() {
	int a[5];
	memset(a, 0, sizeof(a));
	for(int i = 0; i<5; i++) {
		printf("%d ", a[i]);
	}
	printf("\n");
	memset(a, -1, sizeof(a));
	for(int i = 0; i<5; i++) {
		printf("%d ", a[i]);
	}
	return 0;
}

         8.字符数组初始化:可以和普通数组一样赋值单个字符;也可以直接赋值整个字符串(这种操作仅限于初始化操作);注意初始化操作是指在定义变量时便给变量赋值,定义后的赋值不算是初始化操作!

        字符数组输入输出:

        ①scanf printf  %c 输入单个字符,可输入空格;%s输入字符串赋值给字符数组,以空格和换行来判定输入结束;另外,scanf("%s", str)  其中,str前无需取地址符&

        ②getchar()、putchar(): 只用来输入输出单个字符注意输入输出时换行符的处理

        ③gets、puts:gets输入一行字符串(以换行符判断结束),将其存放于一维数组或二维数组的一维中; puts输出一行字符串(紧跟一个换行符)

char str1[20], str2[5][10];

gets(str1);

gets(str2[2]);

puts(str1);

puts(str2[2]);

         字符串存储方式:

        在一维数组或者二维数组第二维的末尾会有一个空字符\0,表示存放字符串的末尾;

        ①③两种输入方式会自动填补空字符,②getchar()输入需要在输入的每个字符串后面加如“\0”

        \0结束符ASCII码为0,占用一个字符位;空格ASCII 码为32;

        只有char字符数组末尾需要加空字符,因此字符数组的长度一定要比实际存储字符串长度至少多1

        9.用于字符数组的函数:                     <string.h>

用于字符数组的函数作用
strlen(字符数组)得到字符数组中第一个\0前面字符的个数
strcmp(字符数组1, 字符数组2)返回两字符数组大小的比较结果(按字典序)
strcpy(字符数组1, 字符数组2)把字符数组2复制给字符数组1,包括\0
strcat(字符数组1, 字符数组2)把字符数组2接到字符数组1后面

        10.sscanf和sprintf  

        sscanf = string + scanf                sprintf = string + printf

        sscanf(str, "%d", &n);                // 将字符串str从左到右输入到n中

        sprintf(str, "%d", n);                   // 将n从右到左写到字符串str中

        sscanf 和 sprintf 使用和 scanf 和 printf 类似。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值