BUAA数据结构2023级期末考试第二题

【问题描述】

一般的浏览器都可以通过“后退”或“前进”查看历史访问记录,编写程序模拟实现该功能,并统计浏览爱好(即:访问次数最多的网站)。

假设浏览器缺省打开的网页为:https://www.baidu.com/,(即:打开浏览器第一个访问的网页都是https://www.baidu.com/)。

输入的网页地址格式只有两种:

(1)https://....../               表示某网站地址,网站名为位于“https://”和“/”之间的字符串,例如:www.buaa.edu.cn

(2)https://....../.../.../......      表示某网站下的网页地址,例如:https://www.buaa.edu.cn/bhgk/jrbh.htm

上述两种格式都是以“https://”开始,且网页地址中没有空白符,最多不超过80个字符。

为了实现该功能,假设有两个栈存放网页访问历史记录:“后退栈”和“前进栈”,这两个栈初始都为空,其作用见输入形式中描述。

【输入形式】

从控制台输入如下命令和网页地址:

VISIT:表示访问某网页,该命令与后面网页地址间以一个空格分隔;其功能是:先将当前网页压入“后退栈”,然后将VISIT后的网页地址指定为新的当前网页,同时清空“前进栈”。所输入的网页地址格式只有上述两种,且输入的网页地址与当前网页地址是不同的。该命令个数少于100。

<- :由英文小于字符和减号字符组成,中间无空格;表示后退命令,其功能是:先将当前网页压入“前进栈”,然后从“后退栈”弹出网页,使其成为新的当前网页。如果执行该命令前“后退栈”为空,则忽略该命令(即当前网页、“前进栈”、“后退栈”都不变)。“后退栈”最多能存入100个网页,且不会满。

-> :由英文减号字符和大于字符组成,中间无空格;表示前进命令,其功能是:先将当前网页压入“后退栈”,然后从“前进栈”弹出页面,使其成为新的当前页面。如果执行该命令前“前进栈”为空,则忽略该命令(即当前网页、“前进栈”、“后退栈”都不变)。“前进栈”最多能存入100个网页,且不会满。

QUIT:表示退出浏览器,后跟参数0或1,QUIT和参数间以一个空格分隔。其后参数若为0:表示只输出所浏览过的网页;其后参数若为1:表示除输出所浏览过的网页外,还要输出浏览次数最多的网站和浏览次数。

【输出形式】

按行输出所浏览过的网页,若QUIT后参数为1,还要输出浏览次数最多的网站名和浏览次数,网站名定义见上述“问题描述”中网页地址格式(1),网站名和浏览次数之间以一个空格分隔。浏览次数最多的网站不会出现多个。

【样例输入】

VISIT https://www.buaa.edu.cn/

VISIT https://www.taobao.com/

<-

<-

<-

->

VISIT https://www.buaa.edu.cn/jgsz/jxkyjg.htm

<-

<-

->

->

->

QUIT 1

【样例输出】

https://www.baidu.com/

https://www.buaa.edu.cn/

https://www.taobao.com/

https://www.buaa.edu.cn/

https://www.baidu.com/

https://www.buaa.edu.cn/

https://www.buaa.edu.cn/jgsz/jxkyjg.htm

https://www.buaa.edu.cn/

https://www.baidu.com/

https://www.buaa.edu.cn/

https://www.buaa.edu.cn/jgsz/jxkyjg.htm

www.buaa.edu.cn 7

【样例说明】

初始浏览器打开的当前网页为https://www.baidu.com/,“前进栈”和“后退栈”都为空,然后依次执行输入的命令:

1、前两个为访问命令,先将https://www.baidu.com/和https://www.buaa.edu.cn/分别压入“后退栈”,同时分别访问网页https://www.buaa.edu.cn/和https://www.taobao.com/;

2、执行两个“后退”命令:先将https://www.taobao.com/和https://www.buaa.edu.cn/分别压入“前进栈”,同时分别访问“后退栈”弹出的网页https://www.buaa.edu.cn/和https://www.baidu.com/;

3、第五个命令为“后退”命令,此时“后退栈”为空,忽略该命令;

4、第六个命令为“前进”命令,先将https://www.baidu.com/压入“后退栈”,同时访问“前进栈”弹出的网页https://www.buaa.edu.cn/;

5、第七个命令为访问命令,先将网页https://www.buaa.edu.cn/压入“后退栈”,同时访问网页https://www.buaa.edu.cn/jgsz/jxkyjg.htm,并清空“前进栈”;

后面的“后退”和“前进”命令同上。

最后输入退出命令,后跟参数1,表示先按时间序依次输出浏览器访问过的网页,并且要统计输出访问次数最多的网站,网站www.buaa.edu.cn访问次数最多,为7次。若后跟参数为0,则只输出访问过的网页。

【评分标准】

该题要求模拟实现浏览器的访问网页和“后退”、“前进”功能,正确实现“QUIT 0”命令可得50%分数,提交程序名为web.c。

【思路】
1.按题目要求建两个栈(前进、后退)
2.建立结构体数组(包含网址与次数)
3.在输入中可以通过scanf("%s ",&xx)引号中带一个空格滤去输入中的空格,再通过strcmp函数来实现VISIT、QUIT、->、<-等的操作
4.通过前进、后退、VISIT的操作,依次向结构体数组中存入网址
5.通过遍历结构体数组输出网址可完成QUIT 0的操作
6.网站与网址相比,网站少了前面的https://以及第一个/与之后的内容,因此可以通过此条件遍历结构体数组,将读到的网址存入一个新的结构体数组
7.遍历新的结构体数组,通过新结构体中的cnt来标记次数

代码实现如下

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1024

typedef struct s1 {
	char web[100];
	int cnt;
} s1;

s1 whole[105];/*总网页*/
int w1 = 0;

char forth[105][100];
int f1 = -1; /*前进*/

char back[105][100];
int b1 = -1; /*后退*/

char temp[102][10];

s1 webb[105];

int cmp(const void*a, const void*b) {
	return ((struct s1*)b)->cnt - ((struct s1*)a)->cnt;
}
int main() {
	int n;
	strcpy(whole[0].web, "https://www.baidu.com/");
	w1++;
	int q = 1;
	int cnt = 0;
	while (q) {
		scanf("%s ", &temp[cnt]);
		if (strcmp(temp[cnt], "VISIT") == 0) {
			cnt++;
			scanf(" %s", &temp[cnt]);
			strcpy(back[++b1], whole[w1 - 1].web);
			strcpy(whole[w1++].web, temp[cnt]);
			f1 = -1;
			cnt++;
		} else if (strcmp(temp[cnt], "->") == 0) {
			cnt++;
			if (f1 != -1) {
				strcpy(back[++b1], whole[w1 - 1].web);
				strcpy(whole[w1++].web, forth[f1--]);
			}
		} else if (strcmp(temp[cnt], "<-") == 0) {
			cnt++;
			if (b1 != -1) {
				strcpy(forth[++f1], whole[w1 - 1].web);
				strcpy(whole[w1++].web, back[b1--]);
			}
		} else if (strcmp(temp[cnt], "QUIT") == 0) {
			scanf("%d", &n);
			q = 0;
		}
	}

	if (n == 0) {
		for (int i = 0; i < w1; i++) {
			printf("%s\n", whole[i].web);
		}
	}
	for(int i=0;i<w1;i++)
	{
		int flag=0;
		int w=0;
		while(flag!=3)
		{
			webb[i].web[w]=whole[i].web[w];
			w++;
			if(whole[i].web[w]=='/')
			{
				flag++;
			}
		}
	}
	
	
	if (n == 1) {
		for (int i = 0; i < w1; i++) {
			printf("%s\n", whole[i].web);
		}
		for (int i = 0; i < w1; i++) {
			for (int j = i + 1; j < w1; j++) {
				if (strcmp(webb[i].web, webb[j].web) == 0 && webb[j].cnt != -1) {
					webb[i].cnt++;
					webb[j].cnt = -1;
				}
			}
		}
		qsort(webb, w1, sizeof(struct s1), cmp);
		int len=strlen(webb[0].web);
		for(int i=8;i<len;i++)
		{
			printf("%c",webb[0].web[i]);
		}
		printf(" %d",webb[0].cnt+1);
	}
	
	return 0;
}

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值