数组总结

一维数组

  • 数组相当于一个容器,开一个连续的空间,将所需要的数据储存起来,同时可以通过下标引用
  • 数组名代表数组名称,同时代表了数组首位置,因此,不能通过将数组名复制到另一个数组
  • 数组内的所有变量的类型都是相一致的
  • 数组定义时元素的总个数只能用常量定义,包括常量和符号常量,但是变量是不合法的
  • int a[10];   //数组定义是合法的          int b[n];    //数组定义是非法的
  • 数组引用    下标可以是任意值为整型的表达式,下标可以是变量,引用时只能逐个引用,不能一次引用一个数组                                                                         memset(a,0,sizeof(a))将数组中的元素全部赋值为0,或者为-1,头文件为cstring
  • 初始化     可以全部列举出来,也可以写一部分,全局变量初始化为0;但是局部变量没有初始化,给的都是随机数
  • 数组越界    下标值为整数,从0开始,若下标为负或者大于元素个数,语法都是正确的,但数组元素不在数组的储存空间,造成内存混乱
  • 应用     开数组时将数组在全局变量中定义,数组可以开的很大,并且数组所有元素初始化为0                                                                                                         从数组a复制k个元素到数组b,可以memcpy(b,a,sizeof(int)*k)也可以定义不同的类型,头文件为cstring       

二维数组

  • 二维数组和一维数组的定义,引用,初始化都相似,二维数组和一维数组在计算机中所开的空间是一样的
  • 二维数组也是数组的数组,同样,当下标有多个时,可以定义多维数组,应用和二维数组相似
  • 二维数组引用时必须给出两个下标,每个下标的取值不能超过指定范围,否则导致越界错误
  • 初始化可以将每一行分开写在括号里,也可以把所有数据写在一个括号里 ,数据赋值时先排行排列
  • 二维数组和矩阵相似,从而可以计算矩阵的转置,交换行,加法和乘法的运算

字符类型和字符数组

  • 无论数组的下标有几个,数组中的元素的类型必须相同,类型可以是任意类型,是字符型时,我们称它为字符数组
  • 字符类型有常量和字符变量,定义使用单引号引起来,字符类型是一个有序数列,从而可以利用字符变量,作为循环变量使用
  • 元素为字符的数组为字符数组,可以存放字符序列和字符串,同时也有一维二维和三维之分
  • 赋值分为初始化和元素的赋值,可以用字符初始化也可以用字符串初始化,字符用单引号引起来,字符串用双引号引起来,并且有结束符\0
  • 字符串中,结束符占用一个字节,因此字符串常量占用字节数等于字符串的字节数加1
  • 可以把字符常量赋给字符变量,但不能把字符串常量赋给字符串变量
  • 输入输出       键盘输入字符数组可以使用scanf语句和gets语句
  • 输入字符串时,不用加取地址符,系统自动加上结束符
  • scanf语句不能读取回车键和空格键,gets只能输入一个字符串,可以读取一行
  • 输出字符串可以使用printf语句和puts语句
  • printf语句输出字符串不包括结束符,puts语句一个字符串和一个换行符

典型例题

1.约瑟夫问题(n个人围成圈报数,猴子选大王,持密码报数,狐狸追兔子)

设置一个标记数组,一个人有两种状态,出圈和未出圈;数到最后一个人,再到第一个人;当所有人都出圈,停止,也就是出圈的人数有n个人,停止

for(i=1;i<=n;i++)

a[i]=false;

f=0,t=0,s=0;

while(f!=n)

{

      ++t;

     if(t==n+1)t=1;

     if(a[t]==false)++s;

     if(s==m)

    {

           s=0;

           cout<<t<<" ";

           a[t]=true;

           ++f;

      }

}

大多数题用到标记数组,或者标记变量,使用标记变量可以是许多问题变得更简单

标记变量:有趣的跳跃,计算鞍点,寻找配对数

标记数组:校门外的树,开关门问题,开关灯问题

2.排序问题(选择排序,冒泡排序,插入排序,桶排序)

sort(a,a+n)前闭后开,默认从小到大排序,也可以自定义函数完成其他排序,头文件algorithm

选择排序:每一次选出一个最小的数,下一次再从剩余数中选出最小的,以此类推,完成排序

冒泡排序:每一次将最大的数排到后面,再将前面的数重复操作,完成从小到大排序

插入排序:在一个有序的数列,和中间的数比较,找到一个合适的位置插入,取中间数,即为二分法。

                 如果是无序数列,但在这个数列中总有一个数是有序的,以这个数为有序数列,将其它的数插入,完成排序

桶排序:开一个较大的数组,将数组清零,如果数据中出现了该数,所对下标的数加加,最后按数组输出即可

例题:有趣的跳跃用到排序,倒置排序(可以开两个数组,两个数组一起进行变化)

寻找配对数问题优化(排序,折半查找,预处理)

将所给的数据排序,预处理用数组存起来,两个循环嵌套,将两个数的乘积在预处理的数组中折半查找,判断是否存在

3.筛法,预处理找素数,完全平方数

for(i=2;i<=n;i++)

a[i]=1;

for(i=2;i<=sqrt(n);i++)

if(a[i])

for(j=2;j<=n/i;j++)

a[i*j]=0;

4.与矩阵有关的问题

矩阵也就是二维数组,有简单的问题,例如,交换两行两列的数据,转置,交换行列,求某行,列数据的和

例题:变换的矩阵,矩阵交换行,蛇形填充数组,计算鞍点等

5.字符数组

scanf输入时,不能加取地址符,不能读取空格

统计单词个数,可以通过空格来简单计算,和将单词首字母换成大写方法一样

大小写转化,数值相差32,通过32转化即可,也可以用字符处理函数(strlwr   大写换小写    strupr  小写换大写)

例题:反反复复,字符串hash

6.对数组内周期赋值

石头剪刀布(周期为m,总数为n,已知第一个周期内的数值)

for(i=1;i<=m;i++)

for(j=m+1;j<=n;j+=m)

a[j]=a[i];

7.相似类型题

扫雷,细菌的繁殖与扩散

注意题意分析,通过一个量确定另一个量的变化,分析好哪一个量,梳理好逻辑关系

总结

   课程已经学了很多了,感觉程序写起来也简单也难,写出一个程序并且编译成功很简单,但是要输出相应的结果很难,这也是一个思维的锻炼,往往我们缺少的就是这样的锻炼。参加了acm新生赛,发现自己学的也就只是冰山一角,看见一个题,对它题意的分析,理解不到位,并且容易忽略了时间复杂度,出现超时现象,或者是定义的量太小。各种毛病都出现了,从而提醒了我要更加努力的学习,多分析题,而不是单单停留在会做一道题,要学会扩展,深入理解一道题,而不是只看表面。我会更加努力去学习,期待19周上机,希望那时候的我会比现在更优秀!!

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值