㈠ 数据结构写程序实现表达式求值算法
这是c++的代码
0stdafx.h
//stdafx.h:标准系统包含文件的包含文件,
//或是经常使用但不常更改的
//特定于项目的包含文件
//
//#pragmaonce是一个比较常用的C/C++杂注,只要在头文件的最开始加入这条杂注,就能够保证头文件只被编译一次。
#pragmaonce
#include"targetver.h"
#include<stdio.h>
#include<tchar.h>
#include<iostream>
#include<stdlib.h>
#include<string>
#include<string.h>
#include<math.h>
#include<time.h>
usingnamespacestd;
//TODO:在此处引用程序需要的其他头文件
1 stack栈的结构
#pragmaonce
#include"stdafx.h"
#include"StackNode.h"
//LinkStack,链式栈的类定义
template<typenameT>
classStack{
private:
StackNode<T>*top;//curptr
//7个方法
public:
//ConstructFunction()
Stack():top(NULL){}
//DeConstructFunction()
~Stack(){
StackNode<T>*p;//temprefdomain
while(top!=NULL){//free()
p=top;
top=top->next;
deletep;
}
}
//Push()从栈顶压入一个元素
voidPush(constT&item){
StackNode<T>*p=newStackNode<T>;
p->data=item;//赋值
p->next=top;//connectcurptr
top=p;//curptrmove++
}
//Pop()从栈顶弹出一个元素
TPop(){
if(IsEmpty()){//emptystack
cerr<<"Attempttopopanemptystack!"<<endl;
exit(1);
}
StackNode<T>*p=top;//temprefdomain
TRetValue=p->data;//tempdatadomain
top=top->next;//top--move
deletep;//free()p,elsewillcrashmemory
returnRetValue;
}
//Peek(),GetTop()
TPeek()const{
if(IsEmpty()){//emptystack
cerr<<"Attempttopopanemptystack!"<<endl;
exit(1);
}
returntop->data;
}//!_Peek
//Clear()
voidClear(void){
//不free()会内存泄漏
StackNode<T>*p;//temprefdomain
while(top!=NULL){//free()
p=top;
top=top->next;
deletep;
}
this.top=NULL;
}//!_Clear()
//IsEmpty()
intIsEmpty(void)const{
returntop==NULL;
}//!_IsEmpty()
};//!_classStack
2表达式求值算法
#pragmaonce
#include"stdafx.h"
#include"Stack.h"
//方法的声明实现的分离写法容易报错,IDE还找不到错误的地方
//表达式求值
classCalculator{
private:
//Calculator'sstack,运算存储区
Stack<double>s;
//7个方法
public:
//建立一个空计算器栈
Calculator(void){}
//De建立一个空计算器栈
virtual~Calculator(){}
//将一个double型操作数压入堆栈
voidEnter(doubleoperand){
s.Push(operand);
}
//弹出2个操作数
voidGetTwoOperands(double&operand1,double&operand2){
if(s.IsEmpty()){
cerr<<"Nooperandtobepop!"<<endl;
s.Clear();
exit(1);
}
operand1=s.Pop();
if(s.IsEmpty){
cerr<<"Nooperandtobepop!"<<endl;
s.Clear();
exit(1);
}
operand2=s.Pop();
}
//操作符运算
voidCompute(charop){
doubleoperand1,operand2,result;
GetTwoOperands(operand1,operand2);
switch(op){
case'+':result=operand1+operand2;break;
case'-':result=operand1-operand2;break;
case'*':result=operand1*operand2;break;
case'/':if(operand2==0){
cerr<<"Dividedby0!"<<endl;
s.Clear();
exit(1);
}else
result=operand1/operand2;break;
default:
break;
}
s.Push(result);
}
//清空栈
voidClear(){
s.Clear();
}
//计算表达式的值
voidRun(){
charop;//操作符
doubleoperand;//操作数
cin>>op;//输入操作符
while(op!='='){
switch(op){
case'+':case'-':case'*':case'/':
Compute(op);break; //运算
default:cin.putback(op);//非操作符,回流
cin>>operand;//入操作数
Enter(operand);break;//入栈操作数
}
cin>>op;//输入操作符
}
cout<<s.Pop()<<endl;//最后出栈
Clear();//清空栈
}
};//!_classCalculator
㈡ 表达式求值 (栈的应用)前中后缀
表达式的分析与求值是编译原理课程中极其重要的部分,主要用于最初的词法分析。其表示方式有:前缀、中缀、后缀表示法。其数据结构可以使用一个堆栈来表示。具体的实现代码,我以前使用的书籍是《C语言大全》,那上面就有完整的代码,你可以参考。但是由于我已经很久没有编写编译原理方面的程序了,所以我也无法亲自给你编写一个完整表达式分析求值的程序。只能够给你提供一些思路和线索。
㈢ 栈的应用举例:数制转换,表达式求值
关于表达式的分析与求值是计算机软件专业中“编译原理”课程极其重要的部分,主要用于最初的词法分析。其表示方式有:前缀、中缀、后缀表示法。其数据结构可以使用一个堆栈来表示。具体的实现代码,我以前使用的书籍是《C语言大全》,那上面就有完整的、现成的代码,可以供你参考运行。同时你还可以参考《编译原理》相关的教材。
但是由于我已经很久没有编写编译原理方面的程序了,况且编写并亲自调试通过该程序,难度还是比较大的。所以我也无法亲自给你编写一个完整表达式分析与求值的程序。只能够给你提供一些思路和线索。
另外,关于不同数制之间的转换问题,这个倒是不难解决,可以采用通常的算法就是短除法,然后将每一次的余数采取“倒排”即可。例如:将十进制的 15 转换为二进制。
2|15(1
--
2|7(1
-
2|3(1
-
2|1(1
-
0
则十进制的 15 为二进制的:1111。
㈣ 编译原理 语义分析 算术表达式求值代码
利用乘法先运算的性质,把压入栈的乘法先运算最后再算加法就好了: #include #include #include using namespace std;const int MaxLen = 4096;char expr[MaxLen];int main(){stack num;cin.getline(expr, MaxLen);stringstream e(expr)
㈤ JAVA表达式求值
这个事情看似很简单,写起来很复杂!~建议你自己写,如果有什么疑问,大家一起探讨一下阿
㈥ 如何将数据结构和算法应用到实际之中
写一些程序,尤其是比较底层的程序。就明白它们的用处了。
列举下我们当初的作业(其实是老师从UC Santa Barbara\UC Berkley CS作业直接来题目)
(1)实现一个简单的 TCP 传输层的协议机制
自己去设计协议,不用照搬 RFC 的标准,其实就是数据结构的用场。
需要考虑到数据包丢失(Loss)、损坏(Corruption)、乱序(Disorder)这样的情况。
(2)实现操作系统的虚拟内存机制(基于Nachos系统)
如何去设计页表。如何使用置换算法。以及应用程序请求页的时候,发生缺页,从而导致的中断如何处理。
(3)实现一个简单的编译器(MiniJava)
词法:字符串匹配,表达式求值 等算法;
语法:生成抽象语法树;
语义:采用适当的设计模式(Visitor)来生成语义表、字典、然后转化为目标代码(可以是汇编、或者是类似的 Three-Address Code)
如果以上三个任务都完成并搞懂了,那么恭喜:你不仅掌握了数据结构、算法,而且也学习了计算机网络、操作系统、编译原理中大部分的知识。
㈦ 数据结构编译器表达式求值需求分析
要看你用什么软件了,在MATLAB 7.0中,直接输5-2*sin(3-sqrt(4))+6/4回车就出来答案了
㈧ 编译器的工作原理
编译 是从源代码(通常为高级语言)到能直接被计算机或虚拟机执行的目标代码(通常为低级语言或机器语言)的翻译过程。然而,也存在从低级语言到高级语言的编译器,这类编译器中用来从由高级语言生成的低级语言代码重新生成高级语言代码的又被叫做反编译器。也有从一种高级语言生成另一种高级语言的编译器,或者生成一种需要进一步处理的的中间代码的编译器(又叫级联)。
典型的编译器输出是由包含入口点的名字和地址, 以及外部调用(到不在这个目标文件中的函数调用)的机器代码所组成的目标文件。一组目标文件,不必是同一编译器产生,但使用的编译器必需采用同样的输出格式,可以链接在一起并生成可以由用户直接执行的EXE,
所以我们电脑上的文件都是经过编译后的文件。
㈨ 编译原理 while 语句文法
while(条件)
{
.......;//语句
X++或者X--;//做自增或自减运算来达到循环的过程
}
while后面跟一堆小括号,里面的条件判断,类似IF语句,当条件满足时做以下语句的循环,条件不满足后直接跳出循环;
例题:
int i=0;//初始化i=0
while(i<5)//i=0满足判断的条件,进入循环语句
{
i++;//做自增运算,当i+到5时跳出循环,因为i不小于5了
}
printf("%d",i);//此时i的值为5
㈩ 表达式求值
从算法来说,要考虑中缀的运算符优先级,括号等,可以使用简单语法制导翻译,去看编译原理书吧,从数据结构来说,可以使用二元树和栈。使用二元树就是先建立表达式的树,然后后根遍历即可。难点在建立树。
使用栈的算法也很多,说个好想的。假设表达式的字符来自输入流in,建立栈A存放运算符,B存放结果,从in读入一个操作数压进B,读入一个运算符压进A,如此反复。
1.读入一个元素e
2.如果e是操作数或者(,压入B,跳转到1
3.如果e是运算符(不包含括号),跳转到3.1
4.如果e是),跳转到4.1
5.如果e是EOF,即输入流结束,反复弹出A栈顶压入B,直到A为空,算法结束,B从栈底到栈顶的符号即为后缀表达式(需要把B翻个个儿^_^)
3.1.判断A的栈定符号t,如果t不为(,且优先级大于等于e,则弹出t压入B,跳转到4,如果t为空,即栈中为空,或其他情况直接把e压入A,跳转到1
4.1.弹出A的栈顶压入到B,如此反复直到弹出的符号为(,(和)不要压入B,跳转到1
这是我临时想的,可能还有bug,或描述不清的地方,如果上网搜的话应该有很多源代码的,如果学过编译原理的话还可以有更好的算法,这个算法没考虑容错性。