AKB Forums

Go Back   AKB Forums > Technical sections > Algorithms
Home Register Blogs FAQ Members List Calendar Downloads Arcade Mark Forums Read

Algorithms The source of algorithms for your project

Troubles when posting message? Click here! :: Проблемы с отправлением сообщения? Нажмите сюда!

Reply
 
LinkBack Thread Tools Display Modes
Old May 1, 2002, 01:07   #1
Administrator
 
acid's Avatar
 
Join Date: Sep 2001
Location: South Korea, Gumi
Posts: 7,189
Blog Entries: 15
Rep Power: 10
Reputation: 313
Post Обpатная польская нотация

(Alexey Olkhovsky aolkhov@messages.to)

Использyется для вычисления аpифметических выpажений. Для пеpевода в нее необходим стек аpифметических опеpаций.

Алгоpитм пеpевода пpоизвольного выpажения в ОПН очень пpост: Выpажение сканиpyется слева напpаво, пpи этом pазбиваясь на токены - числа и знаки аpифметических опеpаций. Если очеpедной токен - число, не глядя пишем его в выходнyю стpокy. Иначе, выталкиваем из стека и пишем в выходнyю стpокy все опеpации с пpиоpитетом выше текyщей, а самy опеpацию пихаем в стек. Левая скобка всегда пишется в стек (ее пpиоpитет - самый низкий). Пpавая скобка выталкивает из стека все опеpации вплоть до левой скобки включительно, сама она в стек не пишется. Когда достигнyт конец входного выpажения, пpосто выталкиваем из стека все что в нем есть.

Пpимеp: (2+3)*4+5

левая скобка - пихаем в стек
2 - пишем в выходнyю стpокy
+ - стек пyст, поэтомy ничего не достаем, а напpотив, пихаем плюс
3 - пишем в выходнyю стpокy
пpавая скобка - выталкиваем плюс и левyю скобкy
* - стек снова пyст, пихаем yмножение
4 - пишем в выходнyю стpокy
+ - пpиоpитет yмножения - выше, поэтомy его достаем, а плюс - пихаем
5 - пишем в выходнyю стpокy
EOF - достаем из стека плюс

Имеем: 2 3 + 4 * 5 +

Обpати внимание на следyющее:

- Вместо записи в выходнyю стpокy можно тyт же вычислять выpажение, для этого необходим еще один стек (почемy - сообpази сам)

- Если выталкивать из стека опеpации с пpиоpитетом выше или pавным текyщемy, то выполнение опеpаций с одинаковым пpиоpитетом бyдет пpоизводиться слева напpаво, т.е. как все мы пpивыкли, да и его глyбина yменьшиться (хоть это и не кpитично)

- Скобки в выходнyю стpокy не пишyтся, так как их пpиоpитет yчитывается автоматически; однако их баланс легко пpовеpяется.
__________________
Chat with acid


acid is offline   Reply With Quote Quote selected
Old May 1, 2002, 03:32   #2
Главный инспектор снов
 
Dream_InspectoR's Avatar
 
Join Date: Jan 2002
Location: Yerevan, Armenia
Posts: 330
Rep Power: 7
Reputation: 10
Send a message via ICQ to Dream_InspectoR
Thumbs up

Eto nazywaetsja preobrazowanie infixnoj stroki w postfixnuju formu. Podrobnosti na http://freenet.am/~id Tam nashi lekcii po structuram dannyx s primerami na armjanskom jazyke.
__________________
Kill'em!!! Kill'em all!!!
Dream_InspectoR is offline   Reply With Quote Quote selected
Old May 1, 2002, 11:44   #3
Дошкольник
 
Dark Abyss of Yerevan's Avatar
 
Join Date: Jan 2002
Location: hell
Posts: 124
Rep Power: 7
Reputation: 10
Send a message via ICQ to Dark Abyss of Yerevan
Post

vot vam source na cpp.
Code:
 
/*
  -----------------------------------------------------------------------------
    Infix,postfix and prefix expressions. (c) 2002 Artashes Aghajanyan. 
    Last modified : Fri Jan 18 21:39:46 2002
    
    Yerevan State University, Department of Applied Mathematics.
  _____________________________________________________________________________
*/


#include <iostream.h>

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++ stack implementation */
struct node {					// stack node
	int info;
	node *next;
};

class stack {
    node *ptr;					// points to the stack
public:
    stack();					// constructor
    int is_empty();				// boolean
    void push(int);
    int pop();
    void dump();				// print stack contents
    void empty();				// clean the stack
};

stack::stack(){					// constructor
    ptr=NULL;
}

void stack::push(int a){
    node *p;
    p=new node;
    p->info=a;
    p->next=ptr;
    ptr=p;
};

int stack::pop(){
    int t;
    node *p;

    t=ptr->info;
    p=ptr;
    ptr=ptr->next;
    delete p;
    return t;
};
int stack::is_empty(){
    return (ptr==NULL)?1:0;
};

void stack::empty(){
    while (!is_empty())pop();
};

void stack::dump(){
    cout << &quot;dumping the stack\n&quot;;
    node * p=ptr;
    while (p!=NULL){
	cout << p->info <<' ';
	p=p->next;
    };
    cout <<'\n';
};



/*+++++++++++++++++++++++++++++++++++++++++++++++++ end stack implementation */


/*++++++++++++++++++++++++++++++++++++++++++++++++ expression implementation */

struct e_node {					// node for expression
    int type;
    char info;
};

class expression {				// 
    stack s;					// temporary stack
    e_node *x,*y;				// x for infix,y for postfix
    int n,m;					// infix,postfix length
    void make_postfix();			// create postfix expression
    void make_infix();
    int priority(char);				// returns operator priority
    int read_value(char);			// reads from standart input
    
public:
    expression(const char *);			// constructor
    char *postfix();				// returns postfix (string)
    int calculate();				// returns expression value(int)
};

expression::expression(const char * e){

    n=strlen(e);
    x=new e_node[n];				// allocate x and y
    y=new e_node[n];
    
    for (int i=1;i<=n;i++){			// set x vector
	x[i].info=e[i-1];
	switch (e[i-1]) {
	    case ')':
		x[i].type=4;break;
	    case '(':
		x[i].type=3;break;
	    case '+':case '-':case '*':case '/':case '^':
		x[i].type=2;break;
	    case '0':case '1':case '2':case '3':case '4':
	    case '5':case '6':case '7':case '8':case '9':
		x[i].type=0;break;	
	    default: x[i].type=1;
	};					// end switch
	
	cout << x[i].info << &quot; (&quot;<< x[i].type<<&quot;)\n&quot;;
    };						// end for

    make_postfix();

};

char * expression::postfix(){
    char *c=new char[m];
    for(int i=1;i<=m;i++)c[i-1]=y[i].info;
    c[m]='\0';
    return c;
};


int expression::priority(char c){
    switch (c) {
	case '-':case '+':
	    return 1;
	case '*':case '/':
	    return 2;
	case '^':
	    return 3;
    };

};

int expression::read_value(char c){
    int x;
    cout << &quot;\nEnter the value of '&quot;<<c<<&quot;' :&quot;;
    cin >> x;
    return x;
};

int expression::calculate(){
    
    s.empty();					// clean the stack
    for (int j=1;j<=m;j++){
	switch (y[j].type){
	    case 0:case 1:
		if (!y[j].type) s.push(int(y[j].info)-int('0'));
		else s.push(read_value(y[j].info));
	    break;
	    
	    case 2:
		s.dump();cout <<&quot;dumped!!\n&quot;;
		int argm2,argm1,res;
		argm2=s.pop();
		argm1=s.pop();
		switch (y[j].info){
		    case '+':
			res=argm1+argm2;
		    break;
		    case '-':
			res=argm1-argm2;
		    break;
		    case '*':
			res=argm1*argm2;
		    break;
		    case '/':
			res=argm1/argm2;
		    break;
		    case '^':
			res=1;
			for (int l=1;l<=argm2;l++)res*=argm1;
		    break;
		};				// end switch (y[j].info)
		s.push(res);
	    break;
	};					// end switch (y[j].type)
    };						// end for
    return s.pop();
};						// end expression::calculate()



void expression::make_postfix(){
    
    int j=0;
    for (int i=1; i<=n;i++){			// H2
        switch (x[i].type){
	    case 0:case 1:			// H3
		j++;y[j]=x[i];
	    break;

	    case 2:				// H4
		while (!s.is_empty()){
		    int k=s.pop();
		    if ( (x[k].type==2) && 
			(priority(x[k].info)>=priority(x[i].info)) ){
			j++;y[j]=x[k];
		    } 				// end if
		    else {
			s.push(k);
			break;			// break from while
		    };				// end else
		};				// end while
		s.push(i);
	    break;

	    case 3:				// H5
		s.push(i);
	    break;

	    case 4:				// H6
		int k=s.pop();
		while (x[k].type!=3){
		    j++;
		    y[j]=x[k];
		    k=s.pop();
		};
	    break;
	};					// end switch

    };						// end for

    while (!s.is_empty()){			// H7 stack cleanup
        int k=s.pop();
        j++;
        y[j]=x[k];	
    };
    m=j;

};
/*++++++++++++++++++++++++++++++++++++++++++++ end expression implementation */



void main() {
    int	i=0;

    stack st;
    //for (i=0;i<100;i++)st.push(i);
    //st.dump();
    expression e(&quot;(a-b)*2^(c+1)&quot;);
    cout << e.postfix()<<&quot;\n&quot;;
    cout << e.calculate()<<&quot;\n&quot;;
    

}
__________________
[x]-=-[ ]-=-[x]
Dark Abyss of Yerevan is offline   Reply With Quote Quote selected
Old May 2, 2002, 16:22   #4
Дошкольник
 
Join Date: Feb 2002
Location: found. AT labs.
Posts: 69
Rep Power: 0
Reputation: 10
Send a message via ICQ to Mr. M
Talking

Artash, loool
pomnish' ty poslal mne??
ya modificiroval ETO do tex por poka ne ponyal chto nado polnostyu perepisyvat'...
leksicheskiy analiztor trudno vpixivat' + produkctions are hardcoded...
kstati, vse-taki kompiliruetsya, i vse to je delaet..
esli xochesh' mogu obratno poslat'
Mr. M is offline   Reply With Quote Quote selected
Old May 3, 2002, 11:07   #5
Дошкольник
 
Dark Abyss of Yerevan's Avatar
 
Join Date: Jan 2002
Location: hell
Posts: 124
Rep Power: 7
Reputation: 10
Send a message via ICQ to Dark Abyss of Yerevan
Post

Да, хочу
Насчет hardcoded согласен. Дело в том что алгоритм мы сами не придумывали.
Нам просто был задан алгоритм ( в комментах - H1-H6 ), и мы должны были написать
имплементацию на C++. А что такое лексический/синтаксический анализ, я узнал только в этом семестре
__________________
[x]-=-[ ]-=-[x]
Dark Abyss of Yerevan is offline   Reply With Quote Quote selected
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT. The time now is 16:11.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
This board was founded on September 29, 2001
Powered by Viper Internet

Affordable Web Hosting | ParevNet

Buy text link