VB利用栈实现表达式求值
栈在表达式求值中的应用
栈在表达式求值中的应用
表达式求值是计算机科学中的一个经典问题,它涉及到了数学、算法和数据结构等多个领域。
在表达式求值中,栈是一种非常重要的数据结构,它可以帮助我们简化表达式计算的过程。
在表达式求值中,我们通常使用中缀表达式来表示计算式,例如:2+3*5。
中缀表达式的特点是运算符位于两个操作数之间,因此需要遵循一定的运算规则才能得出正确的结果。
为了方便计算机进行表达式求值,我们通常会将中缀表达式转换为后缀表达式。
后缀表达式也叫做逆波兰表达式,它的特点是运算符位于操作数的后面,从左到右逐个计算,不需要考虑运算符的优先级和括号的问题。
将中缀表达式转换为后缀表达式的过程中,我们需要借助栈来实现。
具体来说,我们从左到右遍历中缀表达式中的每个元素,遇到数字时直接输出,遇到运算符时则需要判断其优先级和栈顶运算符的优先级,如果当前运算符的优先级低于或等于栈顶运算符的优先级,则弹出栈顶运算符并输出,直到当前运算符的优先级高于栈顶运算符或栈为空时,将当前运算符入栈。
转换为后缀表达式后,我们可以再次使用栈来进行求值操作。
具体来说,我们从左到右遍历后缀表达式中的每个元素,遇到数字时压入栈中,遇到运算符时弹出栈顶的两个数字进行计算,并将结果压入栈中。
最终,栈中只剩下一个元素,即为表达式的计算结果。
综上所述,栈在表达式求值中的应用十分重要,它可以帮助我们
简化表达式计算的过程,提高计算效率。
因此,掌握栈的基本原理和应用方法是非常有必要的。
表达式求值(数据结构-栈的应用)
表达式求值(数据结构-栈的应⽤)⼀.问题描述:限制:只含有‘+’,‘-’,‘*’,‘/ ’和圆括号,正整数。
表⽰:字符数组,栈。
中缀表达式:在程序语⾔中,运算符位于两个运算数中间的表达式称为中缀表达式,例如 1+2*3.中缀表达式运算规则:先乘除,后加减,从左到右,先括号内,后括号外,因此中缀表达式不仅要判断运算符的优先级,⽽且还有处理括号。
后缀表达式:运算符在运算数的后⾯,如1+2*3的后缀表达式:1 2 3*,在后缀表达式中已经考虑了运算符的优先级,没有括号,只有运算数和运算符。
后缀表达式的运算:按照运算符的次序进⾏的。
例如123*+,从左到右扫描时,第⼀个运算符为*,先执⾏2*3=6,第⼆个运算符为‘+’,执⾏1+6=7。
⼆ .表达式求值的过程:将算术表达式转换成后缀表达式,然后对后缀表达式求值。
1.将算术表达式转换为后缀表达式。
(1)从左到右⼀次扫描中缀表达式的每⼀个字符,如果是字符串,直接写⼊后缀表达式。
(2)如果遇到的是' ( ',则压⼊操作符栈,遇到‘(’时,将栈中的元素放到后缀表达式中,直达栈顶元素为'('时,将栈顶元素'('删除,不需要⼊栈。
(3)如果遇到的是操作符,则将操作符和操作符栈顶元素⽐较。
:如果a[i]的运算符的优先级⼩于等于栈顶元素的优先级,退栈运算符并放到后缀表达式中,直到a[i]的运算符优先级⼤于栈顶运算符的优先级:否则⼊栈。
(4)重复上述步骤,知道中缀表达式的结束符标记“#”,转换结束。
我的代码:#include<bits/stdc++.h>using namespace std;stack<char>f;//操作符栈stack<double>s;//操作数栈bool flag;int prior(char ch)//运算符的优先级{switch(ch){case'+':case'-':return 1;case'*':case'%':case'/':return 2;default:return 0;//括号}}string trans(string a){while(!f.empty()) f.pop();f.push('#');string ret="";//保存中缀表达式int len=a.size(),i=0;while(i<len){if(a[i]==' '||a[i]=='=')//??{i++;continue;}else if(a[i]=='(')f.push(a[i++]);else if(a[i]==')'){while(f.top()!='('){ret+=f.top();ret+=' ';f.pop();}f.pop();//(出栈i++;}else if(a[i]=='+'||a[i]=='-'||a[i]=='*'||a[i]=='/'||a[i]=='%'){while(prior(f.top())>=prior(a[i]))//如果a[]的运算符的优先级⼩于等于栈顶元素的优先级,退栈运算符并放到后缀表达式中,直到a[i]的运算符优先级⼤于栈顶运算符的优先级ret+=f.top();ret+=' ';f.pop();}f.push(a[i++]);}else{while((a[i]>='0'&&a[i]<='9')||a[i]=='.'){ret+=a[i++];}ret+=' ';}}while(f.top()!='#'){ret+=f.top();ret+=' ';f.pop();}ret+='=';return ret;}double cal(double a,double b,double ch)//计算{if(ch=='+') return a+b;if(ch=='-') return a-b;if(ch=='*') return a*b;if(ch=='%') return ((int)a%(int)b);if(ch=='/'){if(b!=0)return a/b;flag=true;return 0;}}double solve(string a)//后缀表达式计算{string t=trans(a);while(!s.empty()) s.pop();flag=false;int len=t.length(),i=0;while(i<len){if(t[i]==' '||t[i]=='='){i++;continue;}else if(t[i]=='+'||t[i]=='-'||t[i]=='*'||t[i]=='/'||t[i]=='%') {double num1,num2;num1=s.top();s.pop();num2=s.top();s.pop();s.push(cal(num1,num2,t[i]));i++;}else{double x=0;while(t[i]>='0'&&t[i]<='9'){x=x*10+t[i]-'0';i++;}if(t[i]=='.'){double k=10.0,y=0;i++;while(t[i]>='0'&&t[i]<='9'){y+=((t[i]-'0')/k);i++;k*=10;;}x+=y;}s.push(x);}}return s.top();}int main(){int num;scanf("%d",&num);while(num--){cin>>a;// cout<<e.trans(a)<<endl;//将中缀表达式装换为后缀表达式 cout<<solve(a)<<endl;}return 0;}。
VB程序设计的常用算法
Loop Print "e="; e End Sub Private Sub Command2_Click() Dim e#, t#, n% e = 1: t = 1: n = 1 Do Until (1 / t) < 0.00000001 t=t*n e=e+1/t n=n+1 Loop Print "e="; e End Sub Private Sub Command3_Click() Dim e#, t#, n% e = 1: t = 1: n = 1 While (1 / t) > 0.00000001 t=t*n e=e+1/t n=n+1 Wend Print "e="; e End Sub 3、
abc: Next i End Sub
补充实例:验证哥德巴赫猜想 (任意一个大于等于6的偶数都可以分解为两个素数之和)
基本思想:n为大于等于6的任一偶数,可分解为n1和n2两个数, 分别检查n1和n2是否为素数,如都是,则为一组解。如n1不是素数,就 不必再检查n2是否素数。先从n1=3开始,检验n1和n2(n2=N-n1)是否 素数。然后使n1+2 再检验n1、n2是否素数,… 直到n1=n/2为止。 利用上面的prime函数,验证哥德巴赫猜想的程序代码如下: Dim n%,n1%,n2% n=Val(InputBox("输入大于6的正整数")) For n1=3 to n\2 step 2 n2=n-n1 If prime(n1) Then If prime(n2) then Print n & "=" & n1 & "+" & n2 Exit For '结束循环 End if End if Next n1
《软件设计基础(VB)》课程设计报告书-简单的四则表达式计算程序
2.课程设计任务与要求: .课程设计任务与要求:
要求: 本次课程设计利用《软件设计基础(VB) 》课程中所学到的编程知识和编程技巧,完成具有一定 难度和工作量的程序设计题目,帮助学生掌握编程、调试的基本技能,独立完成所布置的任务。 1.要求: (1) (2) (3) (4) (5) (6) (7) (8) 对系统进行功能需求分析 设计合理的数据结构和系统框架 界面设计美观、清楚、合理 编程简练,程序功能齐全,能正确运行 具有一定的创新性 说明书、流程图要清楚 课题完成后必须按要求提交课程设计报告 任务:
各功能模块流程图: 1. 判断数据和计算式
若除数为 如果是非法 0,则“错 数据,退出 误”
是否有 括号及 负数的 判断
如果不是十进制 将其转化为十进 制再计算
2. 各进制间的转换 . 3. 计算四则运算 ⑷代码实现 本设计共用一个窗体 form1,一个标签 label1,二个文本框 text1.text2,一个命令按钮 command1. Text1 用来输入算式,Text2 用来显示计算结果,command1 用来实现代码的功能,label1 用来标 注计算结果的位置。 设计思路:.1.整个算式当作字符串来处理,在具体计算时化为数值,结果再转为字符串 2.不断地用计算结果替换原单项计算式,例如用“21”替换“3 * 7” 详细内容: 循环过程计算 结果 如果不是十进制将 其转化为十进制再 计算
《软件设计基础(VB) 》课程设计报告
nSt = operate(nSt, "-") Loop analyze = nSt End Function
第
8
页erate(S As String, sign As String) As String '完成一次运算 Dim k1 As Integer, k2 As Integer, S1 As String, S2 As String, z As String, n As String, i As Integer i = InStr(2, S, sign) '获得运算符位置
用栈的方式实现表达式求值
一、程序设计任务掌握栈的用法,实现表达式求值这一栈的典型应用问题:以字符序列的形式从终端输入语法正确的、不含变量的算术表达式,利用算符优先关系,实现对算术四则混合运算表达式求值。
当用户输入一个合法的表达式后,能够返回正确的结果。
能够计算的运算符包括:加、减、乘、除、括号。
二、具体代码实现如下#include<iostream.h>#include<fstream.h>#include<string.h>#include<stdlib.h>#include<math.h>#include<cstdio> //cstdio本来就只是将stdio.h的内容用C++的头文件形式表现出来。
#define NULL 0typedef struct node //定义一个结点结构体{char date;struct node *next;}SNode;SNode *InitStack()//初始化空链栈{SNode *top;top=new SNode;//top=(SNode *)malloc(sizeof(SNode));top->next=NULL;return top;}void PushOptr(SNode *top,char x)//运算符进栈函数{SNode *p;p=new SNode;p->date=x;p->next=top->next;top->next=p;}char PopOptr(SNode *top)//运算符出栈函数{SNode *p;char x;if(top==NULL)return NULL;p=top->next;x=p->date;top->next=p->next;delete p;return x;}void PushOpnd(SNode *top,char x)//操作数进栈函数{SNode *p;p=new SNode;p->date=x;p->next=top->next;top->next=p;}char PopOpnd(SNode *top)//操作数出栈函数{SNode *p;char x;if(top==NULL)return NULL;p=top->next;x=p->date;top->next=p->next;delete p;return x;}char GetTop(SNode *top)//取栈顶元素{return (top->next)->date;}int In(char c){int n;switch(c){case '+':case '-':case '*':case '/':case '(':case ')':case '%':case '^':case '#': n=1;break;default : n=0;break;}return n;}char Precede(char x,char y) //符号优先级规则说明{int i,j;int form[9][9]={{1,1,-1,-1,-1,1,-1,-1,1},{1,1,-1,-1,-1,1,-1,-1,1},{1,1,1,1,-1,1,1,-1,1},{1,1,1,1,-1,1,1,-1,1},{-1,-1,-1,-1,-1,0,-1,-1,2},{1,1,1,1,2,1,1,1,1},{1,1,1,1,-1,1,1,-1,1},{1,1,1,1,-1,1,1,1,1},{-1,-1,-1,-1,-1,2,-1,-1,0}}; //定义一个二维数组存放运算符优先级switch(x){case '+':i=0;break;case '-':i=1;break;case '*':i=2;break;case '/':i=3;break;case '(':i=4;break;case ')':i=5;break;case '%':i=6;break;case '^':i=7;break;case '#':i=8;break;}switch(y){case '+':j=0;break;case '-':j=1;break;case '*':j=2;break;case '/':j=3;break;case '(':j=4;break;case ')':j=5;break;case '%':j=6;break;case '^':j=7;break;case '#':j=8;break;}if(form[i][j]==1) //当form[i][j]==1时,说明运算符i的优先级高于运算符jreturn '>';elseif(form[i][j]==-1) //当form[i][j]==-1时,说明运算符i的优先级低于运算符jreturn '<';else //当form[i][j]等于其他值时,说明运算符i的优先级等于运算符jreturn '=';}int Operate(char x,char z,char y)//操作函数{int a=x-'0',b=y-'0';switch(z){case '+':return a+b;case '-':return a-b;case '*':return a*b;case '/':return a/b;case '%':return a%b;case '^': for(int i=1;i<b;i++) a*=a; return a;// cout<<pow(a,b);}}char Eval_Exp(char t[]) //获取运算结果{char temp[30];strcpy(temp,t);strcat(temp,"#");char a,b,c,r,f,z;int result,i=0;SNode *top[2];top[0]=InitStack(); //top[0]指向栈顶PushOptr(top[0],'#'); //将‘#’进入空运算符栈top[1]=InitStack();c=temp[i];while(c!='#'||(GetTop(top[0]))!='#')//输入符号不为‘#’或者栈顶元素不为‘#’时执行while语句{if(!In(c)) //如果当前输入不为运算符时执行if语句{PushOpnd(top[1],c); //将输入的元素放入操作数栈中c=temp[++i];}else{r=Precede(GetTop(top[0]),c); //获取符号优先级比较结果switch(r){case '<':PushOptr(top[0],c); //将当前输入的运算符进运算符栈中c=temp[++i];break;case '=':PopOptr(top[0]); //出当前运算符栈中的栈顶元素c=temp[++i];break;case '>':b=PopOptr(top[0]); //出当前运算符栈中的栈顶元素a=PopOpnd(top[1]); //出当前操作数栈中栈顶元素z=PopOpnd(top[1]); //出当前操作数栈中栈顶元素result=Operate(z,b,a); //计算结果f=result+'0';PushOpnd(top[1],f); //将运算结果进操作数栈中break;}}}return f; //返回运算结果}void main(){char infilename[40],outfilename[40],ch[30];fstream infile;fstream outfile;cout<<"请输入操作文件名路径: ";cin>>infilename;infile.open(infilename,ios::in|ios::nocreate);if(!infile){cout<<"不能打开文件:"<<infilename<<endl;exit(1);}cout<<"请输入结果文件名路径: ";cin>>outfilename;outfile.open(outfilename,ios::out);if(!outfile){cout<<"不能打开文件:"<<outfilename<<endl;exit(2);}while(infile.getline(ch,80))outfile<<Eval_Exp(ch)-'0'<<endl;infile.close();outfile.close();}三、运行输出结果实例输入表达式实例:2+5*(6-2)/2运行结果如下:。
利用栈来实现算术表达式求值的算法
利用栈来实现算术表达式求值的算法利用栈来实现算术表达式求值的算法算术表达式是指按照一定规则组成的运算式,包含数字、运算符和括号。
在计算机中,求解算术表达式是一项基本的数学运算任务。
根据算术表达式的性质,我们可以考虑利用栈这一数据结构来实现求值算法。
一、算法思路首先,我们需要明确一个重要概念——逆波兰表达式(ReversePolish notation)。
逆波兰表达式是一种没有括号的算术表达式,其运算规则是先计算后面的数字和运算符,再计算前面的数字和运算符。
例如,对于算术表达式“3+4*5-6”,其对应的逆波兰表达式为“3 45 * +6 -”。
那么,我们可以利用栈来实现将中缀表达式转化为逆波兰表达式的过程,具体步骤如下:1. 创建两个栈——操作数栈和操作符栈。
2. 从左到右扫描中缀表达式的每一个数字和运算符,遇到数字则压入操作数栈中,遇到运算符则进行如下操作:(1)如果操作符栈为空或当前运算符的优先级大于栈顶运算符的优先级,则将当前运算符压入操作符栈中。
(2)如果当前运算符的优先级小于或等于栈顶运算符的优先级,则将栈顶运算符弹出并加入操作数栈中,重复此过程直到遇到优先级较低的运算符或操作符栈为空为止,然后将当前运算符压入操作符栈中。
3. 扫描完中缀表达式后,若操作符栈不为空,则将其中所有运算符弹出并加入操作数栈中。
4. 最终,操作数栈中存放的就是逆波兰表达式,我们可以按照逆波兰表达式的计算规则来计算其结果。
二、算法优点利用栈来实现算术表达式求值的算法具有以下优点:1. 代码简洁易懂,易于实现和维护。
2. 由于将中缀表达式转化为逆波兰表达式后,可以减少运算符的优先级关系而消除括号,从而减少求值的复杂度,提高程序的执行效率。
三、代码实现下面是利用栈来实现算术表达式求值的算法的Python代码实现:```pythonclass Stack:def __init__(self):self.items = []def push(self, item):self.items.append(item)def pop(self):return self.items.pop()def peek(self):return self.items[-1]def is_empty(self):return len(self.items) == 0def size(self):return len(self.items)def calculate(op_num1, op_num2, operator):if operator == "+":return op_num1 + op_num2elif operator == "-":return op_num1 - op_num2elif operator == "*":return op_num1 * op_num2elif operator == "/":return op_num1 / op_num2def infix_to_postfix(infix_expr):opstack = Stack()postfix_expr = []prec = {"+": 1, "-": 1, "*": 2, "/": 2, "(": 0} token_list = infix_expr.split()for token in token_list:if token.isdigit():postfix_expr.append(token)elif token == '(':opstack.push(token)elif token == ')':top_token = opstack.pop()while top_token != '(':postfix_expr.append(top_token)top_token = opstack.pop()else:while (not opstack.is_empty()) and(prec[opstack.peek()] >= prec[token]):postfix_expr.append(opstack.pop())opstack.push(token)while not opstack.is_empty():postfix_expr.append(opstack.pop())return " ".join(postfix_expr)def postfix_eval(postfix_expr):opstack = Stack()token_list = postfix_expr.split()for token in token_list:if token.isdigit():opstack.push(int(token))else:op_num2 = opstack.pop()op_num1 = opstack.pop()result = calculate(op_num1, op_num2, token) opstack.push(result)return opstack.pop()infix_expr = "3 + 4 * 5 - 6"postfix_expr = infix_to_postfix(infix_expr)print(postfix_expr)print(postfix_eval(postfix_expr))```四、总结算术表达式求值是一项常见的数学运算任务,利用栈这一数据结构来实现求值算法是一种简单有效的方法,它将中缀表达式转化为逆波兰表达式后,可以消除括号并减少运算符的优先级关系,从而提高程序的执行效率。
vb编写计算公式(一)
vb编写计算公式(一)VB编写计算公式作为一名资深的创作者,你可能会在VB编程中经常使用计算公式来进行数据处理和分析。
本篇文章将列举一些常见的计算公式,并给出相应的解释和示例说明。
1. 数值计算公式基本运算符使用基本运算符来进行数值计算是VB编程中最常见的操作之一。
•加法:使用符号+进行两个数值的相加。
例如,计算两个数的和:result = num1 + num2•减法:使用符号-进行两个数值的相减。
例如,计算两个数的差:result = num1 - num2•乘法:使用符号*进行两个数值的相乘。
例如,计算两个数的乘积:result = num1 * num2•除法:使用符号/进行两个数值的相除。
例如,计算两个数的商:result = num1 / num2平方与开方在某些情况下,我们需要进行数值的平方和开方运算。
•平方:使用`方法对一个数值进行平方运算。
例如,计算一个数的平方:result = (num, 2)`•开方:使用`方法对一个数值进行开方运算。
例如,计算一个数的平方根:result = (num)`取整与四舍五入有时候我们需要对数值进行取整或进行四舍五入操作。
•取整:使用`方法将一个数值向下取整。
例如,将一个浮点数向下取整为整数:result = (num)`•四舍五入:使用`方法将一个数值进行四舍五入。
例如,将一个浮点数四舍五入为指定的小数位数:result = (num,decimalDigits)`2. 统计计算公式平均值在统计分析中,计算一组数据的平均值是常见的需求之一。
•算术平均值:对一组数据进行求和,然后除以数据个数即可得到算术平均值。
例如,计算一组数的算术平均值:result = sum / count•加权平均值:对一组有权重的数据进行求和,然后除以权重之和即可得到加权平均值。
例如,计算一组有权重的数据的加权平均值:result = sumOfData / sumOfWeights方差与标准差方差和标准差常用于描述一组数据的离散程度。
VB常用简单算法
VB常用简单算法VB是一种过程式编程语言,被广泛用于Windows平台的软件开发。
它提供了一系列的算法和数据结构可以用于解决复杂的问题。
下面是一些VB常用的简单算法:1. 顺序(Sequential Search):顺序是一种简单的算法,它检查数组中的每个元素,直到找到目标元素或完整个数组。
该算法的时间复杂度为O(n)。
```vbFunction SequentialSearch(arr( As Integer, target As Integer) As IntegerDim i As IntegerFor i = 0 To UBound(arr)If arr(i) = target ThenReturn iEnd IfNextReturn -1 '表示未找到End Function```2. 二分(Binary Search):二分是一种高效的算法,它将目标元素与数组的中间元素比较,根据比较结果确定目标元素在数组的左半部分还是右半部分,并重复这个过程,直到找到目标元素或范围缩小到空集。
该算法要求数组必须是有序的,并且时间复杂度为O(log n)。
```vbFunction BinarySearch(arr( As Integer, target As Integer) As IntegerDim low As Integer = 0Dim high As Integer = UBound(arr)While low <= highDim mid As Integer = (low + high) \ 2If arr(mid) = target ThenReturn midElseIf arr(mid) < target Thenlow = mid + 1Elsehigh = mid - 1End IfEnd WhileReturn -1 '表示未找到End Function```3. 冒泡排序(Bubble Sort):冒泡排序是一种简单的排序算法,它重复地比较相邻的元素并交换顺序,直到整个数组按照升序或降序排列。
vb6 数据结构
VB6 数据结构1. 引言在计算机科学中,数据结构是指组织和存储数据的方式。
数据结构能够有效地管理数据,提高程序的运行效率和性能。
VB6(Visual Basic 6)是一种面向对象的编程语言,它提供了丰富的数据结构来帮助开发人员处理和操作数据。
本文将介绍VB6中常用的数据结构,包括数组、链表、栈和队列,并对它们的特点和应用进行详细讨论。
2. 数组数组是一种线性数据结构,它由一系列相同类型的元素组成,这些元素被存储在连续的内存空间中。
在VB6中,数组可以是一维或多维的。
数组的大小在声明时确定,并且在程序运行过程中不能改变。
2.1 一维数组一维数组是最简单的数组形式,它由一个索引和一组值组成。
在VB6中,可以使用Dim语句声明和初始化一维数组。
例如:Dim numbers(10) As Integer上述代码创建了一个包含11个整数的一维数组,索引从0到10。
可以通过索引来访问数组中的元素,例如numbers(0)表示数组的第一个元素。
2.2 多维数组多维数组是一种包含多个索引的数组形式。
在VB6中,可以使用Dim语句声明和初始化多维数组。
例如:Dim matrix(3, 3) As Integer上述代码创建了一个4x4的整数矩阵,可以通过两个索引来访问数组中的元素,例如matrix(0, 0)表示矩阵的左上角元素。
2.3 数组的应用数组在VB6中被广泛应用于各种场景,例如存储和处理大量数据、实现排序和搜索算法等。
通过灵活运用数组,可以提高程序的性能和效率。
3. 链表链表是一种非连续的数据结构,它由一系列节点组成,每个节点包含数据和一个指向下一个节点的指针。
在VB6中,可以使用自定义类型和类模块来实现链表。
3.1 单向链表单向链表是最简单的链表形式,它的每个节点只包含一个指向下一个节点的指针。
在VB6中,可以使用自定义类型来定义单向链表的节点。
例如:Type NodeData As IntegerNextNode As NodeEnd Type上述代码定义了一个包含整数数据和指向下一个节点的指针的节点类型。
用栈解决表达式求值问题的c语言代码
栈是一种常见的数据结构,用于解决许多算法和数据处理问题。
在编程中,栈通常用于处理表达式求值问题。
本篇文章将介绍如何使用栈解决表达式求值问题,并给出对应的C语言代码。
1. 表达式求值问题介绍表达式求值是指计算一个数学表达式的值,通常涉及到四则运算、括号和优先级等概念。
给定一个表达式“3 + 4 * 2”,我们需要得到其计算结果为11。
在编程中,需要将该表达式转换为计算机可识别的形式,并使用算法进行求值。
2. 中缀表达式、前缀表达式和后缀表达式在计算机中常见的表达式有三种形式:中缀表达式、前缀表达式和后缀表达式。
其中,中缀表达式是通常人们在日常生活中使用的表达式形式,如“3 + 4 * 2”。
前缀表达式是运算符位于操作数之前的形式,例如“+ 3 * 4 2”。
后缀表达式则是运算符位于操作数之后的形式,例如“3 4 2 * +”。
3. 使用栈解决表达式求值问题在解决表达式求值问题时,我们可以利用栈的特性来简化计算过程。
具体步骤如下:3.1 将中缀表达式转换为后缀表达式我们需要将中缀表达式转换为后缀表达式,这样可以简化表达式的计算顺序。
具体转换规则如下:- 从左至右扫描中缀表达式的每个数字或符号。
- 如果是操作数,则直接输出。
- 如果是运算符,则弹出栈中所有优先级大于或等于该运算符的运算符,并将其压入栈中,然后压入该运算符。
- 如果是括号,则根据括号的不同情况进行处理。
通过以上规则,我们可以将中缀表达式转换为后缀表达式。
3.2 计算后缀表达式的值得到后缀表达式后,我们可以利用栈来计算其值。
具体步骤如下:- 从左至右扫描后缀表达式的每个数字或符号。
- 如果是操作数,则压入栈中。
- 如果是运算符,则弹出栈中的两个操作数进行相应的运算,并将结果压入栈中。
- 继续扫描直到表达式结束,栈中的值即为所求结果。
通过以上步骤,我们可以使用栈来解决表达式求值问题。
4. C语言代码实现以下是使用C语言实现栈来解决表达式求值问题的代码示例:```c#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct {int top;int capacity;int* array;} Stack;Stack* createStack(int capacity) {Stack* stack = (Stack*)malloc(sizeof(Stack));stack->capacity = capacity;stack->top = -1;stack->array = (int*)malloc(stack->capacity * sizeof(int)); return stack;}int isFull(Stack* stack) {return stack->top == stack->capacity - 1; }int isEmpty(Stack* stack) {return stack->top == -1;}void push(Stack* stack, int item) {if (isFull(stack)) return;stack->array[++stack->top] = item;}int pop(Stack* stack) {if (isEmpty(stack)) return -1;return stack->array[stack->top--];}int evaluatePostfix(char* exp) {Stack* stack = createStack(strlen(exp)); for (int i = 0; exp[i]; i++) {if (isdigit(exp[i])) {push(stack, exp[i] - '0');} else {int val1 = pop(stack);int val2 = pop(stack);switch (exp[i]) {case '+':push(stack, val2 + val1); break;case '-':push(stack, val2 - val1); break;case '*':push(stack, val2 * val1); break;case '/':push(stack, val2 / val1); break;}}}return pop(stack);}int m本人n() {char exp[] = "34*2+";printf("The value of s is d\n", exp, evaluatePostfix(exp));return 0;}```以上代码实现了栈的基本功能,并利用栈来计算后缀表达式的值。
利用栈求表达式值
课程设计课程名称数据结构题目名称利用栈求表达式的值专业班级2014级计算机科学与技术本学生姓名刘志,马健,王青星,杨文祥,王胜达学号51402011052,5140201104 2,51402011032,51402011 006,51402011046指导教师姚保峰二○一六年六月十五日目录1.设计目的: (1)2.设计要求: (2)3.设计方案: (3)4.设计内容: (4)4.1.需求分析 (4)4.2.概要设计 (4)4.3.详细设计 (7)4.4.调试分析与结果 (11)4.5:使用说明 (15)5.总结: (16)6.附录三:源代码 (18)1.设计目的:数据结构课程设计是计算机专业集中实践性环节之一,是学习完《数据结构》课程后进行的一次全面的综合练习。
其目的是:(1)要达到理论与实际应用相结合,使学生能够根据数据对象的特性,学会数据组织的方法,能把现实世界中的实际问题在计算机内部表示出来,并培养良好的程序设计技能。
(2)在实践中认识为什么要学习数据结构,掌握数据结构、程序设计语言、程序设计技术之间的关系,是前面所学知识的综合和回顾。
2.设计要求:以字符序列的形式从键盘输入语法正确的、不含变量的整数(或实数)表达式,实现对算术四则混合运算表达式的求值。
当用户输入一个合法的算术表达式后,能够返回正确的结果。
能够计算的运算符包括:加、减、乘、除、括号,对于异常表达式能给出错误提示。
3.设计方案:任何一个表达式都是由操作符,运算符组成的。
我们分别用顺序栈来寄存表达式的操作数和运算符。
栈是限定于紧仅在表尾进行插入或删除操作的线性表。
顺序栈的存储结构是利用一组连续的存储单元依次存放自栈底到栈顶的数据元素。
为了实现运算符优先算法。
可以使用两个栈。
一个称为OPF,用以寄存运算符,另一个称做OPS,用以寄存操作数或运算结果。
1.首先置操作数栈为空栈,表达式起始符”#”为运算符栈的栈底元素;2.依次读入表达式,若是操作符即进OPS栈,若是运算符则和OPF栈的栈顶运算符比较优先权后作相应的操作,直至整个表达式求值完毕(即OPF栈的栈顶元素和当前读入的字符均为”#”)。
利用栈进行表达式求值
myStack.top = myStack.base + myStack.stacksize;
myStack.stacksize += STACKINCREMENT;
#include "Stdafx.h"
#include <stdio.h>
#include <malloc.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef struct {
int *base;
int *top;
int stacksize;
if(isNum(c)) {
push(opnd, ((int)c-48));
c = getchar();
} else {
switch(precede((char)getTop(oprt), c)) {
case '<' : push(oprt, c); c = getchar(); break;
case '=' : pop(oprt, t); c = getchar(); break;
default : return '>';
} break;
case '(' :
switch (c2) {
case ')' : return '='; break;
VB常用算法总结大全
时间复杂度:最好情况下为O(nlogn),最坏情况 下为O(n^2),平均情况下为O(nlogn)。
稳定性:不稳定。
02 查找算法
顺序查找
原理
01
从数据结构的一端开始,顺序扫描,直到找到所查元素为止。
时间复杂度
02
平均时间复杂度和最坏时间复杂度都是O(n),其中n是数据结构
中元素的个数。
适用场景
队列操作
实现入队(enqueue)、出队(dequeue)、 查看队首和队尾元素等基本操作。
3
应用举例
使用栈实现括号匹配检查、表达式求值等;使用 队列实现广度优先搜索(BFS)等算法。
06 文件操作与I/O流处理 算法
文件读写操作
顺序文件读写
使用Open、Input、Output、 Close等语句,按照文件内容的顺 序进行读写操作。
矩阵运算
矩阵加法
将两个矩阵对应元素相加得到新的矩阵。
矩阵乘法
按照矩阵乘法的规则,将两个矩阵相乘得到新的矩阵。
矩阵转置
将矩阵的行和列互换得到新的矩阵。
矩阵求逆
对于可逆矩阵,求解其逆矩阵。
线性方程组求解
高斯消元法
通过消元将线性方程组化为上三角或下三角形式,然后回代求解 。
LU分解法
将系数矩阵分解为一个下三角矩阵和一个上三角矩阵的乘积,然 后分别求解。
链表创建
链表遍历
通过动态分配内存空间,创建链表节点并 连接起来形成链表。
从头节点开始,依次访问链表中的每个节 点。
链表插入
在链表的指定位置插入一个新的节点。
链表删除
删除链表中的指定节点或一系列节点。
栈和队列操作及应用举例
1 2
利用栈求表达式的值
题目:利用栈求表达式的值一.设计任务和目标编写程序实现表达式求值,即验证某算术表达式的正确性,若正确,则计算该算术表达式的值。
主要功能描述如下:1、从键盘上输入表达式。
2、分析该表达式是否合法:(1)是数字,则判断该数字的合法性。
若合法,则压入数据到堆栈中。
(2)是规定的运算符,则根据规则进行处理。
在处理过程中,将计算该表达式的值。
(3)若是其它字符,则返回错误信息。
主要功能描述如下:1、从键盘上输入表达式。
2、分析该表达式是否合法:(1)是数字,则判断该数字的合法性。
若合法,则压入数据到堆栈中。
(2)是规定的运算符,则根据规则进行处理。
在处理过程中,将计算该表达式的值。
(3)若是其它字符,则返回错误信息。
程序应包括以下几个功能函数voidinitstack();初始化堆栈intMake_str();语法检查并计算intpush_operate(intoperate):将操作码压入堆栈intpush_num(doublenum):将操作数压入堆栈intprocede(intoperate):处理操作码intchange_opnd(intoperate):将字符型操作码转换成优先级intpush_opnd(intoperate):将操作码压入堆栈intpop_opnd();将操作码弹出堆栈intcaculate(interru_opnd):简单计算+,-,*,/doublepop_num():弹出操作数程序如下:#include"stdio.h"#include"string.h"#include"stdlib.h"#defineMAXLEN100typedefstruct{charop;intlevel;}opt;optst[MAXLEN];inttop;}op_stack;typedefstruct//定义值栈{doubleD[MAXLEN];inttop;}D_stack;//--------对栈操作的定义-------------optpeek(op_stack*s)//定义看栈顶函数{opterror=;if(s->top>=0)returns->st[s->top];elsereturnerror;}intIsEmpty(op_stack*s)//定义判断栈空的函数{if(s->top<0)return0;elsereturns->st[s->top].op;}charpush(op_stack*s,optc)//定义入栈函数{s->top++;s->st[s->top]=c;returnc.op;}optpop(op_stack*s)//定义出栈函数{opti;opterror=;if(s->top>=0){i=s->st[s->top];s->st[s->top].op='\0';s->top--;returni;}else}voidclear(op_stack*s)//定义初始化栈{s->top=-1;}//-----------------------------definethevaluestack----------------------- doubleDpeek(D_stack*s)//定义看栈顶函数{if(s->top>=0)returns->D[s->top];elsereturn0;}intDIsEmpty(D_stack*s)//定义判断栈空的函数{if(s->top<0)return0;elsereturn(int)(s->D[s->top]);}doubleDpush(D_stack*s,doublec)//定义入栈函数{s->top++;s->D[s->top]=c;returnc;}doubleDpop(D_stack*s)//定义出栈函数{doublei;if(s->top>=0){i=s->D[s->top];s->D[s->top]='\0';s->top--;returni;}elsereturn0;}voidDclear(D_stack*s)//定义初始化栈{s->top=-1;}doublecalval(char*exp){op_stackos;//定义两个栈D_stackds;chartmp[MAXLEN]=;inti=0,leng;doubledtmp,dpoptmp;optA=;optR=;optM=;optD=;optB=;optMo=;clear(&os);Dclear(&ds);//-----定义初始化结束-----while(*exp!='\0'){while(*exp>='0'&&*exp<='9'||*exp=='.') {while(*exp>='0'&&*exp<='9'||*exp=='.') {tmp[i++]=*exp++;}dtmp=atof(tmp);Dpush(&ds,dtmp);leng=strlen(tmp);for(i=0;i<leng;i++){tmp[i]='\0';}i=0;}//-------------------------------switch(*exp){case'+':if(!IsEmpty(&os)||peek(&os).level<A.level) {push(&os,A);*exp++;else{while(IsEmpty(&os)&&peek(&os).level>=A.level) {switch(pop(&os).op){case'%':dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp); Dpush(&ds,dpoptmp);break;case'*':dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case'/':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;case'+':dpoptmp=Dpop(&ds)+Dpop(&ds);Dpush(&ds,dpoptmp);break;case'-':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)-dpoptmp;Dpush(&ds,dpoptmp);break;}}push(&os,A);*exp++;}break;case'-':if(!IsEmpty(&os)||peek(&os).level<R.level){push(&os,R);*exp++;}else{while(IsEmpty(&os)&&peek(&os).level>=R.level) {switch(pop(&os).op)case'%':dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp); Dpush(&ds,dpoptmp);break;case'*':dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case'/':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;case'+':dpoptmp=Dpop(&ds)+Dpop(&ds);Dpush(&ds,dpoptmp);break;case'-':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)-dpoptmp;Dpush(&ds,dpoptmp);break;}}push(&os,R);*exp++;}break;case'*':if(!IsEmpty(&os)||peek(&os).level<M.level){push(&os,M);*exp++;}else{while(IsEmpty(&os)&&peek(&os).level>=M.level) {switch(pop(&os).op){case'%':dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp); Dpush(&ds,dpoptmp);case'*':dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case'/':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;}}push(&os,M);*exp++;}break;case'/':if(!IsEmpty(&os)||peek(&os).level<D.level){push(&os,D);*exp++;}else{while(IsEmpty(&os)&&peek(&os).level>=D.level) {switch(pop(&os).op){case'%':dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp); Dpush(&ds,dpoptmp);break;case'*':dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case'/':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;}}push(&os,D);*exp++;}if(!IsEmpty(&os)||peek(&os).level<Mo.level){push(&os,Mo);*exp++;}else{while(IsEmpty(&os)&&peek(&os).level>=Mo.level) {switch(pop(&os).op){case'%':dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp); Dpush(&ds,dpoptmp);break;case'*':dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case'/':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;}}push(&os,Mo);*exp++;}break;case'(':push(&os,B);exp++;break;case')':while(peek(&os).level!=-2){switch(pop(&os).op){case'%':dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp); Dpush(&ds,dpoptmp);break;dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case'/':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;case'+':dpoptmp=Dpop(&ds)+Dpop(&ds);Dpush(&ds,dpoptmp);break;case'-':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)-dpoptmp;Dpush(&ds,dpoptmp);break;}}pop(&os);//弹出(exp++;break;}}while(IsEmpty(&os)){switch(pop(&os).op){case'%':dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp); Dpush(&ds,dpoptmp);break;case'*':dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case'/':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;case'+':dpoptmp=Dpop(&ds)+Dpop(&ds);Dpush(&ds,dpoptmp);dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)-dpoptmp; Dpush(&ds,dpoptmp);break;}}returnDpop(&ds);}voidmain(){charstring[MAXLEN];char*p=string;printf("输入表达式:\n");gets(p);printf("%s=%f\n\n",string,calval(p));。
栈的应用—算术表达式求值
栈的应⽤—算术表达式求值例三、算术表达式求值1、问题描述当⼀个算术表达式中含有多个运算符,且运算符的优先级不同的情况下,如何才能处理⼀个算术表达式2、思路⾸先我们要知道表达式分为三类:①中缀表达式:a+(b-c/d)*e②前缀表达式+a*-be③后缀表达式abcd/-e*+由于运算符有优先级,所以在计算机中计算⼀个中缀的表达式⾮常困难,特别是带括号的更⿇烦,⽽后缀表达式中既⽆运算符优先⼜⽆括号的约束问题因为在后缀表达式中运算符出现的顺序正是计算的顺序,所以计算⼀个后缀的表达式更简单。
所以,可以将求算术表达式的值的过程化成两个过程:1.将⼀个中缀表达式化成⼀个后缀表达式2.对后缀表达式进⾏求值⼀、将中缀变成⼀个后缀因为要将运算符出现的次序与真正的算术运算顺序⼀直,所以,就要让优先级⾼的以及括号内的运算符出现在前⾯,因此要使⽤⼀个栈来保留还未送往后缀表达式的运算符,此栈称为运算符栈算法描述如下:(1)初始化⼀个运算符栈(2)从算术表达式输⼊的字符串中,从左到右的读取⼀个字符(3)若当前的字符是操作数,则直接送往后缀表达式(4)若当前的字符是左括号,则将其压⼊运算符栈(5)若当前的字符是操作符,则进⾏如下操作:①当运算符栈为空时,直接将其压⼊栈。
②当此运算符的优先级⾼于栈顶的运算符时,则将此运算符压⼊栈,否则,弹出栈顶运算符送往后缀式,并将当前运算符压栈,重复步骤(5)(6)若当前字符是右括号,反复将栈顶符号弹出,并送往后缀表达式中,知道栈顶元素为左括号为⽌,然后将左括号出栈并丢弃(7)若读取还未结束,则重复步骤(2)(8)若读取结束,则将栈中剩余的所有的运算符弹出并送往后缀表达式⼆、计算后缀表达式的值计算步骤很简单,就是找到运算符,然后找前⾯最后出现的两个操作数,从⽽构成⼀个最⼩的算术表达式进⾏运算,在计算过程中也需要利⽤⼀个栈来保留后缀表达式中还未参与运算的操作数,称为操作数栈,算法描述如下:(1)初始化⼀个操作数栈(2)从左到右依次读⼊后缀表达式中的字符①若当前字符是操作数,则压⼊操作数栈。
VB利用栈实现表达式求值
实验一Dim s(100) As String, t As IntegerPrivate Sub Command2_Click()Dim x As String, n, i As IntegerText3.Text = " "For i = t To 1 Step -1pop x, s(), tText3.Text = Text3.Text & xNext iEnd SubPrivate Sub Command1_Click()Dim a, b, x As String, n, i, m As IntegerText2.Text = ""a = Text1.Textn = Len(a)m = 10t = 0For i = 1 To nx = Mid(a, i, 1)PUSH x, s(), m, tText2.Text = Text2.Text & s(i)Next iEnd SubPublic Sub PUSH(x As String, s() As String, m As Integer, top As Integer)If (top = m) ThenMsgBox "数据有误"EndEnd Iftop = top + 1s(top) = x End SubPublic Sub pop(x, s() As String, top As Integer) If top = 0 ThenMsgBox "栈空"End Ifx = s(top)top = top - 1End SubPublic Sub pre(x As String, p As Integer)Select Case xCase "*"p = 2Case "+"p = 1Case "-"p = 1Case ";"p = 0Case "^"p = 3End SelectEnd SubPrivate Sub Command3_Click()Dim topo As Integer, topn As IntegerDim p, f, i, x1, y1 As IntegerDim a1 As Integer, a2 As IntegerDim y, os(100) As StringDim a As String, x As StringDim z As String, w As StringDim ns(100) As String, q As Stringtopo = 0topn = 0z = ";"f = 0PUSH z, os(), 10, topoi = 0a = Text1.TextDo While f <> 2If f = 0 Theni = i + 1w = Mid(a, i, 1)End IfIf Not ((w = "*") Or (w = "+") Or (w = "-") Or (w = "/") Or (w = "^") Or (w = ";")) ThenPUSH w, ns(), 10, topnElsetp q, os(), topopre w, a1pre q, a2If (a1 > a2) ThenPUSH w, os(), 10, topof = 0ElseIf (q = ";") And (w = ";") Thenpop x, ns(), topnf = 2Elsepop x, ns(), topnpop y, ns(), topnpop q, os(), topox1 = Val(x)y1 = Val(y) Select Case qCase "*"x1 = y1 * x1Case "/"x1 = y1 / x1Case "+"x1 = y1 + x1Case "-"x1 = y1 - x1Case "'"x1 = y1 ^ x1End Selectx = Str(x1)PUSH x, ns(), 10, topnf = 1End IfEnd IfLoopText4.Text = Str(x1)End SubPrivate Sub Form_Load()Text1.Text = ""Text2.Text = ""End SubPublic Sub tp(x, s() As String, top As Integer) If top = 0 ThenMsgBox "栈空"End Ifx = s(top)End Sub。
栈的应用表达式求值的原理
栈的应用:表达式求值的原理一、栈的基本原理1.栈是一种具有特殊操作的线性数据结构。
2.栈的特点是后进先出(LIFO,Last In First Out)的存取方式。
3.栈有两个基本操作:入栈和出栈。
二、表达式求值的概念1.表达式是由运算符和运算对象组成的序列。
2.表达式求值是指根据运算符的优先级和结合性来计算表达式的值。
三、中缀表达式与后缀表达式1.中缀表达式:运算符位于运算对象的中间。
–例如:2 + 32.后缀表达式(逆波兰表达式):运算符位于运算对象的后面。
–例如:2 3 +四、中缀转后缀表达式1.利用栈实现中缀表达式到后缀表达式的转换。
2.遍历中缀表达式中的每个字符,若为数字,则输出到后缀表达式中;若为运算符,则根据优先级进行处理。
3.将运算符入栈,直到出现低优先级的运算符或左括号。
4.遇到右括号时,将栈中的运算符出栈并输出,直到遇到左括号。
5.将剩余的运算符出栈并输出。
五、后缀表达式求值1.利用栈实现后缀表达式的求值。
2.遍历后缀表达式中的每个字符,若为数字,则入栈;若为运算符,则弹出栈中的两个数字进行计算,并将结果入栈。
3.最后栈中的唯一元素即为表达式的求值结果。
六、示例假设要求解的中缀表达式为:2 + 3 * 4 - 5 1. 将中缀表达式转换为后缀表达式:2 3 4 * + 5 - 2. 根据后缀表达式求值的原则,遍历后缀表达式进行计算: - 遇到数字2,入栈; - 遇到数字3,入栈; - 遇到运算符*,弹出栈中的两个数字3和2进行计算得到6,并将结果入栈; - 遇到运算符+,弹出栈中的两个数字6和4进行计算得到10,并将结果入栈; - 遇到数字5,入栈; - 遇到运算符-,弹出栈中的两个数字10和5进行计算得到5,并将结果入栈。
3. 栈中的唯一元素5即为表达式的求值结果。
七、总结1.栈的应用在表达式求值中起到关键作用。
2.利用栈可以将中缀表达式转换为后缀表达式,并通过对后缀表达式的求值获得最终结果。
[论文]VB程序设计的常用算法
VB程序设计的常用算法算法(Algorithm),计算机解题的基本思想方法和步骤.算法的描述:是对要解决一个问题或要完成一项任务所采取的方法和步骤的描述,包括需要什么数据(输入什么数据,输出什么结果),采用什么结构,使用什么语句以及如何安排这些语句等.通常使用自然语言,结构化流程图,伪代码等来描述算法.一、计数,求和,求阶乘等简单算法此类问题都要使用循环,要注意根据问题确定循环变量的初值,终值或结束条件,更要注意用来表示计数,和,阶乘的变量的初值.例:用随机函数产生100个[0,99]范围内的随机整数,统计个位上的数字分别为1,2,3,4,5,6,7,8,9,0的数的个数并打印出来.本题使用数组来处理,用数组a(1 to 100)存放产生的确100个随机整数,数组x(0 to 9)来存放个位上的数字分别为0,1,2,3,4,5,6,7,8,9的数的个数.即个位是1的个数存放在x(1)中,个位是2的个数存放在x(2)中,……个位是0的个数存放在x(0).将程序编写在一个GetTJput过程中,代码如下:Public Sub GetTJput()Dim a(1 To 100) As IntegerDim x(0 To 9) As IntegerDim i As IntegerFor i = 1 To 100a(i) = Int(Rnd * 100)r = a(i) Mod 10x(r) = x(r) + 1Print a(i); "("; x(r); ")"; ;If i Mod 10 = 0 Then PrintNextPrint "********************"For i = 0 To 9Print x(i)NextEnd Sub二、最大公约数与最小公倍数(1)(2) m除以n得余数r;(3) 若r=0,则n为求得的最大公约数,算法结束;否则执行(4);(4) m←n,n←r,再重复执行(2).例如: 求m=14 ,n=6 的最大公约数. mnrm=inputBox("m=")n=inputBox("n=")nm=n*mIf m < n Then t = m: m = n: n = tr=m mod nDo While (r <>0)m=nn=rr= m mod nLoopPrint "最大公约数=", nPrint "最小公倍数=", nm/n三、判断素数只能被1或本身整除的数称为素数基本思想:把m作为被除数,将2—(m-1)作为除数,如果都除不尽,m就是素数,否则就不是.(可用以下程序段实现)m =val( InputBox("请输入一个数"))For i=2 To m-1If m Mod i = 0 Then Exit ForNext iIf i = m ThenPrint "该数是素数"ElsePrint "该数不是素数"End If将其写成一函数,若为素数返回True,不是则返回FalsePrivate Function Prime( m as Integer) As BooleanDim i%Prime=TrueFor i=2 To int(sqr(m))If m Mod i = 0 Then Prime=False : Exit ForNext iEnd Function四、验证哥德巴赫猜想(任意一个大于等于6的偶数都可以分解为两个素数之和)基本思想:n为大于等于6的任一偶数,可分解为n1和n2两个数,分别检查n1和n2是否为素数,如都是,则为一组解.如n1不是素数,就不必再检查n2是否素数.先从n1=3开始,检验n1和n2(n2=N-n1)是否素数.然后使n1+1 再检验n1,n2是否素数,…直到n1=n/2为止.利用上面的prime函数,验证哥德巴赫猜想的程序代码如下:Dim n%,n1%,n2%n=Val(InputBox("输入大于6的正整数"))For n1=3 to n\2n2=n-n1If prime(n1) And Prime(n2) thenPrint n & "=" & n1 & "+" & n2Exit For ’结束循环End ifNext n1五、排序问题1.选择法排序(升序)基本思想:1)对有n个数的序列(存放在数组a(n)中),从中选出最小的数,与第1个数交换位置;2)除第1 个数外,其余n-1个数中选最小的数,与第2个数交换位置;3)依次类推,选择了n-1次后,这个数列已按升序排列.程序代码如下:For i = 1 To n - 1imin = iFor j = i + 1 To nIf a(imin) > a(j) Then imin = jNext jtemp = a(i)a(i) = a(imin)a(imin) = tempNext I2.冒泡法排序(升序)基本思想:(将相邻两个数比较,小的调到前头)1)有n个数(存放在数组a(n)中),第一趟将每相邻两个数比较,小的调到前头,经n-1次两两相邻比较后,最大的数已"沉底",放在最后一个位置,小数上升"浮起";2)第二趟对余下的n-1个数(最大的数已"沉底")按上法比较,经n-2次两两相邻比较后得次大的数;3)依次类推,n个数共进行n-1趟比较,在第j趟中要进行n-j次两两比较.程序段如下For i = 1 To n - 1For j = 1 To n-iIf a(j) > a(j+1) Thentemp=a(j): a(j)=a(j+1): a(j+1)=tempEnd ifNext jNext i六、查找问题1.顺序查找法(在一列数中查找某数x)基本思想:一列数放在数组a(1)---a(n)中,待查找的数放在x 中,把x 与a数组中的元素从头到尾一一进行比较查找.用变量p表示a数组元素下标,p初值为1,使x与a(p)比较,如果x不等于a(p),则使p=p+1,不断重复这个过程;一旦x等于a(p)则退出循环;另外,如果p大于数组长度,循环也应该停止.(这个过程可由下语句实现)p = 1Do While x<>a(p) And p < =np = p + 1Loop下面写一查找函数Find,若找到则返回下标值,找不到返回0Option Base 1Private Function Find( a( ) As Single,x As Single) As IntegerDim n%,p%n=Ubound( a )p = 1Do While x<> a(p) And p<=np=p+1LoopFind=pEnd Function2.折半查找法(只能对有序数列进行查找)基本思想:设n个有序数(从小到大)存放在数组a(1)----a(n)中,要查找的数为x,用变量bot,top,mid 分别表示查找数据范围的底部(数组下界),顶部(数组的上界)和中间,mid=(top+bot)/2,折半查找的算法如下:(1)x=a(mid),则已找到退出循环,否则进行下面的判断;(2)x<a(mid),x必定落在bot和mid-1的范围之内,则top=mid-1;(3)x>a(mid),x必定落在mid+1和top的范围之内,则bot=mid+1;(4)在确定了新的查找范围后,重复进行以上比较,直到找到或者bot<=top.将上面的算法写成如下函数,若找到则返回该数所在的下标值,没找到则返回-1.Function search(a() As Integer, x As Integer) As IntegerDim bot%, top%, mid%Dim find As Boolean ’代表是否找到search=-1bot = LBound(a)top = UBound(a)find = False ’判断是否找到的逻辑变量,初值为FalseDo While bot <= top And Not findmid = (top + bot) \ 2If x = a(mid) Thenfind = True : search=mid : Exit DoElse If x<a(mid) Thentop=mid-1Else If x>a(mid) Thenbot=mid+1End IfLoopEnd Function七、数制转换将一个十进制整数m转换成→r(2-16)进制字符串.方法:将m不断除r 取余数,直到商为零,以反序得到结果.下面写出一转换函数,参数idec为十进制数,ibase为要转换成数的基(如二进制的基是2,八进制的基是8等),函数输出结果是字符串.Private Function TrDec(idec As Integer, ibase As Integer) As String Dim strDecR$, iDecR%strDecR = ""Do While idec<>0iDecR = idec Mod ibaseIf iDecR >= 10 ThenstrDecR = Chr$(65 + iDecR - 10) & strDecRElsestrDecR = iDecR & strDecREnd Ifidec = idec \ ibaseLoopTrDec = strDecREnd Function八、穷举法穷举法(又称"枚举法")的基本思想是:一一列举各种可能的情况,并判断哪一种可能是符合要求的解,这是一种"在没有其它办法的情况的方法",是一种最"笨"的方法,然而对一些无法用解析法求解的问题往往能奏效,通常采用循环来处理穷举问题.例: 将一张面值为100元的人民币等值换成100张5元,1元和0.5元的零钞,要求每种零钞不少于1张,问有哪几种组合Dim i%, j%, k%Print "5元1元0.5元"For i = 1 To 20For j = 1 To 100 - ik = 100 - i - jIf 5.0 * i + 1.0 * j + 0.5 * k = 100 ThenPrint i, j, kEnd IfNext jNext i十一、递归算法用自身的结构来描述自身,称递归VB允许在一个Sub子过程和Function过程的定义内部调用自己,即递归Sub子过程和递归Function函数.递归处理一般用栈来实现,每调用一次自身,把当前参数压栈,直到递归结束条件;然后从栈中弹出当前参数,直到栈空.递归条件:(1)递归结束条件及结束时的值;(2)能用递归形式表示,且递归向终止条件发展.例:编fac(n)=n! 的递归函数Function fac(n As Integer) As IntegerIf n = 1 Thenfac = 1Elsefac = n * fac(n - 1)End If。
俩种方法实现表达式求值
一、设计思想用中缀式实现表达式自动计算,可以先定义两个栈。
一个称为OPTR,用以寄存运算符;另一个称做OPND,用以寄存操作数或运算结果。
算法的基本思想是:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素。
(2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较优先权后作相应操作,若栈顶元素优先权低于读入的运算符,则入栈;若栈顶元素优先权等于读入的运算符,则出栈(相当于是把括号去掉);若栈顶元素优先权高于读入的运算符,则从OPND取出两个操作数分别放到变量里,再从OPTR里取出运算符做运算,然后将运算结果再放入OPND栈里。
直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为“#”)。
(3)输出结果。
用后缀式实现表达式自动计算,算法的基本思想是:(1)在主函数定义两个数组,一个数组存放中缀表达式,一个存放后缀表达式,在主函数里定义一个函数,通过调用函数实现中缀式转为后缀式。
(2)首先把输入的表达式放入中缀表达式数组,通过调用实现中缀转后缀,具体过程是定义一个数组存放操作数,定义一个栈存放运算符,当有括号时取两个操作数作运算,再把结果放到后缀式数组。
(3)在通过调用函数对后缀表达式求值。
(4)最后把中缀式,后缀式与结果打印出来。
二、算法流程图图1中缀式算法流程图图2后缀式算法流程图三、源代码下面给出的是用中缀式算法实现的程序的源代码,#include <stdio.h>#include <math.h>#include <string.h>#include <stdlib.h>#define true 1#define false 0#define STACK_SIZE 50char opt[7]={'+','-','*','/','(',')','#'};intisp[7][7]={{3,3,1,1,1,3,3},{3,3,1,1,1,3,3},{3,3,3,3,1,3,3},{3,3,3,3,1,3,3},{1,1,1,1,1,2,0},{3,3,3,3,0,3,3},{1,1,1,1,1, 0,2}};typedef struct{char optr[STACK_SIZE];int top;}stack;typedef struct{char opnd[STACK_SIZE];int top;}dstack; /*定义栈*/void InitStack(stack *s){s->top=-1;}void InitStacks(dstack *s){s->top=-1; /*初始化栈*/}int isempty(stack *s){if(s->top==-1)return true;elsereturn false;}int isemptyd(dstack *s){if(s->top==-1)return true;elsereturn false; /*判断栈是否为空*/}int isfull(stack *s){if(s->top==(STACK_SIZE-1))return true;elsereturn false;}int isfulld(dstack *s){return(s->top==(STACK_SIZE-1)?true:false); /*判断栈是否满*/ }int push(stack *s,char c){if(isfull(s)){printf("stack is full!\n");return false;}else{s->top++;s->optr[s->top]=c;return true;}}int pushd(dstack *s,int n){if(isfulld(s)){printf("dstack is full!\n");return false;}else{s->top++;s->opnd[s->top]=n;return true;}} /*入栈*/ int pop(stack *s,char *c){if(isempty(s)){printf("stack is empty!\n");return false;}else{*c=s->optr[s->top];s->top--;return true;}}int popd(dstack *s,int *n){if(isemptyd(s)){printf("stack if empty!\n");return false;}else{*n=s->opnd[s->top];s->top--;return true;}} /*出栈*/char getoptr(stack *s){if(isempty(s)){printf("stack is empty!\n");return false;}elsereturn s->optr[s->top];}int getopnd(dstack *s){if(isemptyd(s)){printf("stack is empty!\n");return false;}elsereturn s->opnd[s->top];}int isoptr(char ch){int i;for(i=0;i<7;i++){if(opt[i]==ch)return true;}return false;}int compare(char ch1,char ch2){int i,j,k;for(i=0;i<7;i++){if(ch1==opt[i])j=i;if(ch2==opt[i])k=i;}return isp[j][k];}int compute(int a,char optr,int b){int result;switch(optr){case'+': result=a+b;break;case'-': result=a-b;break;case'*': result=a*b;break;case'/': result=a/b;break;}return result;}int execute(){int i=0,temp,j,k,m;char c,op;char *ch;stack optr;dstack opnd;InitStack(&optr);InitStacks(&opnd);push(&optr,'#');printf("请输入表达式以'#'结束\n");ch=(char *)malloc(50*sizeof(char));gets(ch);c=ch[i++];while(c!='#' || getoptr(&optr)!='#'){if(!isoptr(c)){temp=c-'0';c=ch[i++];while(!isoptr(c)){temp=temp*10+c-'0';c=ch[i++];}pushd(&opnd,temp);}else{switch(compare(getoptr(&optr),c)){case 1:push(&optr,c);c=ch[i];i++;break;case 2:pop(&optr,&op);c=ch[i++];break;case 3:pop(&optr,&op);popd(&opnd,&j);popd(&opnd,&k);m=compute(k,op,j);pushd(&opnd,m);break;case 0:printf("wrong input!\n");return false;}}}m=getopnd(&opnd);return m;}void main(){int result;result= execute();printf("结果是%d\n",result);}下面给出的是用后缀式算法实现的程序的源代码,#include <stdio.h>#include <malloc.h>#include<process.h>#define MaxSize 50void trans(char *exp,char *postexp)/*中缀式变后缀式函数*/{struct{char data[MaxSize];/*存放运算符*/int top;} op;int i=0;op.top=-1;while(*exp!='\0'){switch(*exp){case '(':op.top++;op.data[op.top]=*exp;exp++;break;case ')':while(op.data[op.top]!='('){postexp[i++]=op.data[op.top];op.top--;}op.top--;exp++;break; /*等于左括号时,要释放左括号,即op.top--*/case '+':case '-':while(op.top!=-1&&op.data[op.top]!='(')/*为加减乘除是都比新进的加减号优先级高,固要先出站再入*/{postexp[i++]=op.data[op.top];op.top--;}op.top++;op.data[op.top]=*exp;exp++;break;case '*':case '/':while(op.data[op.top]=='*'||op.data[op.top]=='/'){postexp[i++]=op.data[op.top];op.top--;}op.top++;op.data[op.top]=*exp;exp++;break;case ' ':break;default:while(*exp>='0'&&*exp<='9'){postexp[i++]=*exp;exp++;}postexp[i++]='#';/*用#标识一个数值串结束*/ }}while(op.top!=-1)/*栈中的剩余符号,按优先级依次入栈*/{postexp[i++]=op.data[op.top];op.top--;}postexp[i]='\0';}float compvalue(char *postexp)/*后缀式求值运算函数*/{struct{float data[MaxSize];int top;} st;float a,b,c,d;st.top=-1;while(*postexp!='\0'){switch(*postexp){case '+':a=st.data[st.top];/*退栈取数值a,b;符号前已有数值*/st.top--;b=st.data[st.top];st.top--;c=b+a;st.top++;st.data[st.top]=c;break;case '-':a=st.data[st.top];st.top--;b=st.data[st.top];st.top--;c=b-a;st.top++;st.data[st.top]=c;break;case '*':a=st.data[st.top];st.top--;b=st.data[st.top];st.top--;c=b*a;st.top++;st.data[st.top]=c;break;case '/':a=st.data[st.top];st.top--;b=st.data[st.top];st.top--;if(a!=0){c=b/a;st.top++;st.data[st.top]=c;}else{printf("\n\t除零错误!\n");exit(0);}break;default:d=0;while(*postexp>='0'&&*postexp<='9'){d=10*d+*postexp-'0'; /*将d赋值为10乘d与*postexp的ASCII值减数字0的ASCII值的和*/postexp++;}st.top++;st.data[st.top]=d;break;}postexp++;}return st.data[st.top];}int main(){char exp[MaxSize],postexp[MaxSize];while(scanf("%s",&exp)!=EOF){trans(exp,postexp);printf("中缀表达式: %s\n",exp);printf("后缀表达式: %s\n",postexp);printf("值: %g\n",compvalue(postexp));}return 0;}四、运行结果图3中缀式运行结果图图4后缀式运行结果图五、遇到的问题及解决这部分我主要遇到了如下两个问题,其内容与解决方法如下所列:●问题1描述:不知道如何定义栈。
栈实现表达式求值
栈实现表达式求值栈实现表达式求值使⽤键盘输⼊数学表达式(含数字,四种运算符+、-、、/和⼩括号,其中运算数都是⼀位数(0~9)),将数学表达式转化成后缀表达式输出,利⽤后缀表达式求表达式的值并输出。
输⼊格式:输⼊正确的表达式(可以有空格)后回车,得到后缀表达式和结果。
输⼊括号缺失的表达式,输出"ERROR:缺少括号"。
输⼊两个除括号外运算符连续的表达式,输出"ERROR:表达式缺操作数"。
输出格式:请在这⾥描述输出格式。
例如:对每⼀组输⼊,在⼀⾏中输出A+B的值。
输⼊样例:在这⾥给出⼀组输⼊。
例如:5*(8-(3+2))结尾⽆空⾏输出样例:在这⾥给出相应的输出。
例如:5832+-*15结尾⽆空⾏代码如下:#include<stdio.h>#include<iostream>#include<stack>#include<string>#include <math.h>using namespace std;stack<int> MoveIn;stack<char> CharStack;string fixStr = "";void IntoPost(string inStr);bool isPush(char pre, char late);void Calculate(char np);void CalFix();void pushChar(char np);string format(string inStr) { //解决(-1+2)负数报错问题for (int i = 0; i < inStr.length(); i++) //即在 -1 前⾯加⼀个0 变成 0-1 即可if (inStr[i] == '-')if (i == 0)inStr.insert(0, 1, '0');else if (inStr[i - 1] == '(')inStr.insert(i, 1, '0');return inStr;}int main(){string inStr;getline(cin, inStr);//使⽤getline 解决字符串录⼊遇空格结束的问题类似( a + b )只写⼊了(的inStr = format(inStr);int i=0;int K_num=0;int K_1=0;int K_2=0;while(inStr[i]!='\0'){if(inStr[i]=='('||inStr[i]==')'){K_num++;}if(inStr[i]=='+'||inStr[i]=='-'||inStr[i]=='*'||inStr[i]=='/'){if(inStr[i+1]=='+'||inStr[i+1]=='-'||inStr[i+1]=='*'||inStr[i+1]=='/') {K_1=1;printf("ERROR:表达式缺操作数");}}i++;}if(K_num%2!=0){K_2=1;printf("ERROR:缺少括号");}if((K_1==0)&&(K_2==0)){IntoPost(inStr);cout<<fixStr<<endl;CalFix();}return0;}void IntoPost(string inStr) { //前缀转后缀for (int i = 0; i < inStr.length(); i++) {switch (inStr[i]) {case'': break;case'+':pushChar('+'); break;case'(':CharStack.push('('); break;//遇前括号直接⼊栈case')': //遇后括号弹出所有⾄上⼀个括号while (CharStack.top() != '(') {fixStr += CharStack.top();CharStack.pop();}CharStack.pop();break;case'/':pushChar('/'); break;case'*':pushChar('*'); break;case'-':pushChar('-'); break;case'^':pushChar('^'); break;default:fixStr += inStr[i]; break; //数字直接输出}}while (!CharStack.empty()) { //整式尾部时弹出所有站内符号 fixStr += CharStack.top();CharStack.pop();}}void pushChar(char np) { //运算符出栈if (!CharStack.empty()){while (!CharStack.empty() && isPush(CharStack.top(), np)) {fixStr += CharStack.top(); //判断优先级CharStack.pop();}CharStack.push(np);}elseCharStack.push(np);}bool isPush(char pre, char late) { //优先级⽐较if (late == '^')if (pre == '^') return true;else return false;if (late == '*' || late == '/')if (pre == '^' || pre == '*' || pre == '/') return true;else return false;if (late == '+' || late == '-')if (pre == '(') return false;else return true;return false;}void CalFix() { //后缀表达式计算for (int i = 0; i < fixStr.length(); i++) {switch (fixStr[i]) {case'+':Calculate('+'); break;case'/':Calculate('/'); break;case'*':Calculate('*'); break;case'-':Calculate('-'); break;case'^':Calculate('^'); break;case'': break;default:int a;a = (int)(fixStr[i] - 48);MoveIn.push(a);break;}}cout << MoveIn.top();}void Calculate(char np) { //弹出两个栈内数运算后再压进栈int pre, late;late = MoveIn.top();MoveIn.pop();pre = MoveIn.top();MoveIn.pop();switch (np) {case'+':MoveIn.push(pre + late); break;case'/':MoveIn.push(pre / late); break;case'*':MoveIn.push(pre * late); break;case'-':MoveIn.push(pre - late); break;case'^':MoveIn.push(pow(pre,late)); break;default:break;}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一
Dim s(100) As String, t As Integer
Private Sub Command2_Click()
Dim x As String, n, i As Integer
Text3.Text = " "
For i = t To 1 Step -1
pop x, s(), t
Text3.Text = Text3.Text & x
Next i
End Sub
Private Sub Command1_Click()
Dim a, b, x As String, n, i, m As Integer
Text2.Text = ""
a = Text1.Text
n = Len(a)
m = 10
t = 0
For i = 1 To n
x = Mid(a, i, 1)
PUSH x, s(), m, t
Text2.Text = Text2.Text & s(i)
Next i
End Sub
Public Sub PUSH(x As String, s() As String, m As Integer, top As Integer)
If (top = m) Then
MsgBox "数据有误"
End
End If
top = top + 1
s(top) = x
End Sub
Public Sub pop(x, s() As String, top As Integer) If top = 0 Then
MsgBox "栈空"
End If
x = s(top)
top = top - 1
End Sub
Public Sub pre(x As String, p As Integer) Select Case x
Case "*"
p = 2
Case "+"
p = 1
Case "-"
p = 1
Case ";"
p = 0
Case "^"
p = 3
End Select
End Sub
Private Sub Command3_Click()
Dim topo As Integer, topn As Integer Dim p, f, i, x1, y1 As Integer
Dim a1 As Integer, a2 As Integer
Dim y, os(100) As String
Dim a As String, x As String
Dim z As String, w As String
Dim ns(100) As String, q As String topo = 0
topn = 0
z = ";"
f = 0
PUSH z, os(), 10, topo
i = 0
a = Text1.Text
Do While f <> 2
If f = 0 Then
i = i + 1
w = Mid(a, i, 1)
End If
If Not ((w = "*") Or (w = "+") Or (w = "-") Or (w = "/") Or (w = "^") Or (w = ";")) Then
PUSH w, ns(), 10, topn
Else
tp q, os(), topo
pre w, a1
pre q, a2
If (a1 > a2) Then
PUSH w, os(), 10, topo
f = 0
ElseIf (q = ";") And (w = ";") Then
pop x, ns(), topn
f = 2
Else
pop x, ns(), topn
pop y, ns(), topn
pop q, os(), topo
x1 = Val(x)
y1 = Val(y)
Select Case q
Case "*"
x1 = y1 * x1
Case "/"
x1 = y1 / x1
Case "+" x1 = y1 + x1
Case "-"
x1 = y1 - x1
Case "'"
x1 = y1 ^ x1
End Select
x = Str(x1)
PUSH x, ns(), 10, topn
f = 1
End If
End If
Loop
Text4.Text = Str(x1)
End Sub
Private Sub Form_Load()
Text1.Text = ""
Text2.Text = ""
End Sub
Public Sub tp(x, s() As String, top As Integer) If top = 0 Then
MsgBox "栈空"
End If
x = s(top)
End Sub。