表达式求值(中缀式转后缀式,后缀式求值)NYOJ53测试通过

测试地址:http://acm.nyist.net/JudgeOnline/problem.php?pid=35

package calc;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class Main {
	//操作符栈
	static LinkedList<String> opStack=new LinkedList<String>();
	//优先级映射
	static Map<String, Integer> priority=new HashMap<String, Integer>(){
		{
			put("(", 0);
			put(")", 0);
			put("+", 1);
			put("-", 1);
			put("*", 2);
			put("/",2);
		}
	};
	/**
	 * 中缀转后缀:
	 * 		从左到右扫描表达式
	 * 		a:若是数字直接输出
	 * 		b:若是(直接入栈
	 * 		c:若是)将栈中操作符依次退栈输出,直到遇到(为止,将(出栈丢弃
	 * 		d其他:将当前操作符的优先级小于等于栈顶操作符优先级,则将栈顶操作出栈输出,直到不小于或栈空为止;将当前操作符入栈
	 */
	public static List<String> midToAfter(String [] mid){
		LinkedList<String> after=new LinkedList<String>();
		int index=0;
		for(String ss:mid){
			if(ss.equals("=")) continue;
			if(priority.get(ss)==null){//说明是操作数
				after.add(ss);
			}else if(ss.equals("(")){
				opStack.push(ss);
			}else if(ss.equals(")")){
				while(!opStack.peek().equals("(")){//不是“(”,则输出,
					after.add(opStack.pop());
				}
				opStack.pop();//去除(
			}else {
				while(!opStack.isEmpty()&&priority.get(ss)<=priority.get(opStack.peek())){
					after.add(opStack.pop());
				}
				opStack.push(ss);
			}
		}
		while(!opStack.isEmpty()) after.add(opStack.pop());
		return after;
	}
	/**
	 * 后缀求值:从左到右扫描后缀表达式
	 * 		a:若为数字,直接入栈
	 * 		b:若为操作符,从栈中出栈两个数字,按操作符计算,再把结果入栈,注意两个操作数运算顺序
	 * 		结果:最后栈中只有一个数字,出栈即为答案
	 * @param after
	 * @return
	 */
	public static double afterValue(List<String> after){
		LinkedList<Double> number=new LinkedList<Double>();
		for(String ss:after){
			if(priority.get(ss)!=null){//是操作符,取出两个数,按操作符计算后入数字栈
				Double y=number.pop();
				Double x=number.pop();
				if(ss.equals("+")) number.push(x+y);
				else if(ss.equals("-")) number.push(x-y);
				else if(ss.equals("*")) number.push(x*y);
				else if(ss.equals("/")) number.push(x/y);
			}else{
				number.push(Double.valueOf(ss));
			}
		}
		return number.pop();
	}
	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		int n=in.nextInt();
		String s;
		in.nextLine();//读书上面输入数字的那个换行
		while(n--!=0){
			//s=in.nextLine();
			s=in.nextLine();
			//将输入分离
			int pre=-1;//上一个符号的位置,当两个符号一起时:)*   应分成:*# 否则分成:#*#
			StringBuffer sb=new StringBuffer();
			for(int i=0;i<s.length();i++){
				if(s.charAt(i)!='.'&&(s.charAt(i)<'0'||s.charAt(i)>'9')){
					if(i-1==pre){ //上一个也是操作符号
						sb.append(s.charAt(i)+"#");
					}
					else sb.append("#"+s.charAt(i)+"#");
					pre=i;//更新pre
				}else{
					sb.append(s.charAt(i));
				}
			}
			String[] split = sb.toString().split("#");
			List after=midToAfter(split);
			double ans=afterValue(after);
			System.out.printf("%.2f\n",ans);
		}
	}
}
时间: 2024-10-24 12:44:21

表达式求值(中缀式转后缀式,后缀式求值)NYOJ53测试通过的相关文章

PTA-7-20 表达式转换(中缀转后缀,带括号,负数,小数转换)

本题考点:中缀表达式转后缀表达式. 难点: 带有小数的数字 数字可能带有正负号 题目描述: 算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间.请设计程序将中缀表达式转换为后缀表达式. 本题的测试点如下: 输入 输出 说明 2+3*(7-4)+8/4 2 3 7 4 - * + 8 4 / + 正常测试6种运算符 ((2+3)*4-(8+2))/5 2 3 + 4 * 8 2 + - 5 / 嵌套括号 1314+25.5*1

python学习笔记(八)函数return多个值,列表推导式和交换两个变量的值

函数return多个值: 补充知识点:写代码得到时候少用全局变量: 1.不安全 2.会一直占着内存不释放 函数多个return值,那么会把这几个return的值都放在一个元组里面,然后返回 1 def hello(a,b,c,d): 2 return a,b,c,d 3 res=hello('ybq','ede','rfv','deq') 4 print(res)#('ybq', 'ede', 'dede', 'deq') 列表推导式: 1 #列表推导式 2 nums=[0,1,3,4,5,6,

CSS的三种样式:内联式,嵌入式,外部式以及他们的优先级

从CSS 样式代码插入的形式来看基本能够分为下面3种:内联式.嵌入式和外部式三种. 1:内联式css样式表就是把css代码直接写在现有的HTML标签中,如以下代码: <p style="color:red";font-size:12px>这里文字是红色.</p> 2:嵌入式,嵌入式css样式.就是能够把css样式代码写在<style type="text/css">XXX</style>标签之间. <head&g

(一)Python入门-4控制语句:10推导式创建序列-列表推导式-字典推导式-集合推导式-生成器推导式

推导式创建序列: 推导式是从一个或者多个迭代器快速创建序列的一种方法.它可以将循环和条件判断结合, 从而避免冗长的代码.推导式是典型的Python 风格,会使用它代表你已经超过Python初 学者的水平. 一:列表推导式 列表推导式生成列表对象,语法如下: [表达式 for item in 可迭代对象 ] 或者:{表达式 for item in 可迭代对象 if 条件判断} 1 #列表推导式 2 x = [x for x in range(1,5)] 3 print(x) 4 5 x = [x*

算法学习:后缀数组 height的求取

[定义] [LCP]全名最长公共前缀,两个后缀之间的最长前缀,以下我们定义 lcp ( i , j ) 的意义是后缀 i 和 j 的最长前缀 [z函数] 函数z [ i ] 表示的是,第 i 个后缀和字符串的最长前缀  [解决问题] 这两个算法都是在解决这个问题 即求后缀和字符串和后缀之间的最长公共前缀 但是有所不同的是, 后缀数组最终求出的是,字典序第 i 个后缀和第 i + 1 个后缀的最长公共前缀 z函数最终求出的是,第 i 个后缀和字符串的最长公共前缀 然后通过这个最长公共前缀求一些其他

单例模式(懒汉式单例、饿汉式单例、登记式单例)

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建.这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象. 注意: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 介绍 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点.

poj 2752 求一个字符串所有的相同前后缀

求一个字符串所有的相同前后缀Sample Input ababcababababcababaaaaaSample Output 2 4 9 181 2 3 4 5 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <stack> 5 using namespace std; 6 7 const int N = 400010; 8 int next[N]; 9 c

求二维数组中子数组和中最大的值,及子数组

求二维数组中子数组和中最大的值,及子数组 个人信息:就读于燕大本科软件工程专业 目前大三; 本人博客:google搜索"cqs_2012"即可; 个人爱好:酷爱数据结构和算法,希望将来从事算法工作为人民作出自己的贡献; 编程语言:C++ ; 编程坏境:Windows 7 专业版 x64; 编程工具:vs2008; 制图工具:office 2010 powerpoint; 硬件信息:7G-3 笔记本; 真言 每次着急写程序,碰到问题就头疼,头疼之后便是满满的收获,付出总有回报. 题目 求

FreeRTOS——任务调度—抢占式,时间片和合作式

本章教程为大家将介绍 FreeRTOS 操作系统支持的任务调度方式:抢占式,时间片和合作式,这部分算是 FreeRTOS 操作系统的核心了. 对于初学者来说,要一下子就能够理解这些比较困难,需要多花些时间把这些基本概念搞清楚,然后阅读下源码,深入理解实现方法. 关于合作式调度器的特别说明 FreeRTOS 支持的调度方式FreeRTOS 操作系统支持三种调度方式:抢占式调度,时间片调度和合作式调度. 实际应用主要是抢占式调度和时间片调度,合作式调度用到的很少. ? 抢占式调度每个任务都有不同的优

Java实现单例模式之恶汉式、懒汉式、枚举式,带测试。

Java实现单例的3种普遍的模式,恶汉式.懒汉式.枚举式. 具体代码如下: package com.lcx.mode; /** * * 恶汉式单例,不管以后用不用这个对象,我们一开始就创建这个对象的实例, * 需要的时候就返回已创建好的实例对象,所以比较饥饿,故此叫恶汉式单例. * @author qq1013985957 * */ public class SingletonHanger { private static final SingletonHanger instance = new