实验7-1-1 简化的插入排序
方法一:
动态数组
对已经确定的进行操作
#include<stdio.h>
#include<stdlib.h>
void revers(int i,int*a,int n){
while(n>=i){
a[n] = a[n - 1];
n--;
}
}
int main(){
int n;
int i;
int *a;
int add;
scanf("%d", &n);
a = (int *)malloc((n+1) * sizeof(int));
for (i = 0; i < n;i++){
scanf("%d", &a[i]);
}
scanf("%d", &add);
for (i = 0; i < n;i++){
if(add<=a[i]){
revers(i, a, n);
a[i] = add;
break;
}
}
if(i==n)a[i]=add;
for (i = 0; i <= n;i++){
printf("%d ", a[i]);
}
}
有个测试点的问题,n=0时???
实验7-1-2 求最大值及其下标
#include<stdio.h>
int main(){
int a[10];
int n;
int i;
int max,dmax;
scanf("%d", &n);
for (i = 0; i < n;i++)
scanf("%d", &a[i]);
max = a[0];
for (i = n-1; i>0;i--){
if(max<=a[i]){
max = a[i];
dmax = i;
}
}
if(max==a[0])
dmax = 0;
printf("%d %d", max, dmax);
}
没啥好说的
实验7-1-3 将数组中的数逆序存放
#include<stdio.h>
int main(){
int a[10];
int n, i, j,temp;
scanf("%d", &n);
for (i = 0; i < n;i++)
scanf("%d", &a[i]);
for (i = 0, j = n - 1; i < j;i++,j--){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
printf("%d", a[0]);
for (i = 1; i < n;i++)
printf(" %d", a[i]);
}
实验7-1-4 找出不是两个数组共有的元素
唔…一个点
不能同时定义int a,int*a,int a[]
#include <stdio.h>
int main()
{
int n, m, i, j, p, q = 0;
int a[20], b[20];
int book[20] = {0};
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
scanf("%d", &m);
for (i = 0; i < m; i++)
scanf("%d", &b[i]);
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
if (a[i] == b[j])//判断是a[i]是否和B中元素相等
break;
for (p = 0; p <= q; p++)//判断是否有和已储存元素重复
{
if (a[i] == book[p])
break;
}
if (p == q + 1)
{
book[q] = a[i];
q++;
}
}
}
printf("%d", book[0]);
for (i = 1; i < q; i++)
printf(" %d", book[q]);
}
半成品
#include <stdio.h>
int main()
{
int n, m, i, j, p, q = 0;
int a[20]={0}, b[20]={0};
int book[20] = {0};
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
scanf("%d", &m);
for (i = 0; i < m; i++)
scanf("%d", &b[i]);
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++){
if(a[i]==b[j])
break;
}
if(j==m){//条件1:a,b不同 //用数字统计的判断,也可以用flag,但是不能利用break特性,break只能对单个的j起作用,而这个判断,需要遍历完所有的j。
if(a[i]==0){
book[q] = a[i];
q++;
}
for (p = 0; p <= q;p++){
if(book[p]==a[i])
break;
}
if(p==q+1){//条件2:book,a[i]不同
book[q] = a[i];
q++;
}
}
}
for (j = 0; j < m;j++)
{
for (i = 0; i < n; i++)
{
if (a[i] == b[j])
break;
}
if (i == n)
{ //条件1:a,b不同
if(b[j]==0){
book[q] = b[j];
q++;
}
for (p = 0; p <= q; p++)
{
if (book[p] == b[j])
break;
}
if (p == q + 1)
{ //条件2:book,b[i]不同
book[q] = b[j];
q++;
}
}
}
printf("%d", book[0]);
for (i = 1; i < q; i++)
printf(" %d", book[i]);
}
憨憨做题,之后改成函数.
函数:找一个不同,清除重复,找另一个不同,清除重复
实验7-1-5 选择法排序
1.找到最小的下标,n个元素中
2将a[min]与末尾交换
3.n–,回到第一步,执行n-1次
#include <stdio.h>
int indexmin(int *a, int n)
{
int index = 0;
int i;
for (i = 0; i < n; i++)
{
if (a[index] >= a[i])
index = i;
}
return index;
}
void swap(int*a,int*b){
int temp;
temp=*a;
*a = *b;
*b = temp;
}
int main(){
int n, i,min;
int a[10];
scanf("%d", &n);
for (i = 0; i < n;i++)
scanf("%d", &a[i]);
i = n;
while (i-1)
{
min = indexmin(a, i);
swap(&a[min], &a[i - 1]);
i--;
}
printf("%d", a[0]);
for (i = 1; i < n;i++)
printf(" %d", a[i]);
}
实验7-1-6 求一批整数中出现最多的个位数字
对于一个:
1,统计各个位数的次数—数组(1个)
2.获得次数最大的,数组下标(位数),数组对应个数.
重复的,怎么办?只能返回一个下标.
计入数组?那么0怎么办?
比较当中,不要用函数吧。
对多个:
1.用数组储存
2.遍历每一个
#include <stdio.h>
void count(int *book, int *a, int i){
int num = a[i];
int index;
while(num){
index = num % 10;
book[index]++;
num /= 10;
}
}
int main(){
int n,i;
int sum = 0;
int a[1000];
int book[10] = {0};
int max=-1;
scanf("%d", &n);
for (i = 0; i < n;i++)
scanf("%d", &a[i]);
for (i = 0; i < n;i++)
count(book, a, i);
for (i = 0; i < 10;i++){
if(book[i]>=max)
max = book[i];
}
printf("%d:", max);
for (i = 0; i < 10;i++){
if(max==book[i]){
printf(" %d", i);
}
}
}
实验7-1-7 查找整数
#include <stdio.h>
int main(){
int n, x,i;
int a[20];
int have = 0;
scanf("%d%d", &n, &x);
for (i = 0; i < n;i++){
scanf("%d", &a[i]);
}
for (i = 0; i < n;i++){
if(x==a[i]){
printf("%d", i);
have = 1;
}
}
if(!have)
printf("Not Found");
}
实验7-1-8 输出数组元素
#include <stdio.h>
int main(){
int a[10];
int n, i,count=0;
scanf("%d", &n);
for (i = 0; i < n;i++)
scanf("%d", &a[i]);
for (i = 0; i < n - 1;i++){
if(count%3==0)
printf("%d", a[i + 1] - a[i]);
else
printf(" %d", a[i + 1] - a[i]);
count++;
if(count%3==0)
printf("\n");
}
}
实验7-1-9 数字加密
以及数组的初始化问题,若是不出初始化,可能会出现随机数
输入有前导0的问题?正常用int n来读入的话,033=33
方案一:利用数组与getchar
#include <stdio.h>
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int main()
{
char ch;
int i = 0;
int a[4] = {0};
while ((ch = getchar()) != '\n')
{
a[i] = ch - '0';
i++;
}
for (i = 0; i < 4; i++)
{
a[i] = (a[i] + 9) % 10;
}
swap(&a[0], &a[2]);
swap(&a[1], &a[3]);
printf("The encrypted number is ");
for (i = 0; i < 4; i++)
{
printf("%d", a[i]);
}
}
实验7-1-10 交换最小值和最大值
#include<stdio.h>
void swap(int*a,int*b){
int t;
t = *a;
*a = *b;
*b = t;
}
int main(){
int n,i;
int a[10];
int inmin, inmax;
scanf("%d", &n);
for (i = 0; i < n;i++)
scanf("%d", &a[i]);
for (inmin=0, i = 1; i < n;i++){
if(a[i]<=a[inmin])
inmin = i;
}
swap(&a[inmin], &a[0]);
for (inmax = 0, i = 1; i < n;i++){
if(a[i]>=a[inmax])
inmax = i;
}
swap(&a[inmax], &a[n - 1]);
for (i = 0; i < n;i++)
printf("%d ", a[i]);
}
实验7-1-11 求整数序列中出现次数最多的数
这题并不是对个位数字的统计,无法用下标与最大数字对应
事情上是推广:题目保证这样的最大数字是唯一的。
函数思想:个数与数字一一对应。
可以统计个数,得到最大的个数,然后再得到数字
#include <stdio.h>
int main(){
int n, i,j;
int str[1000];
int count = 0,maxc = 0,num,maxn;
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", &str[i]);
for (i = 0; i < n;i++){
count = 0;//重置
num = str[i];
for (j = 0; j < n;j++){
if(num==str[j])
count++;
}
if(maxc<count){
maxc = count;
maxn = num;
}
}
printf("%d %d", maxn, maxc);
}
实验7-1-12 组个最小数
还是一个一一对应的关系
下标i—>数字0~9
a[i]->数字i 的个数
#include <stdio.h>
int main(){
int a[10] = {0};
int i;
for (i = 0; i < 10;i++)
scanf("%d", &a[i]);//初始化,统计
//首位
for (i = 1; i < 10;i++){
if(a[i]!=0){
printf("%d", i);
a[i]--;
break;
}
}
for (i = 0; i < 10;i++){
while(a[i]){
printf("%d", i);
a[i]--;
}
}
}
实验7-1-13 装箱问题
下标i->箱子号码
chset[i]->箱子容量
#include <stdio.h>
int main(){
int n,i,num=0,temp,maxn=0;
int chest[1000];
for (i = 0; i < 1000;i++)
chest[i] = 100;//初始化
scanf("%d", &n);
while(n--){
num = 0;//重置
scanf("%d", &temp);
while(1){
if (chest[num] >= temp)
{
chest[num] -= temp;
printf("%d %d\n", temp, num + 1);
if(maxn<num)
maxn = num;
break;
}
else
num++;
}
}
printf("%d", maxn+1);
}
实验7-2-1 求矩阵各行元素之和
二维数组
#include <stdio.h>
int main(){
int m, n;
int i, j;
int sum = 0;
int a[6][6] = {0};
scanf("%d%d", &m, &n);
for (i = 0; i < m;i++){
for (j = 0; j < n;j++)
scanf("%d", &a[i][j]);
}
for (i = 0; i < m;i++){
sum = 0;
for (j = 0; j < n;j++){
sum += a[i][j];
}
printf("%d\n", sum);
}
}
实验7-2-2 矩阵运算
#include <stdio.h>
int main(){
int a[10][10] = {0};
int n,sum=0;
int i, j;
scanf("%d", &n);
for (i = 0; i < n;i++){
for (j = 0; j < n;j++)
scanf("%d", &a[i][j]);
}
for (i = 0; i < n - 1;i++){
for (j = 0; j < n - 1;j++){
if(i+j==n-1)
continue;
else
sum += a[i][j];
}
}
printf("%d", sum);
}
实验7-2-3 求矩阵的局部极大值
#include <stdio.h>
int main(){
int a[20][20] = {0};
int m, n;
int i, j;
int t,is=1;
scanf("%d%d", &m, &n);
for (i = 0; i < m;i++){
for (j = 0; j < n;j++){
scanf("%d", &a[i][j]);
}
}
for (i = 1; i < m - 1;i++){
for (j = 1; j < n - 1;j++){
t = a[i][j];
if(t>a[i-1][j]&&t>a[i][j-1]&&t>a[i][j+1]&&t>a[i+1][j]){
printf("%d %d %d\n", t, i+1, j+1);
is = 0;
}
}
}
if(is)
printf("None %d %d", m, n);
}
实验7-2-4 计算天数
tip:scanf在读取的时候,只能跳过空格与回车
其他的要用标志
如;2009/03/02
scanf("%d/%d/%d", &yr, &mo, &da);
#include <stdio.h>
int unleap[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int isleap(int n){
if(n%4==0&&n%100!=0||n%400==0)
return 1;
else
return 0;
}
int main(){
int yr, mo, da;
int sum = 0;
scanf("%d/%d/%d", &yr, &mo, &da);
if(isleap(yr)&&mo>=2)
sum += 1;
while(mo-1){
sum += unleap[--mo];
}
sum += da;
printf("%d", sum);
}
实验7-2-5 判断上三角矩阵
#include <stdio.h>
int main(){
int t, n;
int i, j;
int a[10][10];
int flag = 1;
scanf("%d", &t);
while(t--){
//重置
for (i = 0; i < 10;i++){
for (j = 0; j < 10;j++)
a[i][j] = 0;
}
flag = 1;
scanf("%d", &n);
//读入
for (i = 0; i < n;i++){
for (j = 0; j < n;j++)
scanf("%d", &a[i][j]);
}
//判断
for (i = 0; i < n;i++){
for (j = 0; j < i;j++)
if(a[i][j]!=0)
flag = 0;
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
}
实验7-2-6 打印杨辉三角
利用二维数组的位置特性:储存杨辉三角(本身就是一种二维位置递推关系)
#include <stdio.h>
int main(){
int a[10][10];
int i, j;
int n,t;
//初始化
for (i = 0; i < 10;i++){
for (j = 0; j < 10;j++){
a[i][j] = 1;
}
}
//储存杨辉三角
for (i = 2; i < 10;i++){
for (j = 1; j < i;j++)
a[i][j] = a[i - 1][j - 1] + a[i - 1][j];
}
scanf("%d", &n);
t = n;
for (i = 0; i < n;i++){
t--;
for (j = 0; j <=i;j++){
if(j==0)
printf("%*d", 4 + t, a[i][j]);
else
printf("%4d", a[i][j]);
}
printf("\n");
}
}
####方阵循环右移
题目的意思理解有一些问题
可以将移动的数组分成两个部分:
1.后面几个移动到前面去的
2.前面几个移动到后面去的
分界点就在n-m(m>n时,会循环,取余)
#include<stdio.h>
int main(){
int a[10][10] = {0};
int m, n, i, j;
scanf("%d%d", &m,& n);
//读入
for (i = 0; i < n;i++){
for (j = 0; j < n;j++)
scanf("%d", &a[i][j]);
}
m = m % n;
//分成两个部分输出
for (i = 0; i < n;i++){
for (j = n - m; j < n;j++)
printf("%d ", a[i][j]);
for (j = 0; j < n - m;j++)
printf("%d ", a[i][j]);
printf("\n");
}
}
实验7-2-8 找鞍点
有点麻烦,通过判断位置信息,来找鞍点
#include<stdio.h>
int main(){
int a[6][6] = {0};
int n, i, j,q;
int max,inmax_1,inmax_2,min,inmin_1,inmin_2;
int flag = 1;
scanf("%d", &n);
//读入
for (i = 0; i < n;i++){
for (j = 0; j < n;j++)
scanf("%d", &a[i][j]);
}
for (i = 0; i < n;i++){
max = a[i][0];
//找该行上的最大值
for (j = 1; j < n;j++){
if(a[i][j]>=max){
max = a[i][j];
inmax_1 = i;
inmax_2 = j;
}
}
//找到该列上的最小值
min = a[0][inmax_2];
for (q = 1; q < n;q++){
if(a[q][inmax_2]<=min){
min = a[q][inmax_2];
inmin_1 = q;
}
}
//继续判断
if(inmin_1==inmax_1){
printf("%d %d", inmax_1, inmax_2);
flag = 0;
}
}
if(flag)
printf("NONE");
}
实验7-2-9 螺旋方阵
螺旋方阵从人的角度来看很容易,人可以想象出环绕
但是对编程来说,只能进行 行处理和 列处理
怎样将其转换为可递推的行列问题是个难点。
关于是储存还是直接输出:
这里储存更容易些,直接输出对于简单格式用起来比较方便
比较容易的格式,就是用圈数—表示坐标(可循环)
绕一圈:
#include<stdio.h>
int main(){
int n, i, j;
int a[6][6] = {0};
int ncircle;
int num = 1;
scanf("%d", &n);
ncircle = (n + 1) / 2;
for (j = 0; j < n;j++)
a[0][j] = num++;
for (i = 1; i < n;i++)
a[i][n - 1] = num++;
for (j = n - 2; j >= 0;j--)
a[n - 1][j] = num++;
for (i = n - 2; i > 0;i--)
a[i][0] = num++;
for (i = 0; i < n;i++){
for (j = 0; j < n;j++)
printf("%3d", a[i][j]);
printf("\n");
}
}
完整
#include<stdio.h>
int main(){
int n, i, j,fac=0;
int a[10][10] = {0};
int ncircle;
int num = 1;
scanf("%d", &n);
ncircle = (n + 1) / 2;
int startx = fac, endx = n - fac-1;
int starty = fac + 1, endy = n - fac - 2;
while(ncircle){
if(startx==endx)
a[startx][starty-1] = num;
else{
for (j = startx; j <=endx;j++)
a[starty-1][j] = num++;
for (i = starty; i <=endy;i++)
a[i][endx] = num++;
for (j =endx; j >= startx;j--)
a[endy+1][j] = num++;
for (i = endy; i >=starty;i--)
a[i][startx] = num++;
}
ncircle--;
fac++;
startx = fac, endx = n - fac-1;
starty = fac + 1, endy = n - fac - 2;
}
for (i = 0; i < n;i++){
for (j = 0; j < n;j++)
printf("%3d", a[i][j]);
printf("\n");
}
}
实验7-2-10 简易连连看
有点难度…
对单个字符处理还是用getchar,putchat好些
函数传递二维数组:
- 方法1: 第一维的长度可以不指定
- 但必须指定第二维的长度
void print_a(int a[][5], int n, int m)
*方法2: 指向一个有5个元素一维数组的指针
void print_b(int (*a)[5], int n, int m)
#include <stdio.h>
int judge(char a[][10],int n){
int i, j;
int flag = 1;
for (i = 0; i < n;i++){
for (j = 0; j < n;j++){
if(a[i][j]!='*')
flag = 0;
}
}
return flag;
}
int main()
{
char a[10][10];
int n, k;
int i, j;
int x1, y1, x2, y2;
int count = 0;
scanf("%d", &n);
n *= 2;
//读入
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++){
getchar();
scanf("%c", &a[i][j]);
}
}
scanf("%d", &k);
while (k--)
{ //判断
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
//判断
if (a[x1-1][y1-1] == a[x2-1][y2-1]&&a[x1-1][y1-1] != '*')
{
a[x1-1][y1-1] = '*';
a[x2-1][y2-1] = '*';
if(judge(a,n)){
printf("Congratulations!");
break;
}
//打印
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if(j==0)putchar(a[i][j]);
else printf(" %c",a[i][j]);
}
printf("\n");
}
}
else{
printf("Uh-oh\n");
count++;
if(count==3){
printf("Game Over");
break;
}
}
}
}
不太顺利,需要重新过一遍
对字符数组的处理
实验7-3-1 字符串逆序
#include<stdio.h>
int main(){
char a[81];
char ch;
int n = 0;
while((ch=getchar())!='\n'){
a[n] = ch;
n++;
}
while(n--){
putchar(a[n]);
}
}
实验7-3-2 查找指定字符
读入字符串:方式一 一个个读入
ch = getchar();
for(i = 0; ch != '\n'; i++)
{
string[i] = ch;
cnt++;
ch = getchar();
}
读入字符串:方式二 整个读入
scanf("%s", string);
len = strlen(string);
方式二:
不需要&,string本身是地址(数组的首地址)
读入的时候会自动补’\0’,所以要保留一个空间给\0
但是scanf并不安全,会超出地址?

scanf_s可以避免吗?

字符串和字符数组的不同:
字符数组包含字符串。
字符串可以整体输出(用’%s’,遇到’\0’(对应ascii码为0)结束)
字符数组(没有’\0’情况下) 则需要单个遍历输出
本文提供了一系列C语言数组和字符串编程练习题的代码实现,包括数组操作、矩阵处理及字符串处理等内容,有助于读者深入理解并掌握C语言编程技巧。

被折叠的 条评论
为什么被折叠?



