170 likes | 316 Views
题 3.17. 题 3.19. 题 3.28. 题 3.22. 题 3.31. 题 3.32. 题 3.19. int matching(SqList exp) { // 顺序表 exp 中存有数据元素为字符的表达式 , // 若表达式中三种括弧正确嵌套,则返回 1, // 否则返回 0 。 }. state = 1; i = 1; InitStack(S); while (i<=exp.length && state ) { }
E N D
题3.17 题3.19 题3.28 题3.22 题3.31 题3.32
题3.19 int matching(SqList exp) { // 顺序表exp中存有数据元素为字符的表达式, // 若表达式中三种括弧正确嵌套,则返回 1, // 否则返回 0。 } state = 1; i = 1; InitStack(S); while (i<=exp.length &&state) { } if (state&& StackEmpty(S)) return 1; else return 0; ……
switch of exp.elem[i] { case左括弧: {Push(S, exp.elem[i]); i++; break;} case): { if (NOT StackEmpty(S) && GetTop(S)=() { Pop(S,e); i++; } else state = 0; break; } case]: { if (NOT StackEmpty(S) && GetTop(S)=[) { Pop(S,e); i++; } else state = 0; break; } case}: ……
识别读入的一个字符序列是否为反对称的字符序列。识别读入的一个字符序列是否为反对称的字符序列。 题3.17 例如:abcd&dcba@是反对称字符序列; abc&@或 abc&abc@或 ab&bac@都不是反对称字符序列。 则这个算法和“判别括弧是否正确匹配”的算法极其相似。
同样,在算法过程中需要用到一个栈,由于序列中必定出现字符 & , 则可将在字符&出现之前的所有字符均入栈,滤去字符&之后再读入的字符则应和栈顶的字符相等,当然,首先必须判别此时的“栈”是否为“空栈”。 此题的参数仅为一个字符序列,可以设为元素为字符的数组。
int symmetry(char Ch[] ) { // 若 Ch[] 为反对称字符序列,则返回 1, //否则返回 0。 } p = Ch; InitStack(S); while (*p!=‘&’) { Push(S,*p); p++; } state = 1; p++; // 滤去字符‘&’ while (*p!=‘@’ && state ) { if (NOT StackEmpty(S)&&GetTop(S)==*p ) { Pop(S,e); p++; } else state = 0; } return(StackEmpty(S) && state )
int valuation(SqList suffixal) { IniStack(S); p=suffixal.elem; ch=*p; while ( ch != # ) { if (!IN(ch,OP)) Push(S,ch); else { Pop(S,b); Pop(S,a); x=value(a,ch,b); e=setvar(x); // e 为其值=x的变量名 Push(S,e); } ch=*p++; } Pop(S,e); return(val(e)); // 返回变量e的值 } 题3.22
定义循环链队列 题3.28 typedef QueuePtr CLQueue; // 指向队尾结点的指针 初始化操作 Status InitQueue(CLQueue &Q) { // 构造空队列 Q = new Qnode; // 生成头结点 if (!Q) exit(OVERFLOW); // 存储分配失败 Q->next = Q; // 自成循环 return OK; }
入队列操作 Status EnQueue(CLQueue &Q, QElemType e) { // 插入元素 e 为新的队尾元素 p = new Qnode; // 生成新的结点 if (!p) exit(OVERFLOW); // 存储分配失败 p->data = e; p->next= Q->next; Q->next = p; // 插入队尾 Q = p; // 修改队尾指针 return OK; }
出队列操作 Status DeQueue(CLQueue &Q, QElemType& e) { // 若队列不空,则删除Q的队头元素,以 e 带回 // 其值,并返回OK,否则返回 ERROR if (Q->next == Q) return(ERROR); // 空队列 p = Q->next->next; e = p->data; Q->next->next = p->next; // 删除队头元素 if (p == Q) Q = Q->next; delete p; return OK; // 释放被删结点 }
题3.31 判别读入的字符序列是否为“回文”。 例如: abcdedcba或 abccba是回文。 由于回文的字符序列中的分界线不明确,因此无法判定字符序列的“中间位置”,即只能按照回文的定义从字符的两头出发进行判别。
然而,按照题目的要求,这个字符序列是从外部环境输入的。为了在输入结束的时候,同时能得到序列的“头”和“尾”,因此算法中,除了需要用一个栈之外,还需要一个队列。然而,按照题目的要求,这个字符序列是从外部环境输入的。为了在输入结束的时候,同时能得到序列的“头”和“尾”,因此算法中,除了需要用一个栈之外,还需要一个队列。 算法的基本思想是: 将依次读入的字符分别插入栈和队列,然后依次比较“栈顶”和“队头”的字符。
Status ex331( ) { // 若从终端依次输入的字符序列是“回文”,// 则返回TRUE,否则返回FALSE InitStack(S); InitQueue(Q); scanf(ch); while(ch!=@) { Push(S, ch); EnQueue(Q, ch); scanf(ch); }
state=TRUE; while(!StackEmpty && state) { if(GetTop(S)==GetHead(Q)) { Pop(S); DeQueue(Q); } else state=FALSE; } return state; }
题3.32 k 阶斐波那契函数的定义: f0 = f1 = …… = fk-2 = 0, fk-1 = 1, fn = fn-1+fn-2+…… + fn-k n ≥k 由于题目要求循环队列的容量为 k, 即当前队列中 k 个元素之和为下一个函数值。 利用公式 fn = 2fn-1 - fn-k-1 可以简化计算,但需要队列的容量为 k+1。
void k_Fib(CQueue Q, int k, int max) { for (i=0; i<k-1; i++) Q.elem[i] = 0; //赋初值 Q.elem[k-1] = 1; Q.rear = 0; f = 1; while ( f <= max ) { cout << Q.elem[Q.rear]; // 输出队头元素 Q.elem[Q.rear] = f; // 插入新的队尾元素 Q.rear ++; // 队尾指针增1 f = 0; // 计算下一个函数值 for ( i=0; i<k; i++) f+= Q.elem[i]; } 继续输出循环队列中的其余函数值; }
void k_Fib( int k, int max) { InitQueue(Q); //附设含k+1个分量的循环队列 for (i=0; i<k-1; i++) EnQueue(Q, 0); EnQueue(Q, 1); f = 1; //赋初值 while ( f <= max ) { DeQueue(Q, e); cout << e <<‘,’; // 输出队头元素 EnQueue(Q, f ); // 插入新的队尾元素 f = 2*f - e; // 计算下一个函数值 } // while while(! QueueEmpty (Q)) { DeQueue( Q, e); cout << e << ‘e’; // 继续输出循环队列中的其余函数值 } }