package come.feiqiang.stack;
import java.util.Scanner;
import java.util.Stack;
import java.util.regex.Pattern;
public class Algorithm {
/**
* 验证各种括号的匹配问题,是对栈的基本应用:
* @param expression
* @return
*/
public static boolean isBalanced(String expression){
final char LEFT_NOMAL='(';
final char RIGHT_NOMAL=')';
final char LEFT_CURLY='{';
final char RIGHT_CURLY='}';
final char LEFT_SQUARE='[';
final char RIGHT_SQUARE=']';
Stack<Character> store=new Stack<Character>();
int i;
boolean failed=false;
for(i=0;!failed&&i<expression.length();i++){
switch(expression.charAt(i)){
case LEFT_NOMAL:
case LEFT_CURLY:
case LEFT_SQUARE:
store.push(expression.charAt(i));
break;
case RIGHT_NOMAL:
if(store.isEmpty()||store.pop()!=LEFT_NOMAL){
failed=true;
}
break;
case RIGHT_CURLY:
if(store.isEmpty()||store.pop()!=LEFT_CURLY){
failed=true;
}
break;
case RIGHT_SQUARE:
if(store.isEmpty()||store.pop()!=LEFT_SQUARE){
failed=true;
}
break;
}
}
return (store.isEmpty()&&!failed);
}
/**
* 计算完全加括号的算术:
* @param numbers 数字栈
* @param operations 操作符栈
* 算法:
* do
* if(下一个输入是数值)
* 进数值栈
else if(下一个输入是操作符)
* 进操作符栈
* else if(下一个输入是右括号)
* 弹出两个数值,弹出一个操作符,将后弹出的数值与前弹出的数值作运算,将操作结果压入数值栈
* 如果栈为空,或操作数为空,抛出异常
* else if(下一个输入是左括号)
* 跳过
* else 抛出非法字符异常
*while(还有更多输入)
* 算法缺点:没有检查括号的正确匹配情况,有兴趣的读者可以自己研究一下
*
*/
public static void evaluateStackTops(Stack<Double> numbers, Stack<Character> operations){
double operand1;
double operand2;
operand1=numbers.pop();
operand2=numbers.pop();
char operation=operations.pop();
switch(operation){
case '+':
numbers.push(operand1+operand2);
break;
case '-':
numbers.push(operand1-operand2);
break;
case '*':
numbers.push(operand1*operand2);
break;
case '/':
numbers.push(operand1/operand2);
break;
default:
throw new IllegalArgumentException("Illegal Operation");
}
}
public static double evaluate(String expression){
Stack<Double> numbers=new Stack<Double>();
Stack<Character> operations=new Stack<Character>();
Scanner input=new Scanner(expression);
String next;
final Pattern CHARACTER=Pattern.compile("\\S.*?");
final Pattern UNSIGN_DOUBLE=Pattern.compile("(((\\d+\\.?\\d*)|(\\.\\d+))([Ee][+-]?\\d+)?.*?)");
while(input.hasNext()){
if(input.hasNext(UNSIGN_DOUBLE)){
next=input.findInLine(UNSIGN_DOUBLE);
numbers.push(new Double(next));
}
else{
next=input.findInLine(CHARACTER);
switch(next.charAt(0)){
case '+':
case '-':
case '*':
case '/':
operations.push(next.charAt(0));
break;
case ')':
evaluateStackTops(numbers,operations);
break;
case '(':
break;
default:
throw new IllegalArgumentException("Illegal character");
}
}
}
if(numbers.size()!=1){
throw new IllegalArgumentException("Illegal input Exception");
}
return numbers.pop();
}
/**
* 后缀表达式的计算:
* @param expression
* @return
* 算法:
* 初始化一个由双精度实数构成的栈
* while(表达式中有更多输入)
* if(下一个输入是数值)
* 读取下一个元素并压入栈中
* else
* (下一个输入是操作符)
* 弹出两个操作数,根据操作符运算后将结果压入栈中
* while end
*
*/
public static double evaluatePostfix(String expression){
double answer;
Scanner scanner=new Scanner(expression);
Stack<Double> numbers=new Stack<Double>();
Pattern UNSIGN_DOUBLE=Pattern.compile("((\\d+\\.?\\d*)|(\\.\\d+))([Ee][+-]?\\d+)?.*?");
Pattern CHARACTER=Pattern.compile("\\S.*?");
while(scanner.hasNext()){
if(scanner.hasNext(UNSIGN_DOUBLE)){
numbers.push(new Double(scanner.findInLine(UNSIGN_DOUBLE)));
}
else if(scanner.hasNext(CHARACTER)){
double operand2=numbers.pop();
double operand1=numbers.pop();
switch(scanner.findInLine(CHARACTER).charAt(0)){
case '+':numbers.push(operand1+operand2);break;
case '-':numbers.push(operand1-operand2);break;
case '*':numbers.push(operand1*operand2);break;
case '/':numbers.push(operand1/operand2);break;
default:throw new IllegalArgumentException("the expression is't right");
}
}
else{
throw new IllegalArgumentException("the expression is't right");
}
}
if(numbers.size()!=1){
throw new IllegalArgumentException("illegal expression");
}
answer=numbers.pop();
return answer;
}
/**
* 由普通的中缀表达是转化为后缀表达式:
* @param expression
* @return
* 算法:
* 略
*/
public static String convertMidToPost(String expression){
String answer="";
Stack<Character> operations=new Stack<Character>();
Pattern UNSIGN_DOUBLE=Pattern.compile("((\\d+\\.?\\d*)|(\\.\\d+))([Ee][+-]?\\d+)?.*?");
Pattern CHARACTER=Pattern.compile("\\S.*?");
Scanner scanner=new Scanner(expression);
while(scanner.hasNext()){
if(scanner.hasNext(UNSIGN_DOUBLE)){
answer+=scanner.findInLine(UNSIGN_DOUBLE)+" ";
}
else{
char m;
if(scanner.hasNext(CHARACTER)){
switch((m=scanner.findInLine(CHARACTER).charAt(0))){
case '+':
case '-':
case '*':
case '/':
case '(':
operations.push(m);break;
case ')':
char c=operations.pop();
if((operations.isEmpty())||(c!='+'&&c!='-'&&c!='*'&&c!='/')){
throw new IllegalArgumentException("not valid expression");
}
answer+=String.valueOf(c)+" ";
if(operations.pop()!='('){
throw new IllegalArgumentException("not valid expression");
}
break;
default:
throw new IllegalArgumentException("not valid expression");
}
}
}
}
return answer;
}
/**
* 带有优先级的中缀表达式的求解
* @param expression
* @return
* 算法:
* 初始化一个空字符串和一个字符栈
* while(表达式还有更多输入)
* if(下一个输入为数值)
* 读取下一个输入,并入字符串尾部
* else
* if(下一个输入是优先级较高的(*,/)运算符||当前栈为空||当前栈顶元素为'(')
* 读取字符下一个输入符号
* else if(下一个输入是'(')
* 读取字符并且压入栈中
* else if(下一个输入是')')
* 将当前栈中元素全部加入字符串尾部
* else if(下一个输入是运算符)
* 将栈中的符号弹出,并入字符串尾部
* 读取下一个字符串,并且压入栈中
* else
* 弹出非法表达是一茶馆
* while end
*
* 下面的代码与算法稍有差别,因为算法是后写的,所以算法的入错能力更强
*/
public static String priorityOfMid(String expression){
String answer="";
Scanner scanner=new Scanner(expression);
Pattern UNSIGN_DOUBLE=Pattern.compile("((\\d+\\.?\\d*)|(\\.\\d+))([Ee][+-]?\\d+)?.*?");
Pattern CHARACTER=Pattern.compile("\\S.*?");
Stack<Character> operations=new Stack<Character>();
if(!scanner.hasNext()){
throw new IllegalArgumentException("illegal exception");
}
while(scanner.hasNext()){
if(scanner.hasNext(UNSIGN_DOUBLE)){
answer+=scanner.findInLine(UNSIGN_DOUBLE)+" ";
}else{
char occurrence=scanner.findInLine(CHARACTER).charAt(0);
if((operations.isEmpty()||operations.peek()=='(')||(occurrence=='*'||occurrence=='/')&&(operations.peek()=='+'||operations.peek()=='-')){
System.out.println("in 1");
operations.push(occurrence);
}else if(occurrence=='('){
operations.push(occurrence);
System.out.println("in 2");
}else if(occurrence==')'){
System.out.println("in 3");
while(!operations.isEmpty()&&operations.peek()!='('){
answer+=String.valueOf(operations.pop())+" ";
}
if(operations.pop()!='('){
throw new IllegalArgumentException("illegal exception");
}
}
else{
System.out.println("in 4");
answer+=operations.pop()+" ";
operations.push(occurrence);
}
}
}
while(!operations.isEmpty()){
answer+=operations.pop()+" ";
}
scanner.close();
return answer;
}
public static void main(String args[]){
//System.out.println(evaluate("(((2+3)+3)*3)"));
//System.out.println("concequence:"+evaluatePostfix("2 3.0*5-6/"));
String midExpression="2";
String postExpression=priorityOfMid(midExpression);
System.out.println("postExpression:"+postExpression);
System.out.print(midExpression+"=");
double x=evaluatePostfix(postExpression);
System.out.println(x);
}
}
分享到:
相关推荐
5. 计算机算术运算的设计原理:算术运算设计不仅仅是一个独立的领域,它与计算机科学和数字工程的许多领域都密切相关。设计原理涉及到算术运算算法的开发、逻辑实现、计算机结构设计以及数值分析等方面,对计算机的...
在数字信号处理(DSP)领域,基本算术运算扮演着至关重要的角色,因为它们是所有复杂算法的基础。本文将深入探讨在CCS2000(Code Composer Studio)环境下进行这些基本运算的方法,并通过实际的实验报告和代码来增强...
设计一个VHDL模块进行算术运算,通常需要一个测试平台来验证其功能。测试平台会生成输入,调用模块,并检查输出是否符合预期。 综上所述,VHDL的算术运算是构建数字系统的基础,涵盖了从基本的加减乘除到更复杂的...
这个名为“简单的算术运算程序”的项目,就是为初学者设计的一个小程序,旨在帮助他们理解和应用基本的算术运算,比如加法。EVC(Embedded Visual C++)是微软提供的一种用于开发嵌入式系统应用程序的工具,它基于...
设计算术运算电路需要选择适合的电路结构和电子元件,以满足特定的应用要求。 第五部分:算术运算电路的实现 算术运算电路可以用多种方式实现,如使用数字集成电路(IC)、现场erasable programmable gate array...
小学算术运算测试程序,JAVA课程设计报告,有基本代码
本pdf文档介绍了计算机算术运算的原理、结构与设计。从简单的各类加减法到各种算法实现的乘法器、除法器,以及一些浮点运算、函数运算等等。深入浅出的解扰各种实现方法,帮你快速入门。作为手头一个全面的查找手册...
在现代计算机中,算术运算单元通常被设计得非常高效,能够快速准确地处理大量数据,这对于运行复杂计算任务至关重要。理解和掌握其工作原理对于深入理解计算机系统以及优化计算性能有着深远的影响。
易语言的核心支持库包括了汇编版本的算术运算模块,这是为了提高程序运行效率和性能而设计的。汇编语言是计算机硬件层面的编程语言,它可以更直接地控制硬件资源,相比高级语言通常能实现更快的计算速度。因此,将...
算术运算类指令是计算机指令集中的核心组成部分,它们用于执行基本的数学操作,如加、减、乘、除以及一些扩展的算术运算。在本文档中,我们将重点讨论不带进位的算术运算指令,特别是它们如何应用于多字节加法和减法...
"算术运算电路实验报告.pdf" 本实验报告主要介绍了算术运算电路的实验原理和实验步骤。算术运算电路是一种高放大倍数、高输入阻抗、低输出阻抗的直接耦合多级放大电路,具有两个输入端和一...3. 算术运算电路设计指南
在本篇微机原理实验报告中,主要目的是学习如何使用数据传送和算术运算指令来实现两个多位十进制数的相加。实验的具体任务是将十进制数28056和47193相加,这两个数以ASCII码的形式分别存储在内存的DATA1和DATA2区域...
### C高级语言程序设计:算术运算与逻辑运算 #### 运算符概述 C语言提供了多种运算符来处理各种计算需求,主要包括算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、条件运算符、逗号运算符、指针运算符...
随机算术运算程序设计 本文档介绍了一个使用C语言编写的随机算术运算程序,该程序可以生成10以内的随机算术运算题,并计算用户的回答是否正确。该程序使用了基本的C语言编程技术,包括变量声明、函数定义、条件语句...
8051算术逻辑运算单元设计8051算术逻辑运算单元设计8051算术逻辑运算单元设计8051算术逻辑运算单元设计8051算术逻辑运算单元设计8051算术逻辑运算单元设计8051算术逻辑运算单元设计8051算术逻辑运算单元设计
7. **算术与逻辑运算**:算术运算通常涉及到加减法,而逻辑运算包括AND, OR, NOT, XOR等操作。74LS181可以通过设置不同的S3, S2, S1, S0, M和CN信号,实现各种算术和逻辑运算功能,并通过总线指示灯显示运算结果。 ...
本课程设计报告主要探讨了如何实现一个简单的算术表达式求值系统,该系统能够处理不含变量的、基于字符序列的算术表达式,并按照运算优先级顺序进行运算。以下是详细的知识点说明: 1. **输入与输出**: - 用户...
### 组成原理实验算术运算知识点解析 #### 一、实验目的 本实验旨在深入理解算术逻辑单元(ALU)的工作原理及其在运算器中的应用。具体目标包括: 1. **掌握算术逻辑运算单元(ALU)的工作原理**:ALU是计算机的...
《计算机组成原理》实验报告——8位算术逻辑运算实验主要涵盖了计算机硬件系统中的核心组件——运算器的设计和操作。该实验旨在让学生深入理解算术逻辑运算器(ALU)的工作原理,以及如何通过控制电路实现不同的算术...