实验04 数组及其在程序设计中的应用(2021级)

1. (括号匹配)

题目编号:Exp04-Basic01,GJBook3例-06-13

题目名称:括号匹配

题目描述:编写程序,从终端读入以‘@’为结束符的字符序列,检查该字符序列中的 ( 与 )、 [ 与 ] 、{ 与 } 是否匹配(个数相等且位置不相交)。

输入:包含一串以‘@’为结束符的字符串,其间可能包含空白或其它非括号字符。

输出:如果字符串中三类括号匹配,则输出YES;否则输出NO。
 

样例1:

输入:

{a,a}b{c[cc]c}  {a(bb[cc]dd)a}@
输出:
YES

样例2:

输入:
{a,a}b{c[cc]c] {a(bb[cc]dd)a}@
输出:
NO
#include<stdio.h>
#define size 100
int top = 0;
char a[100];
bool push(char x) {
	if (top > size - 1)return false;
	else {
		a[top] = x;
		top++;
		return true;
	}
}
char pop(void) {
	if (top == 0) return '\0';
	else {
		top--;
		return a[top];
	}
}
int check(char x, char y) {
	if (x == '\0' || x == '@') { printf("NO"); return 0; }
	else if (x != y) { printf("NO"); return 0; }
	else return 1;
}
int main() {
	char ch, out;
	int i = 1;
	push('@');
	ch = getchar();
	while (ch != '@') {
		switch (ch) {
		case'[':
		case'(':
		case'{':push(ch); break;
		case']':out = pop(); i = check(out, '['); break;
		case'}':out = pop(); i = check(out, '{'); break;
		case')':out = pop(); i = check(out, '('); break;
		default:break;
		}
		ch = getchar();
		if (i == 0) break;
	}
	out = pop();
	if (i == 1)
	{
		if (out == '@') {
			printf("YES");
		}
		else {
			printf("NO");
		}
	}
	return 0;
}

2. (数组排序)

题目编号:  Exp04-Basic03

题目名称:  数组排序
题目描述:  编写函数,分别采用教材给出的“主元选择排序”、“冒泡排序”和“逐步增加递增子序列”排序方法对给定数组进行排序。综合运用调试方法,观察不同排序方法在排序过程中数组元素值的变化情况,如观察递增排序如下序列{9、8、7、6、5、4、3、2、1、0},{0、1、2、3、4、5、6、7、8、9}和{2、9、4、7、6、5、8、3、0、1}时,数组中元素比较次数、移动或交换次数。

说明:

(1)对于“主元选择排序”和“冒泡排序”,执行完3个赋值操作,计为1次交换。

(2)对于“逐步增加递增子序列”排序,每执行一次while循环的循环条件判断,计为1次比较;如果在某轮比较中元素本身的位置没有变化,则本轮移动次数为0。

(3)因本题目的是观察输出数据,深入理解排序算法;所以样例点和实测点一致。

输入:包含10个整数的待排序数组。

输出:在一行内依次输出,递增排序时,主元排序比较次数 和 移动/交换次数、冒泡排序比较次数 和 移动/交换次数和递增子序列排序比较次数 和 移动/交换次数,相邻数字之间以一个西文空格间隔。

样例1:

输入:
9 8 7 6 5 4 3 2 1 0
输出:
45 9 90 45 54 54

样例2:

输入:
0 1 2 3 4 5 6 7 8 9
输出:
45 9 9 0 9 0

样例3:

输入:
2 2 3 3 5 5 4 4 6 6
输出:
45 9 27 4 13 6

样例4:

输入:
1 0 3 2 5 4 7 6 9 8
输出:
45 9 18 5 14 10

样例5:

输入:
1 2 3 4 5 5 4 3 2 1
输出:
45 9 81 20 29 24
#include<stdio.h>
#include<string.h>  //数组需要复制,所以需要包含头文件string.h
int a[10];          //声明数组
int y1 = 0, y2 = 0, y3 = 0;//函数只能返回一个值,所以需要全局变量来存储比较次数
//以下是主元排序部分

int zhuyuan() {
	int sum = 0;
	int b[10], i, j, k, r;
	memcpy(b, a, sizeof(a));     //调用函数将a数组复制给b数组
	for (i = 0; i < 9; i++) {
		j = i;
		for (k = i + 1; k < 10; k++) {
			y1++;//记录比较的次数
			if (b[k] < b[j]) j = k;
		}
		r = b[i]; b[i] = b[j]; b[j] = r;
		sum++;    //记录移动次数
	}
	return sum;

}

//以下是冒泡排序部分

int maopao() {
	int sum = 0;
	int b[10], i, r, flag = 1;
	memcpy(b, a, sizeof(a));
	while (flag) {
		flag = 0;
		for (i = 0; i < 9; i++) {
			y2++;//记录比较次数
			if (b[i] > b[i + 1]) {
				r = b[i]; b[i] = b[i + 1]; b[i + 1] = r;
				sum++;//记录移动次数
				flag = 1;
			}
		}
	}

	return sum;

}

//以下是逐步增加递增子序列法

int zhubu() {
	int sum = 0;
	int b[10], i, j, k, r, flag;
	memcpy(b, a, sizeof(a));
	for (i = 1; i < 10; i++) {
		flag = 0;
		j = i - 1;
		while ((b[j] > b[i]) && (j >= 0)) {
			j = j - 1;
			flag = 1; //用于判断是否有移动
			y3++; //记录比较的次数中进入while部分
		}
		r = b[i];
		for (k = i - 1; k >= j + 1; k--) {
			b[k + 1] = b[k];
			if (flag) sum++;//记录移动次数中部分移动
		}
		if (flag) sum++; //移动次数加上未在循环中的部分
		b[j + 1] = r;
	}
	y3 = y3 + 9;//比较中有9次条件不成立未进入循环
	return sum;
}

int main() {
	int x1, x2, x3;
	int i;
	for (i = 0; i < 10; i++) {
		scanf_s("%d", &a[i]);
	}
	x1 = zhuyuan();
	x2 = maopao();
	x3 = zhubu();
	printf("%d %d %d %d %d %d", y1, x1, y2, x2, y3, x3);
	return 0;
}

3. (索引数组排序)

题目编号:Exp04-Enhance04,GJBook3-06-21

题目名称:索引数组排序

题目描述:已知n(n≤100)个元素的整型数组 A 未排序,一个索引数组 B 保存 A 的下标。编写程序,在不改变数组A的情况下,只改变数组 B完成对A的递增排序,如下所示:排序后索引数组B的第一个元素值是A数组中最小元素的下标。

排序前
数组A:9 7 5 8 0 4 1 3 2 6 
数组B:0 1 2 3 4 5 6 7 8 9
排序后
数组A:9 7 5 8 0 4 1 3 2 6
数组B:4 6 8 7 5 2 9 1 3 0


输入:第一行输入一个正整数n,第二行随机输入n个互不相同的整数作为数组A的元素。

输出:第一行输出数组A的n个元素,元素间以一个西文空格间隔;第二行输出数组B的n个元素,元素间以一个西文空格间隔;每行最后一个元素后无字符。
 

样例1:

输入:
10
9 7 5 8 0 4 1 3 2 6
输出:
9 7 5 8 0 4 1 3 2 6
4 6 8 7 5 2 9 1 3 0

样例2:

输入:
5
9 8 7 6 5
输出:
9 8 7 6 5
4 3 2 1 0
#include <stdio.h>
int main()
{
	int i, n, temp, x = 0, A[100], B[100];
	for (int k = 0; k < 100; k++)
		B[k] = k;
	scanf("%d", &n);
	for (i = 0; i < n; i++)
	{
		scanf("%d", &A[B[i]]);
	}
	for (int j = 0; j < n - 1; j++)
		printf("%d ", A[B[j]]);
	printf("%d", A[B[n - 1]]);
	printf("\n");
	int flag = 1;
	while (flag == 1)
	{
		flag = 0;
		for (i = 0; i < n - 1; i++)
		{
			if (A[B[i]] > A[B[i + 1]])
			{
				x = 1;
				temp = B[i];
				B[i] = B[i + 1];
				B[i + 1] = temp;
				flag = 1;
			}
		}
	}
	for (i = 0; i < n - 1; i++)
		printf("%d ", B[i]);
	printf("%d", B[n - 1]);
	return 0;
}

4. (检验矩阵重复元素)

题目编号:Exp04-Basic07,GJBook3-06-01

题目名称:检验矩阵重复元素

题目描述:编写程序判断任意给定n*n的两维整型数组中是否有相同元素。
 

输入:第一行输入数组行数n(≤10),第二行随机输入n*n个整数作为数组元素值。

输出:如果数组中有相同元素,则输出YES;否则,输出NO。
 

样例1:

输入:
3
1 2 3 4 5 6 7 8 9
输出:
NO

样例2:

输入:
3
1 1 2 3 4 5 6 7 8
输出:
YES
​
#include <stdio.h>
int main()
{
	int n, i, a[100], flag = 0;
	scanf_s("%d", &n);
	for (i = 0; i < n * n; i++)
		scanf_s("%d", &a[i]);
	for (i = 0; i < n * n - 1; i++)
	{
		for (int j = i + 1; j < n * n; j++)
		{
			if (a[i] == a[j])
			{
				flag++; break;
			}
		}
	}
	if (flag)
		printf("YES");
	else printf("NO");
	return 0;
}

​

5. (矩阵转置)

题目编号: Exp04-Basic08,GJBook3-06-03

题目名称: 矩阵转置

问题描述: 编写程序,将任意给定n*n的两维整型数组转置。

输入:第一行输入数组行数n(≤10),第二行随机输入n*n个整数作为数组元素值。

输出:按先行后列、从左至右的顺序输出转置后数组内的所有元素,每行n个元素,同一行内的各元素间以一个西文空格间隔;每行最后一个元素除必要的回车换行符外无其它字符。

样例1:

输入:
3
1 2 3
1 2 3
1 2 3
输出:
1 1 1
2 2 2
3 3 3

样例2:

输入:
3
1 1 1
2 2 2
3 3 3
输出:
1 2 3
1 2 3
1 2 3
#include <stdio.h>
int main()
{
	int n, i, j, a[10][10], flag = 0;
	scanf_s("%d", &n);
	for (i = 0; i < n; i++)
		for (j = 0; j < n; j++)
			scanf_s("%d", &a[i][j]);
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n; j++)
		{
			printf("%d", a[j][i]);
			if (j < n - 1)
				printf(" ");
			else printf("\n");
		}
	}
	return 0;
}

6. (字符串反序)

题目编号:Exp04-Basic10,GJBook3-06-12

题目名称:字符串反序

问题描述:编写程序,将给定的字符串反序输出。

输入:一个长度不超过255的字符串,字符串中可能含有空白字符。

输出:反序输出的字符串。

样例1:

输入 A            输出 A

样例2:

输入 123 45    输出  54 321

#include <stdio.h>
int main()
{
	char a[255];
	int i;
	gets_s(a);
	for (i = 0; i < 255; i++)
	{
		if (a[i] == '\0')
			break;
	}
	for (int j = i - 1; j >= 0; j--)
		printf("%c", a[j]);
	return 0;
}

7. (转移0元素)

题目编号:Exp04-Basic05,GJBook3-06-06

题目名称:转移0元素

题目描述:编写程序,不使用其他辅助数组,把给定整型数组中所有0元素全部移到后面,且所有非0元素的顺序不变。
 

输入:第一行输入数组长度n(≤100),第二行依次从键盘随机输入n个整数作为数组元素值。

输出:已将所有0元素串到后面的整数数组,各元素间以一个西文空格间隔,最后一个元素后无字符。
 

样例1:

输入:
10
0 3 1 0 0 0 1 2 3 0
输出:
3 1 1 2 3 0 0 0 0 0

样例2:

输入:
10
0 0 0 0 0 0 1 2 3 4
输出:
1 2 3 4 0 0 0 0 0 0
#include <stdio.h>
int main()
{
	int a[100], b[100], * p, * q, i, * originA, * originB, x = 0, y = 0;
	p = a;
	q = b;
	originB = &b[0];
	originA = &a[0];
	int n;
	scanf_s("%d", &n);

	for (i = 0; i < n; i++)
		scanf_s("%d", &a[i]);
	for (i = 0; i < n; i++)
	{
		if (*(p + i) != 0)
		{
			q = p + i;
			printf("%d ", *q);
			x++;
			q = q + 1;
		}
	}
	for (i = 0; i < n; i++)
	{
		if (*(p + i) == 0)
		{
			originA = p + i;
			printf("%d", *originA);
			y++;
			if (x + y < n)
				printf(" ");
			originA = ++q;
		}
	}
	return 0;
}

8. (约瑟夫问题(Josephus))

题目编号 :Exp04-Enhance02,GJBook3-06-26

题目名称:约瑟夫问题(Josephus)

题目描述:

古代某法官要判决 n 个犯人死刑, 他有一条荒唐的逻辑, 将犯人首尾相接排成圆圈,所有计数从1开始; 然后从第 s 个人开始数, 每数到第 m 个犯人,则拉出来处决; 然后再数 m 个,数到的犯人再处决;... ; 但剩下的最后一个犯人可以赦免。编程序,给出处决顺序,并告知哪一个人活下来。

输入:三个正整数 n(≤1000),s和m,都可以使用int类型变量表示。

输出:依次输出被处决人员的编号,每个编号之间用一个西文空格间隔,最后一个编号后无字符。
 

样例:

输入:6 1 5
输出:5 4 6 2 3 1
#include<stdio.h>
#include<stdlib.h>
#define LEN sizeof(struct LNode)
typedef int datatype;
typedef struct LNode {
	datatype data;
	struct LNode* next;
}LNode, * LinkList;
int N, S, M;//N:人数(<50); S:起始编号; M:间隔数;
LinkList L, Start;//Start:起始编号的结点;
void Creat_LinkList(int n);
void Find_start(int n);
void Find_delete();
int main()
{
	scanf("%d %d %d", &N, &S, &M);
	Creat_LinkList(N);//创建无头结点的链表 
	Find_start(S);//搜索链表,寻找结点 
	Find_delete();//从指点结点开始按间隔长度逐一删除结点 
	return 0;
}
void Creat_LinkList(int n)
{
	int i = 1;
	LinkList p, q;
	p = (LinkList)malloc(LEN);
	p->data = i++;
	L = p;
	q = p;
	while (i <= n) {
		p = (LinkList)malloc(LEN);
		p->data = i;
		q->next = p;
		q = p;
		i++;
	}
	q->next = L;
}
void Find_start(int n)
{
	Start = L;
	while (Start->data != n) {
		Start = Start->next;
	}
}
void Find_delete()
{
	int i, j, k = 0, num = N;
	LinkList pre = L, s;
	while (num > 1) {
		for (i = 1; i < M; i++) {
			Start = Start->next;
		}
		printf("%d ", Start->data);
		while (pre->next != Start) {
			pre = pre->next;
		}
		s = pre->next;
		pre->next = s->next;
		free(s);
		Start = pre->next;
		num -= 1;
	}
	printf("%d", Start->data);
}

9. (n倍数关系)

题目编号:Exp04-Basic02

题目名称:n倍数关系

题目描述:

给定若干不完全相同的正整数(<10000)和n(n<5),计算这些正整数里面有多少数对满足:其中一个是另一个的n倍。例如:1 4 3 2 9 7 18 22,n=3时得到的答案是2;因为3是1的3倍,9是3的3倍。


输入:输入第一行给出正整数n的值,接下来包括多组测试数据。每组数据最多100个整数占用一行,以数字0结束(不计入100个整数里)。测试数据不超过20组,最后一行只包括-1,表示输入数据结束。

输出:对每组输入数据,输出一行,给出有多少数对满足其中一个是另一个n倍。(注:最后一行末尾无换行符等多余字符。)
 

样例:

输入:
2
1 4 3 2 9 7 18 22 0
2 4 8 10 0
7 5 11 13 1 3 0
-1
输出:
3
2
0
#include <stdio.h>
int main()
{
	int n, i, j, count = 0, b[20] = { 0 }, c[20] = { 0 };
	float a[20][100];
	scanf_s("%d", &n);
	for (j = 0.0;; j++)
	{
		for (i = 0;; i++)
		{
			scanf_s("%f", &a[j][i]);
			b[j]++;
			if (a[j][i] == 0 || a[j][i] == -1)
				break;
		}
		if (a[j][i] == -1 && i == 0)
			break;
	}
	for (j = 0;; j++)
	{
		for (i = 0; i < b[j] - 2; i++)
		{
			for (int k = i + 1; k < b[j] - 1; k++)
				if ((float)a[j][i] / a[j][k] == n || (float)a[j][k] / a[j][i] == n)
					c[j]++;
		}
		count = j;
		if (a[j][0] == -1)
			break;
	}
	for (j = 0; j < count; j++)
		printf("%d\n", c[j]);
	return 0;
}

不用二维数组版

#include <stdio.h>
int main()
{
	int n,a[101]={0},count[101]={0},sum=0;
//记住这里一定要多一位
	scanf("%d", &n);
	for (int i = 0;; i++)
	{
		for (int j = 0;; j++)
		{
			scanf("%d", &a[j]);
			if (a[j] == 0||a[j]==-1)
				break;
		}
		if (a[0] != -1)
		{
			for (int j = 0; a[j] != 0; j++)
			{
				for (int k = j; a[k] != 0; k++)
				{
					if ((float)a[j] / a[k] == n || (float)a[k] / a[j] == n)
						count[i]++;
				}
			}
			sum++;
		}
		else break;
	}
	for (int i = 0; i < sum-1; i++)
		printf("%d\n", count[i]);
	printf("%d", count[sum - 1]);
}

10. (循环右移)

题目编号 :Exp04-Basic06,GJBook3-06-04

题目名称:循环右移

题目描述:编写程序,不使用其它辅助数组,把一维整型数组中的各个元素循环右移j位。

输入:

第一行输入两个整数,n表示数组长度(0<n<=100),j表示循环右移的位数(j>=0);

第二行依次从键盘随机输入n个整数作为数组元素值。

输出:

循环右移后的整数数组,各元素间以一个西文空格间隔,最后一个元素后无字符。

样例1:

输入:
10 2
1 2 3 4 5 6 7 8 9 0
输出:
9 0 1 2 3 4 5 6 7 8

样例2:

输入:
10 23
1 2 3 4 5 6 7 8 9 0
输出:
8 9 0 1 2 3 4 5 6 7
#include <stdio.h>
int main()
{
	int n, j, i, a[100];
	scanf_s("%d %d", &n, &j);
	j = j % n;
	for (i = 0; i < n; i++)
		scanf_s("%d", &a[i]);
	int x = 0, y = 0;
	for (i = n - j; i <= n - 1; i++)
	{
		printf("%d", a[i]);
		x++;
		if (x < n)
			printf(" ");
	}
	for (i = 0; i <= n - 1 - j; i++)
	{
		printf("%d", a[i]);
		y++;
		if (x + y < n)
			printf(" ");
	}
	return 0;
}

11. (检验矩阵主对角线对称)

题目编号:Exp04-Basic09,GJBook3-06-02

题目名称:检验矩阵主对角线对称

题目描述:编写程序,判断任意给定n*n的两维整型数组是否关于主对角线对称。
 

输入:第一行输入数组行数n(≤10),第二行随机输入n*n个整数作为数组元素值。

输出:如果数组关于主对角线对称,则输出YES;否则输出NO。

样例1:

输入:

3
1 2 3
2 1 2
3 2 1
输出:
YES

样例2:

输入:

3
0 0 1
2 1 2
3 2 1
输出:
NO
#include<stdio.h>
int main() {
	int n, i, j, a[100][100];
	scanf("%d", &n);
	for (i = 0; i < n; i++) {
		for (j = 0; j < n; j++) {
			scanf("%d", &a[i][j]);
		}
	}
	int right = 1;
	for (i = 0; i < n; i++) {
		for (j = 0; j < n; j++) {
			if (a[i][j] != a[j][i]) {
				right = 0;
				break;
			}
		}
	}
	if (right == 1)printf("YES");
	else printf("NO");
	return 0;
}

12. (删除重复元素)

题目编号:Exp04-Basic04,GJBook3-06-19

题目名称:删除重复元素

题目描述:编写函数,不使用其他辅助数组,把整型数组中重复元素删得只剩一个;所有未被删除元素都保留最先顺序移动到数组前面。


输入:第一行输入数组长度n(≤100),第二行依次从键盘随机输入n个整数作为数组元素值。

输出:已删除重复元素的数组,各元素间以一个西文空格间隔,最后一个元素后无字符。

样例1:

输入:
10
1 1 2 3 3 3 2 1 2 4
输出:
1 2 3 4

样例2:

输入:
10
1 0 2 2 2 2 2 2 2 2
输出:
1 0 2
#include <stdio.h>
int main()
{
	int n, i, a[100], count = 0, x = 0;
	scanf_s("%d", &n);
	for (i = 0; i < n; i++)
		scanf_s("%d", &a[i]);
	for (i = 0; i < n; i++)
	{
		count = 0;
		for (int j = i - 1; j >= 0; j--)
		{
			if (a[j] != a[i])
			{
				count++;
			}
		}
		if (count == i)
		{
			if (x == 0)
			{
				printf(" %d", a[i]);
				x++;
			}
			else printf(" %d", a[i]);
		}
	}
	return 0;
}

13. (螺旋矩阵)

题目编号:Exp04-Enhance05,freshman-1050,GJBook3-0622

题目名称:螺旋矩阵

题目描述:

螺旋矩阵指一个呈螺旋状的数字矩阵,它的数字由第一行开始到右边不断变大,向下变大,向左变大,向上变大,如此循环。如下所示为3阶螺旋矩阵。

1.JPG

输入:输入一个正整数 N (N<=30),标明矩阵阶数。

输出:按螺旋矩阵形式输出整数 1~N^2, 共 N 行N 列,每个数字输出占4个西文字符宽度,右对齐,最后一个数字后无多余字符。

样例:

输入:
15
输出:

    

#include <stdio.h>
int main()
{
	int N, a[30][30], num = 1;
	scanf_s("%d", &N);
	for (int i = 0; i < N / 2; i++)
	{
		for (int x = i; x < N - 1 - i; x++)
			a[i][x] = num++;
		for (int y = i; y < N - 1 - i; y++)
			a[y][N - 1 - i] = num++;
		for (int z = N - 1 - i; z >= i + 1; z--)
			a[N - 1 - i][z] = num++;
		for (int p = N - 1 - i; p >= i + 1; p--)
			a[p][i] = num++;
	}
	if (N % 2 != 0)
	{
		a[N / 2][N / 2] = num;
		for (int k = 0; k < N; k++)
		{
			for (int j = 0; j < N; j++)
				printf("%4d", a[k][j]);
			if (k < N - 1)
				printf("\n");
		}
	}
	else
		for (int k = 0; k < N; k++)
		{
			for (int j = 0; j < N; j++)
				printf("%4d", a[k][j]);
			if (k < N - 1)
				printf("\n");
		}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值