小弟拜求

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小弟拜求相关的知识,希望对你有一定的参考价值。

我是个软件学生,求C语言版的表达式求值的程序,用栈实现!
原理基本用一个运算符栈,一个操作数栈分别存储表达式的运算符和数值,实现输入任意简单表达式都可求值的目的!
本来我也是筐架都想好的可到具体编程时就力不从心了!
请那位大哥不吝指教!编不出来着急啊!!!!
哥哥姐姐们一定注意 ,我刚学C,所以一定要C版语言的!
其它的你就是难为俺了!

参考技术A 汇编 ;
data segment
inputhint db 13,10,"Please input the expression to calculate:",13,10,'$'
errorInputMsg db 13,10,"Illeagle input.",13,10,'$'
errorTwoOperator db 13,10,"There are two operator adjacent!",13,10,'$'
errorFirstChar db 13,10,"The first character must be '(','+','-',or a digit.",13,10,'$'
opStack db 256 dup(0) ; operator stack
infix db 512 dup(0) ; infix expression stack
chLast db -1 ; the character that is reat last time.
dataStack dw 256 dup(0) ; data stack
data ends

code segment
assume cs:code, ds:data
main proc far
mov ax, data
mov ds, ax
mov ah, 9
lea dx, inputhint
int 21h

call input
call calculate
call print

mov ah, 4ch
int 21h
input proc near
push ax
push bx
lea bx, infix
input_exp: mov ah, 1
int 21h
cmp al, '=' ;输入等号或者回车都会使得输入结束
je exit_input
cmp al, 13
je exit_input
call inputCheck ;is the character illegal?
mov [bx], al
inc bx
jmp input_exp
exit_input: mov byte ptr [bx], '='
pop bx
pop ax
ret
input endp
calculate proc near ;计算中缀表达式函数
push ax ; ax -- 计算结果累加器
push cx ; ch -- 运算符栈顶元素, compute 函数的入口参数之一
push dx ; cl -- 当前从中缀表达式中读入的元素
push bx ; bx -- opStack 栈顶指针
push di ; di -- dataStack 栈顶指针
push si ; si -- 中缀表达式下标
mov bx, -1
mov si, -1
mov di, -2
analyze: inc si ;读入待分析字符, 存入在CL寄存器中
mov cl, byte ptr infix[si]
cmp cl, '='
je case_exit
cmp cl, '('
je case_left
cmp cl, ')'
je case_right
cmp cl, '+'
je case_add
cmp cl, '-'
je case_sub
cmp cl, '*'
je case_mul
cmp cl, '/'
je case_div
jmp case_data
case_exit: jmp exit_calculate
case_left: jmp left
case_right: jmp right
case_add: jmp addsub
case_sub: jmp addsub
case_mul: jmp muldiv
case_div: jmp muldiv
case_data: jmp read_data
left: inc bx
mov byte ptr opStack[bx], '('
mov chLast, '('
jmp analyze
right: mov cl, byte ptr opStack[bx]
dec bx
cmp cl, '('
je analyze
mov ch, cl
call compute
jmp right
addsub: cmp chLast, -1
jz push_data_0
cmp chLast, '('
jz push_data_0
cmp chLast, '+'
jz errTwoOperator
cmp chLast, '-'
jz errTwoOperator
cmp chLast, '*'
jz errTwoOperator
cmp chLast, '/'
jz errTwoOperator
jmp push_cl
push_data_0: add di, 2
mov word ptr dataStack[di], 0
push_cl: cmp bx, -1 ; is opStack empty ?
jz push_cl_direct
mov ch, byte ptr opStack[bx]
cmp ch, '(' ; the top of opStack is '(' ?
jz push_cl_direct
mov byte ptr opStack[bx], cl
call compute
mov chLast, cl
jmp analyze
push_cl_direct: inc bx
mov byte ptr opStack[bx], cl
mov chLast, cl
jmp analyze
errTwoOperator: lea dx, errorTwoOperator
mov ah, 9
int 21h
mov ah, 4ch
int 21h
muldiv: cmp chLast, -1
jz errFirstChar
cmp chLast, '+'
jz errTwoOperator
cmp chLast, '-'
jz errTwoOperator
cmp chLast, '*'
jz errTwoOperator
cmp chLast, '/'
jz errTwoOperator
cmp chLast, '('
jz errFirstchar
jmp muldiv_x
errFirstChar: lea dx, errorFirstChar
mov ah, 9
int 21h
mov ah, 4ch
int 21h
muldiv_x: cmp bx, -1 ; is stack empty ?
je push_muldiv
mov ch, byte ptr opStack[bx] ;peek the element on the top
cmp ch, '*'
je comp_muldiv
cmp ch, '/'
je comp_muldiv
jmp push_muldiv ; the top is neither '*' nor '/', push cl directly
comp_muldiv: mov byte ptr opStack[bx], cl ; replace
call compute
mov chLast, cl
jmp analyze
push_muldiv: inc bx
mov byte ptr opStack[bx], cl
mov chLast, cl
jmp analyze
read_data: xor ax, ax
read: add ax, ax ; use add, never use adc
mov dx, ax
add ax, ax
add ax, ax
add ax, dx
and cx, 0fh
add ax, cx
inc si
mov cl, byte ptr infix[si]
cmp cl, '0'
jc finish_read
cmp cl, 3ah
jnc finish_read
jmp read
finish_read: add di, 2
mov word ptr dataStack[di], ax
dec si
mov chLast, '2'
jmp analyze
pre_exit_calculate: mov ch, byte ptr opStack[bx]
dec bx
call compute ; no jump, just fall down
exit_calculate: cmp bx, -1 ; is operator stack empty ?
jne pre_exit_calculate
pop si
pop di
pop bx
pop dx
pop cx
pop ax
ret
calculate endp
compute proc near ;用来计算每一步结果,两个入参:ch-运算符,di-数据栈顶指针
push ax
push dx
cmp di, 2
jc exit_compute
mov dx, word ptr dataStack[di] ; the second operator
sub di, 2
mov ax, word ptr dataStack[di] ; the first operator
sub di, 2
and ax, ax ; set cf = 0
cmp ch, '+'
je addf
cmp ch, '-'
je subf
cmp ch, '*'
je mulf
cmp ch, '/'
je divf
addf: adc ax, dx
jmp finish_c
subf: sbb ax, dx
jmp finish_c
mulf: imul dx
jmp finish_c
divf: idiv dx
jmp finish_c
finish_c: add di, 2
mov word ptr dataStack[di], ax
exit_compute: pop dx
pop ax
ret
compute endp
print proc near ;输出结果函数
push ax
push cx
push dx
mov cx, word ptr dataStack
test cx, 8000h ;是否为负数
jnz negative
begin: cmp cx, 10000
jnc ten_thousand
cmp cx, 1000
jnc thousand
cmp cx, 100
jnc handred
cmp cx, 10
jnc ten
jmp remains
negative: mov dl, '-'
mov ah, 2
int 21h
neg cx
jmp begin
ten_thousand: mov dl, -1
a: sub cx, 10000
inc dl
jnc a
add cx, 10000
or dl, 30h
mov ah, 2
int 21h
thousand: mov dl, -1
b: sub cx, 1000
inc dl
jnc b
add cx, 1000
or dl, 30h
mov ah, 2
int 21h
handred: mov dl, -1
cc: sub cx, 100
inc dl
jnc cc
add cx, 100
or dl, 30h
mov ah, 2
int 21h
ten: mov dl, -1
d: sub cx, 10
inc dl
jnc d
add cx, 10
or dl, 30h
mov ah, 2
int 21h
remains: mov dl, cl
or dl, 30h
mov ah, 2
int 21h
exit_print: pop dx
pop cx
pop ax
ret
print endp
inputCheck proc near
push dx
cmp al, '+'
je exit_success
cmp al, '-'
je exit_success
cmp al, '*'
je exit_success
cmp al, '/'
je exit_success
cmp al, '('
je exit_success
cmp al, ')'
je exit_success
cmp al, '0'
jc exit_failure
cmp al, 3ah
jnc exit_failure
jmp exit_success
exit_failure: lea dx, errorInputMsg
mov ah, 9
int 21h
mov ah, 4ch
int 21h
exit_success: pop dx
ret
inputCheck endp
main endp
code ends
end main

c++
栈的应用很广泛,原书只讲解了表达式求值,那我也就只写这些。其实,栈的最大的用途是解决回溯问题,这也包含了消解递归;而当你用栈解决回溯问题成了习惯的时候,你就很少想到用递归了,比如迷宫求解。另外,人的习惯也是先入为主的,比如树的遍历,从学的那天开始,就是递归算法,虽然书上也教了用栈实现的方法,但应用的时候,你首先想到的还是递归;当然了,如果语言本身不支持递归(如BASIC),那栈就是唯一的选择了——好像现在的高级语言都是支持递归的。

如下是表达式类的定义和实现,表达式可以是中缀表示也可以是后缀表示,用头节点数据域里的type区分,这里有一点说明的是,由于单链表的赋值函数,我原来写的时候没有复制头节点的内容,所以,要是在两个表达式之间赋值,头节点里存的信息就丢了。你可以改写单链表的赋值函数来解决这个隐患,或者你根本不不在两个表达式之间赋值也行。

#ifndef Expression_H

#define Expression_H

#include "List.h"

#include "Stack.h"

#define INFIX 0

#define POSTFIX 1

#define OPND 4

#define OPTR 8

template <class Type> class ExpNode



public:

int type;

union Type opnd; char optr;;

ExpNode() : type(INFIX), optr('=')

ExpNode(Type opnd) : type(OPND), opnd(opnd)

ExpNode(char optr) : type(OPTR), optr(optr)

;

template <class Type> class Expression : List<ExpNode<Type> >



public:

void Input()



MakeEmpty(); Get()->type =INFIX;

cout << endl << "输入表达式,以=结束输入" << endl;

Type opnd; char optr = ' ';

while (optr != '=')



cin >> opnd;

if (opnd != 0)



ExpNode<Type> newopnd(opnd);

LastInsert(newopnd);



cin >> optr;

ExpNode<Type> newoptr(optr);

LastInsert(newoptr);





void Print()



First();

cout << endl;

for (ExpNode<Type> *p = Next(); p != NULL; p = Next() )



switch (p->type)



case OPND:

cout << p->opnd; break;

case OPTR:

cout << p->optr; break;

default: break;



cout << ' ';



cout << endl;



Expression & Postfix() //将中缀表达式转变为后缀表达式



First();

if (Get()->type == POSTFIX) return *this;

Stack<char> s; s.Push('=');

Expression temp;

ExpNode<Type> *p = Next();

while (p != NULL)



switch (p->type)



case OPND:

temp.LastInsert(*p); p = Next(); break;

case OPTR:

while (isp(s.GetTop()) > icp(p->optr) )



ExpNode<Type> newoptr(s.Pop());

temp.LastInsert(newoptr);



if (isp(s.GetTop()) == icp(p->optr) )



s.Pop(); p =Next(); break;



s.Push(p->optr); p = Next(); break;

default: break;





*this = temp;

pGetFirst()->data.type = POSTFIX;

return *this;



Type Calculate()



Expression temp = *this;

if (pGetFirst()->data.type != POSTFIX) temp.Postfix();

Stack<Type> s; Type left, right;

for (ExpNode<Type> *p = temp.Next(); p != NULL; p = temp.Next())



switch (p->type)



case OPND:

s.Push(p->opnd); break;

case OPTR:

right = s.Pop(); left = s.Pop();

switch (p->optr)



case '+': s.Push(left + right); break;

case '-': s.Push(left - right); break;

case '*': s.Push(left * right); break;

case '/': if (right != 0) s.Push(left/right); else return 0; break;

// case '%': if (right != 0) s.Push(left%right); else return 0; break;

// case '^': s.Push(Power(left, right)); break;

default: break;



default: break;





return s.Pop();



private:

int isp(char optr)



switch (optr)



case '=': return 0;

case '(': return 1;

case '^': return 7;

case '*': return 5;

case '/': return 5;

case '%': return 5;

case '+': return 3;

case '-': return 3;

case ')': return 8;

default: return 0;





int icp(char optr)



switch (optr)



case '=': return 0;

case '(': return 8;

case '^': return 6;

case '*': return 4;

case '/': return 4;

case '%': return 4;

case '+': return 2;

case '-': return 2;

case ')': return 1;

default: return 0;





;

#endif

愤怒的孙小弟

Hello,大家好,欢迎再次来到西瓜编程课,我是勺之己·饭皮大哈必胜,今天我们要做一个超好玩的游戏——愤怒的孙小弟

 

游戏效果:

1.用孙小弟的身体去撞击怪物,如果碰到怪物,那么获胜,如果碰到火焰弹,那么失败如果什么都没有碰到,那么不输不赢

2.装一个开玩按钮,点击后开始游戏

 

 

首先,添加背景AngrySunXiaoDi

技术分享图片

接着添加角色:

技术分享图片

我们首先让孙小弟动起来,这次的代码有点多哦:添加变量:ACC,power,wind。添加广播:win,gameover,start,secondstart。我们想让角色们在start是删除克隆体初始化,在second start时执行。

这是start部分:

 技术分享图片

 

这是second start:

技术分享图片

技术分享图片

接着,我们来编写flying的代码:

技术分享图片

missile是攻击孙小弟的:

技术分享图片

哦,接下来我们来完成,风。

技术分享图片

Replay也很难完成,需要用到很多知识。

技术分享图片

这是gameover的代码

技术分享图片

接着,我们要做一个很重要的部分,判断输赢,所有角色的代码都在这里:

孙小弟:                                              flying:              missile:                           Replay:

技术分享图片技术分享图片       技术分享图片          技术分享图片      技术分享图片

gameover:

技术分享图片

注意:孙小弟的录音1里面录: 终于找到你了。

 

 

谢谢大家

 




以上是关于小弟拜求的主要内容,如果未能解决你的问题,请参考以下文章

拜求高手帮解决qq.dll问题

为啥我的eclipse每次要开机后要重新写workbench的路径 拜求高手解答!!!!!!!!!!!!!!!

联想乐pad S1怎么安装12306订票网站的SRCA根证书,拜求大虾解答!!!!!

拜求我电脑安装 Management Studio 2008,但安装的时间久了,SQL Server的用户名和密码都忘啦,该如何解决

求java大神帮我看看 小弟跪求 QAQ

各位大神,小弟启动访问Maven项目时报了如下错误,有知道啥原因额嘛