数组
考点
-
排序
- 冒泡排序 O(n^2)
- 选择排序 O(n^2)
- (插入排序)
-
分离每一位
- 正序
- 字符串
- 栈(递归)
- 逆序
- 正序
-
哈希(hash) → 用值直接作为下标
-
数组的基本操作
- 插入和删除
- 逆序(移位)
-
日期处理问题
-
7 - 19田忌赛马 (双指针)
-
二维数组 → 矩阵
- 矩阵转置
- 判断对称矩阵
- 矩阵运算
- 矩阵移位
-
杨辉三角
用递归实现正序分离数的每一位
//递归边界
//n是个位数, 直接打印n
// 46666
// 4 6666
// 6 666
// 6 66
// 6 6
// 6
//递归式子
#include <stdio.h>
#include <stdio.h>
void print(int n) // n为待分离的数
{
if (n / 10 == 0)
{
printf("%d ", n);
}
else
{
print(n / 10);
printf("%d ", n % 10);
}
}
int main()
{
int n;
scanf("%d", &n);
print(n);
return 0;
}
数组的插入
数组的随机访问O(1)
q[] 0 ~ 100
访问数组中的第三个数
q[2]
访问数组中的第100个数
q[99]
数组的插入O(n)
值 1 2 4 5 6
下标 0 1 2 3 4
插入3 → 把3后面的元素全都往后移一位
值 1 2 3 4 5 6
下标 0 1 2 3 4 5
数组的删除O(n)
值 1 2 4 5 6
下标 0 1 2 3 4
删除4 → 把4后面的元素全都往前移一位
值 1 2 5 6
下标 0 1 2 3
//方法一: 先把待插入的数放到数组里, 然后对新的数组排序
#include <stdio.h>
int q[200];
int main()
{
int n, m;
while(scanf("%d %d", &n, &m) != EOF)
{
if(n == 0 && m == 0) break;
for (int i = 0; i < n; i++)
{
scanf("%d", &q[i]);
}
q[n] = m;
//n + 1个元素, 下标0 ~ n
//排序模板只需要把所有的n换成n + 1即可
for(int i = 1; i <= n; i++)
{
for(int j = 0; j < n + 1 - i; j++)
{
if(q[j] < q[j + 1])
{
int t = q[j];
q[j] = q[j + 1];
q[j + 1] = t;
}
}
}
for(int i = 0; i <= n; i++)
{
if(i)
{
printf(" %d", q[i]);
}
else printf("%d", q[i]);
}
printf("\n");
}
return 0;
}
//方法二、先找到插入的位置, 把后面的数整体后移一位, 插入元素
#include <stdio.h>
int q[200];
int main()
{
int n, m;
while (scanf("%d %d", &n, &m) != EOF)
{
if (n == 0 && m == 0)
break;
for (int i = 0; i < n; i++)
{
scanf("%d", &q[i]);
}
//普通查找
//找插入的位置pos
int pos = n; //默认插入位置为n, 如果每一个数都比m大就插到q[n]
for(int i = 0; i < n; i++)
{
if(q[i] < m) //从前往后找第一个比它小的数 或者 从后往前找第一个比它大的数(pos以前的数要往前移动一位, 不好移)
{
pos = i;
break;
}
}
// 1 2 3 4 5
// 1 x 2 3 4 5
// 0 1 2 3 4 5
//往后移位的时候, 从后往前移动, 并且把原来最后的一个数存一下
int last = q[n - 1];
for(int i = n - 1; i >= pos; i--)
{
q[i] = q[i - 1];
}
q[n] = last;
//插入进去
q[pos] = m;
for(int i = 0; i <= n; i++)
{
if(i) printf(" %d", q[i]);
else printf("%d", q[i]);
}
printf("\n");
}
return 0;
}
//思考: 如果把插入改成删除
删除第一个 <= m 的数
3 3
4 2 1
0 0
#include <stdio.h>
int q[200];
int main()
{
int n, m;
while (scanf("%d %d", &n, &m) != EOF)
{
if (n == 0 && m == 0)
break;
for (int i = 0; i < n; i++)
{
scanf("%d", &q[i]);
}
//找删除的数的位置 → 第一个 <= m 的数
int pos = n;
for(int i = 0; i < n; i++)
{
if(q[i] <= m)
{
pos = i;
break;
}
}
if(pos == n)
{
printf("没有<=m的数\n");
continue;
}
for(int i = pos; i <= n - 1; i++) //pos的位置被代替了, 因此不需要有额外的删除操作
{
q[i] = q[i + 1];
}
// 1 2 3 4 5
// 1 2 4 5 0/5
for (int i = 0; i < n - 1; i++)
{
if (i)
printf(" %d", q[i]);
else
printf("%d", q[i]);
}
printf("\n");
}
return 0;
}
数组移位
//往后移
往后移动m次等价于往后移动m % n次
往后移动 → 从后往前写for
从第一个数到第n - 1个数都往后移动1位, 再把第一个数替换为原来的最后一个数
1 2 3 4 5
5 1 2 3 4 m = 1
4 5 1 2 3 m = 2
3 4 5 1 2 m = 3
2 3 4 5 1 m = 4
1 2 3 4 5 m = 5
…
5 1 2 3 4 m = 6
4 5 1 2 3 m = 7
3 4 5 1 2 m = 8
2 3 4 5 1 m = 9
1 2 3 4 5 m = 10
#include <stdio.h>
int q[150];
int main()
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &q[i]);
int m;
scanf("%d", &m); //移动m次
//步骤: 记录一下最后一个数t, 从第一个数到第n-1个数往后移动1位, 第一个数替换为t
while(m--)
{
int t = q[n - 1];
for(int i = n - 1; i >= 1; i--) //往后移动, 从后往前写, 注意结束是到1
{
q[i] = q[i - 1];
}
q[0] = t;
}
for(int i = 0; i < n; i++)
{
if(i) printf(" %d", q[i]);
else printf("%d", q[i]);
}
return 0;
}
//往后移动m次等价于往前移动n - m次
后n次一个循环
只需要移动(100 % n)次 → m = m % n;
往后移动m次相当于往前移动 n - m % n 次
往后移动m次相当于往前移动 n - m % n 次
//往前移
往前移, 从前往后写for
1 2 3 4 5
2 3 4 5 1 m = 1
3 4 5 1 2 m = 2
4 5 1 2 3 m = 3
5 1 2 3 4 m = 4
1 2 3 4 5 m = 5
7-18 sdut-C语言实验-矩阵输出(数组移位)
#include <stdio.h>
int q[150];
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &q[i]);
int m = n;
// 步骤: 记录一下最后一个数t, 从第一个数到第n-1个数往后移动1位, 第一个数替换为t
while (m--)
{
for (int i = 0; i < n; i++)
{
if (i)
printf(" %d", q[i]);
else
printf("%d", q[i]);
}
printf("\n");
int t = q[n - 1];
for (int i = n - 1; i >= 1; i--) // 往后移动, 从后往前写, 注意结束是到1
{
q[i] = q[i - 1];
}
q[0] = t;
}
return 0;
}
日期处理
//判断闰年
int is_leap(int n)
{
//xx00 xxxx
if(n % 400 == 0 || (n % 100 != 0) && n % 4 == 0) return 1;
else return 0;
}
//存某月的天数
int month[2][13] = {{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
d = month[is_leap(y)][m];//y年m月对应的天数
7-6 sdut- C语言实验-数日子
#include <stdio.h>
int is_leap(int n)
{
// xx00 xxxx
if (n % 400 == 0 || (n % 100 != 0) && n % 4 == 0)
return 1;
else
return 0;
}
int month[2][13] = {{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
int main()
{
int y, m, d;
int n;
scanf("%d", &n);
while(n--)
{
int sum = 0;
scanf("%d %d %d", &y, &m, &d);
for(int i = 1; i < m; i++) //m月之前已经过完了, 直接把对应月份的所有天数加起来
{
sum += month[is_leap(y)][i];
}
sum += d; //当前的m月已经过了d天
printf("%d\n", sum);
}
return 0;
}
###二维数组矩阵转置小引
```int q[5][10];
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
scanf("%d", &q[i][j]);
}
}
1111111111
1111111111
1111111111
1111111111
1111111111
(m * n) * (s * t)
n = s
m * t
1234
2314
1324
1234
1423
2143
2*4 4*4 2*4
xxxx
xxxx
123
321
213
313
122
231
231
122
313
313
221
132