1、判断题
1-1
通过对堆栈S操作:Push(S,1), Push(S,2), Pop(S), Push(S,3), Pop(S), Pop(S)。输出的序列为:123。
F
1-2
若一个栈的输入序列为{1, 2, 3, 4, 5},则不可能得到{3, 4, 1, 2, 5}这样的出栈序列。
F
1-3
在用数组表示的循环队列中,front值一定小于等于rear值。
F
1-4
栈是插入和删除只能在一端进行的线性表;队列是插入在一端进行,删除在另一端进行的线性表。
T
1-5
栈顶元素和栈底元素有可能是冋一个元素。
T
1-6
在n个元素连续进栈以后,它们的出栈顺序和进栈顺序一定正好相反。
F
1-7
栈和队列的存储方式,既可以是顺序方式,也可以是链式方式。
T
1-8
对顺序栈进行进栈、出栈操作不涉及元素的前、后移动问题。
T
1-9
n个元素通过一个栈产生n个元素的出栈序列,其中进栈和出栈操作的次数总是相等的。
T
1-10
循环队列也存在着空间溢出问题。
T
1-11
队列是一种插入和删除操作分别在表的两端进行的线性表,是一种先进后出的结构。
F
1-12
(neuDS_C++)空串与空格串是相同的。
F
1-13
(nueDS_C++)如果一个串中的所有字符均在另一串中出现,则说前者是后者的子串。
F
1-14
假设模式串是abababaab,则KMP模式匹配算法中的next[j] = 0 1 1 2 3 4 5 6 2。
F
2、单项选择题
2-1
假设有5个整数以1、2、3、4、5的顺序被压入堆栈,且出栈顺序为3、5、4、2、1,那么为了获得这样的输出,堆栈大小至少为:
- 2
- 3
- 4
- 5
C
2-2
若一个栈的入栈序列为1、2、3、…、N,其输出序列为p
1 、p2 、p3 、…、pN 。若p1 =N,则pi 为:
- i
- n−i
- n−i+1
- 不确定
C
2-3
若栈采用顺序存储方式存储,现两栈共享空间V[m]:top[i]代表第i(i=1或2)个栈的栈顶;栈1的底在V[0],栈2的底在V[m-1],则栈满的条件是:
- |top[2]-top[1]|==0
- top[1]+top[2]==m
- top[1]==top[2]
- top[1]+1==top[2]
D
2-4
若用大小为6的数组来实现循环队列,且当前front和rear的值分别为0和4。当从队列中删除两个元素,再加入两个元素后,front和rear的值分别为多少?
- 2和0
- 2和2
- 2和4
- 2和6
C
2-5
有一个100阶的三对角矩阵M,其三对角元素m
i,j
(1≤i≤100,1≤j≤100)按行优先次序压缩存入下标从0开始的一维数组N中。元素m
30,30
在N中的下标是:
- 86
- 87
- 88
- 89
B
2-6
适用于压缩存储稀疏矩阵的两种存储结构是:
- 三元组表和十字链表
- 三元组表和邻接矩阵
- 十字链表和二叉链表
- 邻接矩阵和十字链表
A
2-7
为了减小栈溢出的可能性,可以让两个栈共享一片连续存储空间,两个栈的栈底分别设在这片空间的两端,这样只有当( )时才可能产生上溢。
- 两个栈的栈顶在栈空间的某一位相遇
- 其中一栈的栈顶到达栈空间的中心点
- 两个栈的栈顶同时到达空间的中心点
- 两个栈均不空,且一个栈的栈顶到达另一个栈的栈顶
A
2-8
栈的插入和删除操作在( )进行。
- 栈顶
- 栈底
- 任意位置
- 指定位置
A
2-9
下列算法的功能是()。
void func( )
{
int x;
Statck s; //定义栈s
cin >> x;
while (x<>0)
{
push(s,x);
cin>>x;
}
while (!EmptyStack(s))
cout << pop(s);
}
- 以读入数据的相同顺序输出数据
- 以读入数据的相反顺序输出数据
- 将数据读入到栈中进行保存
- 读入一批数据到栈中进行求和并输出
B
2-10
在一个链队列中,front和rear分别为头指针和尾指针,则插入一个结点s的操作为( )。
- front=front->next
- s->next=rear;rear=s
- rear->next=s;rear=s;
- s->next=front;front=s;
B
2-11
(nueDS_C++)一个队列的数据入列序列是1,2,3,4,则队列的出队时输出序列是( ) 。
- 4,3,2,1
- 1,2,3,4
- 1,4,3,2
- 3,2,4,1
B
2-12
(neuDS)设有两个串p和q,其中q是p的子串,求q在p中首次出现的位置的算法称为( )。
- 求子串
- 联接
- 模式匹配
- 求串长
C
2-13
(neuDS)设有一个10阶的对称矩阵A,采用压缩存储方式,以行序为主进行存储,a11为第一元素,其存储地址为1,每个元素占一个地址空间,则a85的地址为( )
- 13
- 33
- 18
- 40
B
2-14
(neuDS)用十字链表表示一个稀疏矩阵,每个非零元素一般用一个含有( )域的结点表示。
- 5
- 4
- 3
- 2
A
2-15
在解决计算机主机和打印机之间速度不匹配问题时通常设置一个打印数据缓冲区,主机将要输出的数据依次写入该缓冲区,而打印机将要输出的数据依次写入该缓冲区,而打印机则从该缓冲区中取走数据打印.该缓冲区应该是一个( )结构。
- 栈
- 队列
- 数组
- 任意
B
2-16
下面关于串的叙述中,哪一个是不正确的
- 串是字符的有限序列
- 空串是由空格构成的串
- 模式匹配是串的一种重要运算
- 串既可以采用顺序存储,也可以采用链式存储
B
2-17
假设链队列头指针直接指向队头元素,进行出队操作时需要的操作为( )。
- 仅修改头指针
- 仅修改尾指针
- 头、尾指针都必须修改
- 头、尾指针可能都要修改
D
2-18
假设元素按照e1,e2,e3,e4,e5,e6的次序进栈,出栈序列为e2,e4,e3,e6,e5,e1,则栈的容量至少是()。
- 6
- 4
- 3
- 2
C
2-19
已知字符串S为“abaabaabacacaabaabcc”,模式串t为“abaabc”。采用KMP算法进行匹配,第一次出现“失配”(s[i]≠t[j])时,i=j=5,则下次开始匹配时,i和j的值分别是()。
- i=1,j=0
- i=5,j=0
- i=5,j=2
- i=6,j=2
C
3、程序填空题
5-1
循环队列入队出队操作。
#include<iostream>
using namespace std;
#define MAXQSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef char QElemType;
typedef char SElemType;
typedef int Status;
typedef struct {
QElemType *base;
int front;
int rear;
} SqQueue;
Status InitQueue(SqQueue &Q) {
/*1*/Q.base = (QElemType *)malloc(MAXQSIZE*sizeof(QElemType));
if (!Q.base)
exit(OVERFLOW);
/*2*/Q.front = Q.rear = 0
;
return OK;
}
Status EnQueue(SqQueue &Q, QElemType e) {
/*3*/if (Q.front = Q.rear = 0)
return ERROR;
Q.base[Q.rear] = e;
/*4*/Q.rear=(Q.rear + 1) % MAXQSIZE;
return OK;
}
Status DeQueue(SqQueue &Q, QElemType &e) {
/*5*/if (Q.rear == Q.front)
return ERROR;
e = Q.base[Q.front];
/*6*/Q.front = (Q.front + 1) % MAXQSIZE;
return OK;
}
int main() {
SqQueue Q;
int n, i;
char c;
InitQueue(Q);
cin >> n;
for(i=0;i<n;i++){
cin >> c;
EnQueue(Q,c);
}
for(i=0;i<n;i++){
DeQueue(Q,c);
cout << c << " ";
}
return 0;
}
5-2
将一个十进制数转换成八进制数。
#include<iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct SNode {
int data;
struct SNode *next;
} SNode, *LinkStack;
Status InitStack(LinkStack &S) {
S = NULL;
return OK;
}
bool StackEmpty(LinkStack S) {
if (!S)
return true;
return false;
}
Status Push(LinkStack &S, int e) {
LinkStack p;
p = new SNode;
if (!p) {
return OVERFLOW;
}
p->data = e;
p->next = S;
S = p;
return OK;
}
Status Pop(LinkStack &S, int &e) {
LinkStack p;
if (!S)
return ERROR;
e = S->data;
p = S;
S = S->next;
delete p;
return OK;
}
void conversion(int N) {
int e;
LinkStack S;
InitStack(S);
while (N)
{
/*1*/Push(&S,N%8);
N = N / 8;
}
while (!StackEmpty(S))
{
/*2*/Pop(&S,&x);
cout << e;
}
}
int main() {
int n, e;
cin >> n;
conversion(n);
return 0;
}
4、编程题
7-1 括号匹配 (20 分)
检查一段C语言代码的小括号( )、 中括号 [ ] 和大括号{ } 是否匹配。
输入格式:
在一行中输入一段C语言代码,长度不超过1000个字符(行末以换行符结束)。
输出格式:
第一行输出左括号的数量和右括号的数量,中间以一个空格间隔。
若括号是匹配的,在第二行打印YES,否则打印NO。
输入样例1:
for(int i=0; i<v; i++){ visited[i] = 0; for(int j=0; j<v; j++) scanf("%d",&(g->Adj[i][j])); }
输出样例1:
8 8
YES
输入样例2:
for(int i=0; i<v; i++) a(i]=0;
输出样例2:
2 2
NO
#include <iostream>
#include <stack>
using namespace std;
bool is_left_kuohao(char ch)
{
return ch == '(' || ch == '[' || ch == '{';
}
bool is_right_kuohao(char ch)
{
return ch == ')' || ch == ']' || ch == '}';
}
bool match(char left, char right)
{
return (left == '(' && right == ')') ||
(left == '[' && right == ']') ||
(left == '{' && right == '}');
}
int main()
{
string line;
getline(cin, line);
int left_kuohao_count = 0;
int right_kuohao_count = 0;
for (int i = 0; i < line.length(); i++)
{
if (is_left_kuohao(line[i]))
left_kuohao_count += 1;
if (is_right_kuohao(line[i]))
right_kuohao_count += 1;
}
cout << left_kuohao_count << " "
<< right_kuohao_count << endl;
stack<char> left_kuohaos;
for (int i = 0; i < line.length(); i++)
{
if (is_left_kuohao(line[i]))
left_kuohaos.push(line[i]);
if (is_right_kuohao(line[i]))
{
if (!left_kuohaos.empty() && match(left_kuohaos.top(), line[i]))
left_kuohaos.pop();
else
{
cout << "NO" << endl;
return 0;
}
}
}
if (left_kuohaos.empty())
cout << "YES" << endl;
else
cout << "NO" << endl;
return 0;
}
7-2 串的模式匹配 (20 分)
给定一个主串S(长度<=106)和一个模式T(长度<=105),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串S中出现的位置。
输入格式:
输入有两行: 第一行是主串S; 第二行是模式T.
输出格式:
输出相匹配的子串中的第一个字符在主串S中出现的位置。若匹配失败,输出0.
输入样例:
在这里给出一组输入。例如:
aaaaaba
ba
输出样例:
在这里给出相应的输出。例如:
6
#include<iostream>
#include<string.h>
using namespace std;
char* trans(string str)
{
int size = str.length();
char *s;
s= new char[size];
strcpy(s, str.c_str());
return s;
}
void calc_next(string pstring, int *next)
{
next[0] = -1;//-1表示模式串开头
int j = 0, k = -1;
int p_len = pstring.length();//模式串长度
char *p = trans(pstring);//模式串字符数组
while(j<p_len){//当j尚未指向模式串尾端时
if(k == -1 || p[j] == p[k]) {
k++;//k指前缀开始下标
j++;//j指后缀开始下标
next[j] = k;//next[]存放已匹配子串中最长前后缀长度
//其中,next[j]表示 p[0]-p[j-1]子串中最长前后缀长度
}else{
k = next[k]; //k回溯到模式串开头
}
}
}
int kmp(string sstring, string pstring)
{
int *next = new int[pstring.length()];
calc_next(pstring, next);//得到 next[]数组
char *s = trans(sstring), *p = trans(pstring); //转字符串为字符数组
int i=0, j=0;
int pos = 0;
while( i<=sstring.length() || j<=pstring.length()){
if( j == -1 || s[i] == p[j]){
i++;
j++;
}else{
j = next[j];
}
if(j == pstring.length()){//匹配成功
pos = i-j+1;
break;
}
}
return pos;
}
int main()
{
string sstring, pstring;//定义字符串
getline(cin, sstring);//输入字符串
getline(cin, pstring);
cout<<kmp(sstring, pstring);
return 0;
}