实验04数组及其在程序设计中的应用(2023级)吉林大学高级语言程序设计作业

请同学们先看提示,自行思考实践后无果再看通过代码。学习不要欺骗自己!!!

欢迎校友+q3023225096进行讨论交流

1.括号匹配(提示:栈)

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

题目名称:括号匹配

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

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

输出:如果字符串中三类括号匹配,则输出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>
#include <stdlib.h>
/*以下两项分别是栈和栈顶指针,建议用全局声明*/
char stack[1000] = {""};			  //初始化栈
int top=0;						      //初始化栈顶序号,其始终对应栈顶部的第一个空元素

void push(char ch);							//入栈函数声明,把接收的元素压入栈中
char pop(void);							    //出栈函数声明,弹出并获取最顶部栈项
void check(char left, char right);		    //检查函数声明,左右括号匹配检查

int main()				//主函数
{
	for (char ch = getchar(); ch != '@'; ch = getchar())		//循环读取缓冲区字符并送入开关语句
		switch (ch)
		{
		case '(':								//只有左括号才入栈
		case '[':
		case '{':push(ch); break;
		case ')':check(pop(), '('); break;		//对右括号逐个检查匹配性
		case ']':check(pop(), '['); break;
		case '}':check(pop(), '{'); break;
		}
	printf("YES");								//如果能成功结束循环就YES,即所有括号匹配成功
	return 0;
}
 
void push(char ch)					  //入栈函数定义
{
	stack[top++] = ch;
}

char pop(void)					      //出栈函数定义
{
	if (top > 0)
		return stack[--top];
	else
	{
		printf("NO");
		exit(0);							//栈空,出栈失败,打印NO并退出程序
	}
}

void check(char left, char right)	  //检查函数定义
{
	if (left != right)		 //如果弹出的元素不是右括号对应的左括号,即左接收值≠右接收值
	{
		printf("NO");					//括号不匹配,打印NO并退出程序
		exit(0);
	}
}

2.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>
#include<stdlib.h>
int main()
{
	int i, j, l, n = 0, k = 0, r = 0;
	int arr1[30] = { 0 };
	scanf("%d", &n);
	while (1)
	{
		int arr[200] = { 0 }; i = 0;
		do
		{
			scanf("%d", &arr[i++]);
			if (arr[i - 1] == -1) break;
		} while (arr[i - 1] != 0);
		if (arr[i - 1] == -1) break;
		i--;
		for (l = 0; l < i - 1; l++)            //一定一动的遍历检查法,可以优化
			for (j = l + 1; j < i; j++)
				if (arr[l] == n * arr[j] || arr[l] * n == arr[j])
					arr1[r]++;
		r++;
	}
	for (int s = 0; s < r; s++)
	{
		if (k == 0)
		{
			k = 1; printf("%d", arr1[s]);
		}
		else printf("\n%d", arr1[s]);
	}
	return 0;
}

4.删除重复元素 (提示:样例没有负数)

题目编号: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

卡bug,样例没有负数

#include<stdio.h>
int main()
{
	int arr[101];
	int i = 0, j = 0, n = 10;
	scanf("%d", &n);
	for (; i < n;) scanf("%d", &arr[i++]);
	for (i=0;i<n;i++)
	{
		for(j=i+1;j<n;j++)
		if (arr[i] == arr[j]) arr[j] = -1;
	}
	for(j=0;n>0;j++,n--)
	{
		if (arr[j] == -1) continue;
		if(j==0) printf("%d", arr[j]);
		else printf(" %d", arr[j]);
	}
	return 0;
}

10.字符串反序 (提示:无)

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

题目名称:字符串反序

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

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

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

样例1:

输入 A            输出 A

样例2:

输入 123 45    输出  54 321

两行够了

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[256]; gets(arr);
	for (int i = strlen(arr) - 1; i >= 0; i--) printf("%c", arr[i]);
	return 0;
}

11.约瑟夫环(提示:理解题意,可以用-1代表死人,0与肮数据混淆不能用)

题目编号 :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

典型链表题,但是可以卡bug(滑稽)

#include<stdio.h>
int main()
{
	int arr[1000] = { 0 }, n = 10, m = 10, s = 10, i, j, count, k = 0;	//n为总人数,s为开始计数的序号,m为处决对应报的数
	scanf("%d %d %d", &n, &s, &m);					//i为当前人的序号,j为报的数,报数报到m即被处决
	for (i = 1; i <= n; i++) arr[i] = i;	//给所有人编序号
	for (i = s, count = 0; count < n; count++)
	{
		for (j = 0;;)
		{
			if (i == n + 1) i = 1;			//if-for-if 语块作用是实现循环报数并跳过死人轮到下一个活人
			for (; arr[i] == -1; i++);
			if (i == n + 1) i = 1;
			j++;	    //当前的人报数
			if (j == m) break;	    //报数报到m就处决
			i++;
			if (i == n + 1) i = 1;		    //同上
			for (; arr[i] == -1; i++);
			if (i == n + 1) i = 1;
		}
		if (k == 0) { printf("%ld", arr[i]); k = 1; }      // if-else保持输出格式正确
		else printf(" %ld", arr[i]);				   //先输出序号再处决
		arr[i++] = -1;	    //赋值为-1即处决,并轮到下一个人
		if (i == n + 1) i = 1;			    //同上
		for (; arr[i] == -1; i++);
		if (i == n + 1) i = 1;
	}
	return 0;
}

12. 英文翻译自然数(提示:数组的进阶初始化)

题目编号 :Exp04-Enhance03,freshman-1006

题目名称:英文翻译自然数

题目描述:按常规英文输出1000以内自然数的英文读法。
 

输入:每个测试输入包含 1 个测试用例,给出正整数 n(0<= n <1000)

输出:输出占一行:如果 0<= n <1000, 用规定的格式输出 n,所有英文单词小写,最后一个单词后无字符;否则输出ERR。

样例1:

输入:41
输出:forty-one

样例2:

输入:123
输出:one hundred and twenty-three

这里也可以用二维数组存放多个字符串

#include<stdio.h>
#include<string.h>
int main()
{
	int n = 0, i = 0, a, b, c;
	char arr[4];
	char* arr1[] = { "zero","one","two","three","four","five","six","seven","eight","nine" };
	char* arr2[] = { "ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen" };
	char* arr3[] = { "0","0","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety" };
	gets(arr);
	c = arr[2] - '0'; b = arr[1] - '0'; a = arr[0] - '0';
	if (strlen(arr) == 3)
	{
		if (b > 1)
		{
			if (c > 0)
				printf("%s hundred and %s-%s", arr1[a], arr3[b], arr1[c]);
			else
				printf("%s hundred and %s", arr1[a], arr3[b]);
		}
		else if (b == 1)
			printf("%s hundred and %s", arr1[a], arr2[c]);
		else if (b == 0)
		{
			if (c > 0)
				printf("%s hundred and %s", arr1[a], arr1[c]);
			else
				printf("%s hundred", arr1[a]);
		}
	}
	else if (strlen(arr) == 2)
	{
		if (a > 1 && b > 0)
			printf("%s-%s", arr3[a], arr1[b]);
		else if (a > 1 && b == 0)
			printf("%s", arr3[a]);
		else if (a = 1 && b > 0)
			printf("%s", arr2[b]);
		else if (a = 1 && b == 0)
			printf("ten");
	}
	else printf("%s", arr1[a]);
	return 0;
}

13.螺旋矩阵 (提示:找规律)

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

题目名称:螺旋矩阵

题目描述:

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

1.JPG

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

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

样例:

输入: 15
输出:

    

2.JPG

本人的得意之作

#include<stdio.h>
int main()
{
	int arr[30][30], i = 0, j = -1, n = 5, m, a, b, c, d;
	scanf("%d", &n);
	for (m = 0, b = n - 1, d = n; d > 0; b--, d--)
	{
		for (c = 0; c < d; c++) arr[i][++j] = ++m;
		for (a = 0; a < b; a++) arr[++i][j] = ++m;
		b--; d--;
		for (c = 0; c < d; c++) arr[i][--j] = ++m;
		for (a = 0; a < b; a++) arr[--i][j] = ++m;
	}
	for (i = 0, j = 0; i < n; i++)
	{
		if (i > 0) printf("\n");
		for (j = 0; j < n; j++) printf("%4d", arr[i][j]);
	}
	return 0;
}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值