java中定义的字符串操作符,如何让运算时先执行括号里的

direren 2011-01-10 10:04:48
首先从系统中获得字符串输入,&运算表示字符串连接,@表示取相应字符串中,特定字母后面的子字符串,但是希望把这些操作混合在一起,初步想到用括号,但是没有想好怎么用,例如:输入:((hell & o )&wolrd)) 输出:helloworld
输入:((hello @ l)&(a world @ a)) 输出:lo world
希望有解决办法的人,提示一下
import java.util.Scanner;
import java.io.*;

public class Interpreter
{
public static void main(String[] args)
{
System.out.println("Please Input the Command");
Scanner sc=new Scanner(System.in);
String s=sc.nextLine();
char[] c=s.toCharArray();
for(int i=0;i<c.length;i++)
{
int bracket;
if (c[i]=='(')
{
bracket=i+1;
}
System.out.print(bracket);
}
for(int i=0;i<c.length;i++)
{
//System.out.print(c[i]);

if (c[i]=='&')
{
for (int j=0; j<i; j++)
{
System.out.print(c[j]);
}
for (int j=i+1; j<c.length; j++)
{
System.out.print(c[j]);
}
}
if (c[i]=='@')
{
for (int j=0; j<i; j++)
{
if (c[j]==c[i+1])
{
for (int k=j+1; k<i; k++)
{
System.out.print(c[k]);
}
}
}
}
}
}
}
...全文
391 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
direren 2011-01-12
  • 打赏
  • 举报
回复
7楼的程序,如果需要考虑,运算符前后的空格是字符串的话,应该怎么改呢
jsut_yi 2011-01-10
  • 打赏
  • 举报
回复
可以用堆栈来实现运算优先级问题。
direren 2011-01-10
  • 打赏
  • 举报
回复
没提取出你回答中的关键字,麻烦你给个链接
yaoweijq 2011-01-10
  • 打赏
  • 举报
回复
这实际上就是表达式求值的简化版
你可以定一个& @的相对优先级别
不定也行
用括号可以满足大部分需求
然后用栈处理就行了
网上程序一堆一堆的
direren 2011-01-10
  • 打赏
  • 举报
回复
import java.util.Scanner;
import java.io.*;

public class Interpreter
{
public static void main(String[] args)
{
System.out.println("Please Input the Command");
Scanner sc=new Scanner(System.in);
String s=sc.nextLine();
char[] c=s.toCharArray();
for(int i=0;i<c.length;i++)
{
//System.out.print(c[i]);

if (c[i]=='&')
{
for (int j=0; j<i; j++)
{
System.out.print(c[j]);
}
for (int j=i+1; j<c.length; j++)
{
System.out.print(c[j]);
}
}
if (c[i]=='@')
{
for (int j=0; j<i; j++)
{
if (c[j]==c[i+1])
{
for (int k=j+1; k<i; k++)
{
System.out.print(c[k]);
}
}
}
}
}
}
}
micsolaris 2011-01-10
  • 打赏
  • 举报
回复
改成

private static String process_and(String content){
content = content.replaceAll("&","");
return content;
}
micsolaris 2011-01-10
  • 打赏
  • 举报
回复
恩,那么上面代码修改process_and()

private static String process_and(String content){
content = content.replaceAll("\\s*&\\s*","");
return content;
}

即可
direren 2011-01-10
  • 打赏
  • 举报
回复
谢谢楼上两位的帮助,太牛了,膜拜一下,是需要考虑空格为字符串的
((hello& )&world) = hello world
micsolaris 2011-01-10
  • 打赏
  • 举报
回复
而且你所给的两个例子

((hell & o )&wolrd)) 输出:helloworld
((hello @ l)&(a world @ a)) 输出:lo world

到底是否&的两边都需要有空格,像你第一个例子会自动消除空格。而第二个例子 当执行到 lo&空格world的时候又保留空格.具体的修改可以对应上面的process_and方法
micsolaris 2011-01-10
  • 打赏
  • 举报
回复

/*
首先从系统中获得字符串输入,&运算表示字符串连接,@表示取相应字符串中,特定字母后面的子字符串,但是希望把这些操作混合在一起,初步想到用括号,但是没有想好怎么用,例如:输入:((hell & o )&wolrd)) 输出:helloworld
输入:((hello @ l)&(a world @ a)) 输出:lo world
*/

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test{

public static final int PRIORITY_AND = 1; // & 优先级高
public static final int PRIORITY_AT = 2; // @ 优先级高

public static void main(String[] args){
String content = "((hello @ l)&(a world @ a))";
System.out.println(process(content,PRIORITY_AT));
}

private static String process_and(String content){
content = content.replaceAll("\\s*&\\s*","");
return content;
}

private static String process_at(String content){
//假设可以满足 abcd @ abc ABC= d ABC的情况
String regex = "(.+?)\\s+@\\s+([^\\s]+)(.*)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(content);
int index = 0;
String temp1 = null;
String temp2 = null;
while(matcher.find()){
temp1 = matcher.group(1);
temp2 = matcher.group(2);
//System.out.println("temp1:" + temp1);
index = temp1.indexOf(temp2);
//System.out.println("index:" + index);
if(index >= 0){
//如果index >= 0 那么表示group(1)中含有group(2)的内容,截取对应的后面的内容
temp1 = temp1.substring(index + temp2.length(), temp1.length());

}
//content应该是在消除了原来的@表达式后的返回

content = temp1 + matcher.group(3);

matcher = pattern.matcher(content);
}
return content;
}

private static String process1(String content,int priority){//不包含括号的情况下
content = content.replaceAll("[()]","");//此方法将处理单个括号的内容,传值进来时需要处理括号
if(priority == PRIORITY_AND){
content = process_and(content);
content = process_at(content);
}else if(priority == PRIORITY_AT){
content = process_at(content);
content = process_and(content);
}else{
System.err.println("The argument is invalid!");
throw new IllegalArgumentException("The argument of priority = " + priority + " is invalid!");
}
return content;
}

public static String process(String content,int priority){ //含括号的处理
String regex = "(.*?)(\\([^()]+\\))(.*)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
content = matcher.group(1) + process1(matcher.group(2),priority) + matcher.group(3);
matcher = pattern.matcher(content);
}
//当所有括号都去除的时候别忘记了需要处理一下最后的部分
content = process1(content,priority);
return content;
}
}
micsolaris 2011-01-10
  • 打赏
  • 举报
回复
可以考虑用正则迭代括号处理,但是需要考虑是否要考虑空格 比如 “空格 空格 @ 空格 空格 a”这样的形式是否返回空格后的内容还是a后面的内容,还有比如 "空格 空格 @ 空格 abc"是返回abc后的内容还是a后面的内容
  • 打赏
  • 举报
回复
表达式解析。先将中缀表达式转为后缀表达式,之后用这一规则进行运行:

1:初始化空栈;
2:从索引 0 开始遍历 String[]
3:如果为操作数,则将其压入栈中;
4:如果为运算符,将栈中的数弹出两次,后弹出的数与先弹出的数进行运算,将结果再压回栈中;
5:遍历完成;
6:这时栈中应该只有一个元素,将其弹出,这个元素就是计算结果。

public class Test {

public static void main(String[] args) {
String str = "((hello @ l)&(a world @ a))";
Calculator c = Calculator.getInstance();
System.out.println(c.eval(str));
}
}


import java.util.HashMap;
import java.util.Map;

/**
* 运算符
*/
public abstract class Operator {

/**
* 运算符
*/
private char operator;

/**
* 运算符的优先级别,数字越大,优先级别越高
*/
private int priority;

private static Map<Character, Operator> operators = new HashMap<Character, Operator>();

private Operator(char operator, int priority) {
setOperator(operator);
setPriority(priority);
register(this);
}

private void register(Operator operator) {
operators.put(operator.getOperator(), operator);
}

/**
* 截取运算
*/
public final static Operator ADITION = new Operator('@', 100) {
public String eval(String left, String right) {
int index = left.indexOf(right);
if(index < 0) {
return "";
}
return left.substring(index + right.length());
}
};

/**
* 连接运算
*/
public final static Operator SUBTRATION = new Operator('&', 200) {
public String eval(String left, String right) {
return left + right;
}
};

public char getOperator() {
return operator;
}
private void setOperator(char operator) {
this.operator = operator;
}
public int getPriority() {
return priority;
}
private void setPriority(int priority) {
this.priority = priority;
}

/**
* 根据某个运算符获得该运算符的优先级别
* @param c
* @return 运算符的优先级别
*/
public static int getPrority(char c) {
Operator op = operators.get(c);
if(op != null) {
return op.getPriority();
}
return 0;
}

/**
* 工具方法,判断某个字符是否是运算符
* @param c
* @return 是运算符返回 true,否则返回 false
*/
public static boolean isOperator(char c) {
return getInstance(c) != null;
}
public static boolean isOperator(String str) {
if(str.length() > 1) {
return false;
}
return isOperator(str.charAt(0));
}

/**
* 根据运算符获得 Operator 实例
* @param c
* @return 从注册中的 Operator 返回实例,尚未注册返回 null
*/
public static Operator getInstance(char c) {
return operators.get(c);
}
public static Operator getInstance(String str) {
if(str.length() > 1) {
return null;
}
return getInstance(str.charAt(0));
}

/**
* 根据操作数进行计算
* @param left 左操作数
* @param right 右操作数
* @return 计算结果
*/
public abstract String eval(String left, String right);
}


public interface Symbol {

/**
* 左括号
*/
public final static char LEFT_BRACKET = '(';

/**
* 右括号
*/
public final static char RIGHT_BRACKET = ')';

/**
* 中缀表达式中的空格,需要要忽略
*/
public final static char BLANK = ' ';

/**
* 后缀表达式的各段的分隔符
*/
public final static char SEPARATOR = '|';
}


import java.util.Stack;
import java.util.regex.Pattern;

public class Calculator implements Symbol {

private final static Calculator instance = new Calculator();

private Calculator() {
}

public static Calculator getInstance() {
return instance;
}

/**
* 计算中缀表达式
* @param expression
* @return
*/
public String eval(String expression) {
String str = infix2Suffix(expression);
// System.out.println(" Infix Expression: " + expression);
// System.out.println("Suffix Expression: " + str);
if(str == null) {
throw new IllegalArgumentException("Expression is null!");
}
String[] strs = str.split(Pattern.quote(String.valueOf(SEPARATOR)));
Stack<String> stack = new Stack<String>();
for(int i = 0; i < strs.length; i++) {
strs[i] = strs[i].trim();
if(!Operator.isOperator(strs[i])) {
stack.push(strs[i]);
} else {
Operator op = Operator.getInstance(strs[i]);
String right = stack.pop();
String left = stack.pop();
stack.push( op.eval(left, right) );
}
}
return stack.pop();
}

/**
* 将中缀表达式转换为后缀表达式
* @param expression
* @return
*/
public String infix2Suffix(String expression) {
if(expression == null) {
return null;
}
char[] chs = expression.toCharArray();
Stack<Character> stack = new Stack<Character>();
StringBuilder sb = new StringBuilder(chs.length);
boolean appendSeparator = false;
for(int i = 0; i < chs.length; i++) {
char c = chs[i];
if(appendSeparator) {
sb.append(SEPARATOR);
appendSeparator = false;
}
if(isLeftBracket(c)) {
stack.push(c);
continue;
}
if(isRightBracket(c)) {
while(stack.peek() != LEFT_BRACKET) {
sb.append(SEPARATOR);
sb.append(stack.pop());
}
stack.pop();
continue;
}
if(!Operator.isOperator(c)) {
sb.append(c);
continue;
}
appendSeparator = true;
if(Operator.isOperator(c)) {
if(stack.isEmpty() || stack.peek() == LEFT_BRACKET) {
stack.push(c);
continue;
}
int precedence = Operator.getPrority(c);
while(!stack.isEmpty() && Operator.getPrority(stack.peek()) >= precedence) {
sb.append(SEPARATOR);
sb.append(stack.pop());
}
stack.push(c);
}
}
while(!stack.isEmpty()) {
sb.append(SEPARATOR);
sb.append(stack.pop());
}
return sb.toString();
}

/**
* 判断某个字符是否为左括号
* @param c
* @return
*/
private boolean isLeftBracket(char c) {
return c == LEFT_BRACKET;
}

/**
* 判断某个字符是否为右括号
* @param c
* @return
*/
private boolean isRightBracket(char c) {
return c == RIGHT_BRACKET;
}
}
  • 打赏
  • 举报
回复
@ 优先级高,还是 & 优先级高?

另外,运算符前后的空格算是字符串中的么?
direren 2011-01-10
  • 打赏
  • 举报
回复
谁能给出一些代码

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧