赞
踩
标准Web浏览器具有在最近访问的网页间后退和前进的功能。实现这些功能的一个方法是:使用两个栈,追踪可以后退和前进而能够到达的网页。在本题中,要求模拟实现这一功能。
需求分析
需要支持以下指令
(1)BACK:将当前页推到“前进栈”的顶部。取出“后退栈”中顶端的页面,使它成为当前页。若“后退栈”是空的,忽略该命令。
(2)FORWARD:将当前页推到“后退栈”的顶部。取出“前进栈”中顶部的页面,使它成为当前页。如果“前进栈”是空的,忽略该命令。,
(3)VISIT <url>:将当前页推到“后退栈”的顶部。使URL特指当前页。清空“前进栈”。,URL中没有空格,最多70个字符。
(4)QUIT:退出浏览器。除了QUIT命令外,若某一命令没有被忽略掉,则在命令执行后输出当前页的URL,否则输出“Ignored”。对每个输入命令,产生相应的输出。QUIT命令不产生任何输出。
(5)针对所有测试数据,任何时候在每个栈中的元素都不超过100个。
(6)假设浏览器首先加载的网页URL是: http://www.acm.org/。
(1)功能图
(2)概要设计
void PUSHQ(QU* qu, char cur[])//入队
void POPQ(QU* qu)//出队
void PUSH(ST* st, char cur[])//入栈
void POP(ST* st)//出栈
int EMPTY(ST* st)//判空
void BACK(ST* stfront, ST* strear, char cur[], QU* qu)//回溯
void FORWARD(ST* stfront, ST* strear, char cur[], QU* qu)//前寻
void VISIT(ST* stfront, ST* strear, char cur[], QU* qu)//访问
(3)存储结构
typedef struct stack
{
char s[100][70];
int top;
}ST;//栈定义
typedef struct queue
{
char q[100][70];
int head;
int tail;
}QU;//队列定义,用于接受输出
(4)源代码
- #define _CRT_SECURE_NO_WARNINGS 1
-
- #include <stdio.h>
-
- #include <stdlib.h>
-
- #include <string.h>
-
- typedef struct stack
-
- {
-
- char s[100][70];
-
- int top;
-
- }ST;//栈定义
-
- typedef struct queue
-
- {
-
- char q[100][70];
-
- int head;
-
- int tail;
-
- }QU;//队列定义,用于接受输出
-
- void PUSHQ(QU* qu, char cur[])//入队
-
- {
-
- if (qu->tail == 100)
-
- {
-
- printf("队满\n");
-
- }
-
- else
-
- {
-
- qu->tail++;
-
- strcpy_s(qu->q[qu->tail], strlen(cur) + 1, cur);
-
- }
-
- }
-
- void POPQ(QU* qu)//出队
-
- {
-
- qu->head++;
-
- }
-
- void PUSH(ST* st, char cur[])//入栈
-
- {
-
- if (st->top == 100)
-
- {
-
- printf("栈满\n");
-
- }
-
- else
-
- {
-
- strcpy_s(st->s[st->top], strlen(cur) + 1, cur);
-
- st->top++;
-
- }
-
- }
-
- void POP(ST* st)//出栈
-
- {
-
- if (st->top == 0)
-
- {
-
- printf("栈空\n");
-
- }
-
- else
-
- {
-
- st->top--;
-
- }
-
- }
-
- int EMPTY(ST* st)//判空
-
- {
-
- if (st->top == 0)
-
- return 1;
-
- else
-
- return 0;
-
- }
-
- void BACK(ST* stfront, ST* strear, char cur[], QU* qu)//回溯
-
- {
-
- if (!EMPTY(strear))
-
- {
-
- PUSH(stfront, cur);
-
- POP(strear);
-
- strcpy_s(cur, strlen(strear->s[strear->top]) + 1, strear->s[strear->top]);
-
- PUSHQ(qu, cur);
-
- }
-
- else
-
- {
-
- char* a = "Ignored";
- PUSHQ(qu, a);
-
- }
-
- }
-
- void FORWARD(ST* stfront, ST* strear, char cur[], QU* qu)//前寻
-
- {
-
- if (!EMPTY(stfront))
-
- {
-
- PUSH(strear, cur);
-
- POP(stfront);
-
- strcpy_s(cur, strlen(stfront->s[stfront->top]) + 1, stfront->s[stfront->top]);
-
- PUSHQ(qu, cur);
-
- }
-
- else
-
- {
-
- char* a = "Ignored";
- PUSHQ(qu, a);
-
- }
-
- }
-
- void VISIT(ST* stfront, ST* strear, char cur[], QU* qu)//访问
-
- {
-
- PUSHQ(qu, cur);
-
- stfront->top = 0;
-
- }
-
-
-
- int main()
-
- {
-
- printf("输入:\n");
-
- ST stfront;
-
- ST strear;
-
- stfront.top = 0;
-
- strear.top = 0;
-
- QU qu;
-
- qu.head = -1;
-
- qu.tail = -1;
-
- char cur[70];
-
- char start[70] = "http://www.acm.org/";//需先对此网站进行如回溯栈的特殊处理
-
- char in[2][70];
-
- strcpy_s(cur, strlen(start) + 1, start);
-
- scanf_s("%s", in[0], 70);
-
- while (strcmp(in[0], "QUIT") != 0)
-
- {
-
- if (strcmp(in[0], "VISIT") == 0)
-
- {
-
- PUSH(&strear, cur);
-
- scanf_s("%s", in[1], 70);
-
- strcpy_s(cur, strlen(in[1]) + 1, in[1]);
-
- VISIT(&stfront, &strear, cur, &qu);
-
- }
-
- else if (strcmp(in[0], "QUIT") == 0)
-
- {
-
- break;
-
- }
-
- else if (strcmp(in[0], "BACK") == 0)
-
- {
-
- BACK(&stfront, &strear, cur, &qu);
-
- }
-
- else
-
- {
-
- FORWARD(&stfront, &strear, cur, &qu);
-
- }
-
- scanf_s("%s", in[0], 70);
-
- }
-
- printf("输出:\n");//输出
-
- while (qu.head != qu.tail)
-
- {
-
- POPQ(&qu);
-
- printf("%s\n", qu.q[qu.head]);
-
- }
(1)问题
现象:"const char *" 类型的值不能用于初始化 "char *" 类型的实体。
原因:有些编译器将字符串字面值视为只读常量,如果试图修改它们,将导致运行阶段错误。字符串字面值都将被视为常量,但并不是所有的编译器都对以前的行为做了这样的修改。有些编译器只使用字符串字面值的一个副本来表示程序中所有的该字面值。
方法:打开项目–>属性–>c/c+±->语言–>符合模式–>否,此方法虽然不会报错,但是执行后,无论输入什么,都不会继续下一步操作,并不推荐。最后发现需要将文件类型由.cpp转化为.c文件即可。
(2)运行结果
按书上一些列命令后,得到对应输出结果,并且结果相符合。这里需要输入完命令以后,并输入QUIT之后才会显示所有的输出,而不是输入一项再输出一项,且所有的命令都是大写。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。