導航:首頁 > 源碼編譯 > 堆棧計算器演算法

堆棧計算器演算法

發布時間:2023-03-19 15:56:28

『壹』 c++堆棧實現計算器,一位整數的我會,主要是雙精度數和多位整數咋實現啊最好給一下思想,謝謝!

你問的不太明確啊, 是說把數學表達式中的數和運算埋行符轉換為前序表達式,然後存進堆棧嗎?
回答1:這和幾位整數沒啥關系吧,一位、兩位、三位都是整數……

回答2:難道你的慶則堆棧不能存多位整數和浮點數嗎?如果不能,改寫堆棧讓它能存double。入棧的時候將整數強制轉換為double。
整彎差嘩數都會了,雙精度還遠嗎?祝你早日成功

『貳』 幫我講解一下基於堆棧的計算器怎麼工作。謝謝

堆,主要是把東西保存裡面然後去做另一件敏碧事情。當事情做完以後出缺晌堆棧。。然後再完成他本來的工作橋扮舉。就是這樣的。

『叄』 用棧來實現表達式求值

include <malloc.h>
#include <stdio.h>
#include <ctype.h>//判斷是否為字元的函數的頭文件
#define maxsize 100

typedef int elemtype;
typedef struct sqstack sqstack;//由於sqstack不是一個類型 而struct sqstack才是

char ch[7]=;//把符號轉換成一個字正槐符數組
int f1[7]=;//棧內元素優舉唯友先級
int f2[7]=;//棧外的元素優先順序

struct sqstack
{
elemtype stack[maxsize];
int top;
};

void Initstack(sqstack *s)
{
s->top=0;
}

void Push(sqstack *s,elemtype x)
{
if(s->top==maxsize-1)
printf("Overflow\n");
else
{
s->top++;
s->stack[s->top]=x;
}
}

void Pop(sqstack *s,elemtype *x)
{
if(s->top==0)
printf("underflow\n");
else
{
*x=s->stack[s->top];
s->top--;
}
}

elemtype Gettop(sqstack s)
{
if(s.top==0)
{
printf("underflow\n");
return 0;
}
else
return s.stack[s.top];
}

elemtype f(char c)
{
switch(c)
{
case '+':
return 0;
case '-':
return 1;
case '*':
return 2;
case '/':
return 3;
case '(':
return 4;
case ')':
return 5;
default:
return 6;
}
}

char precede(char c1,char c2)
{
int i1=f(c1);
int i2=f(c2);//把字元變成數字
if(f1[i1]>f2[i2])//通過原來設定找到優先順序
return '>';
else if(f1[i1]<f2[i2])
return '<';
else
return '=';
}

int Operate(elemtype a,elemtype theta,elemtype b)
{
int sum;
switch(theta)
{
case 0:
sum=a+b;
break;
case 1:
sum=a-b;
break;
case 2:
sum=a*b;
break;
default:
sum=a/b;
}
return sum;
}

EvaluateExpression()
{
char c;
int i=0,sum=0;
int k=1,j=1;//設置了開關變數
elemtype x,theta,a,b;
sqstack OPTR,OPND;
Initstack(&OPTR);
Push(&OPTR,f('#'));//0壓入棧
Initstack(&OPND);
c=getchar();
if(c==ch[2]||c==ch[3]||c==ch[5]||c==ch[6])//先對+和-的情況忽略和左括弧的情況
{
printf("錯誤1 \n");
k=0;
return 0;
}

if(c==ch[0])
c=getchar();//如果是+,把它覆蓋
if(c==ch[1])
{
j=0;
c=getchar();//也把-號覆蓋
}
while(c!='#'||ch[Gettop(OPTR)]!='#')
{
if(isdigit(c))
{
sum=0;
while(isdigit(c))
{
if(!j)
{
sum=sum*10-(c-'0');//實現山悶了數字串前面有負號(之前是:sum=-(sum*10)-(c-'0')結果是-12+13=21)
}
else
sum=sum*10+(c-'0');
c=getchar();
}
Push(&OPND,sum);//如果還是數字先不壓棧,把數字串轉化成十進制數字再壓棧
j=1;
}
else
if(k)
{
switch(precede(ch[Gettop(OPTR)],c))
{
case'<': Push(&OPTR,f(c));//把它們整型化
c=getchar();
if(c==ch[0]||c==ch[1]||c==ch[2]||c==ch[3]||c==ch[5]||c=='\n')//要除去下個是『(』的情況 也把以運算符歸到這里來
{
printf("出錯2\n");
k=0;
return 0;//加了開關變數和返回0的值使程序更以操作
}

break;
case'=': Pop(&OPTR,&x);
c=getchar();
if(c==ch[0]||c==ch[1]||c==ch[2]||c==ch[3]||c==ch[5]||c=='\n')//把ch[6]的情況也忽略了但此時並沒有注意到右括弧後面右運算符的情況
{
printf("出錯2\n");
k=0;
return 0;
}

break;
case'>': Pop(&OPTR,&theta);
Pop(&OPND,&b);
Pop(&OPND,&a);//注意這里是誰先出棧
Push(&OPND,Operate(a,theta,b));
break;
}
}
}//在這里判斷是否以運算符結束是不對的

return(Gettop(OPND));
}

main()
{
int result;
printf("輸入你的算術表達式:\n");
result=EvaluateExpression();
printf("結果是 :%d\n",result);
return 0;
}

:
本計算器利用堆棧來實現。
1、定義後綴式計算器的堆棧結構
因為需要存儲的單元不多,這里使用順序棧,即用一維數組來模擬堆棧:
#define MAX 100
int stack[MAX];
int top=0;
因此程序中定義了長度為MAX的一維數組,這里MAX用宏定義為常數100,我們可以修改宏定義而重新定義堆棧的大小。
整型數據top為棧頂指示,由於程序開始時堆棧中並無任何數據元素,因此top被初始化為0。
2、存儲後綴式計算器的運算數
我們定義了堆棧stack[MAX]後,就可以利用入棧操作存儲先後輸入的兩個運算數。
下面看一下是如何實現的:
int push(int i) /*存儲運算數,入棧操作*/
{
if(top<MAX)
{
stack[++top]=i; /*堆棧仍有空間,棧頂指示上移一個位置*/
return 0;
}
else /*堆棧已滿,給出錯誤信息,返回出錯指示*/
{
printf("The stack is full");
return ERR;
}
}
我們在調用函數push時,如果它的返回值為0,說明入棧操作成功;否則,若返回值為ERR(在程序中說明為-1),說明入棧操作失敗。
3、從堆棧中取出運算數
當程序中讀完了四則運算符後,我們就可以從堆棧中取出已經存入的兩個運算數,構成表達式,計算出結果。取出運算數的函數採用的正是出棧演算法。在本例中,實現該演算法的函數 為pop():
int pop(); /*取出運算數,出棧操作*/
{
int var; /*定義待返回的棧頂元素*/
if(top!=NULL) /*堆棧中仍有數據元素*/
{
var=stack[top--]; /*堆棧指示下移一個位置*/
return var;
}
else /*堆棧為空,給出錯誤信息,並返回出錯返回值*/
printf("The stack is cmpty!\n");
return ERR;
}
同樣,如果堆棧不為空,pop()函數返回堆棧頂端的數據元素,否則,給出棧空提示,並返回錯誤返回值ERR。
4、設計完整的後綴式計算器
有了堆棧存儲運算數,後綴式計算器的設計就很簡單了。程序首先提示用戶輸入第一個運算數,調用push()函數存入堆棧中;而後提示用戶輸入第二個運算數,同樣調用push()函數存入堆棧中。接下來,程序提示用戶輸入+,-,*,/四種運算符的一種,程序通過switch_case結構判斷輸入運算符的種類,轉而執行不同的處理代碼。以除法為例,說明程序的執行流程:
case '/':
b=pop();
a=pop();
c=a/b;
printf("\n\nThe result is %d\n",c);
printf("\n");
break;
程序判斷用戶輸入的是除號後,就執行上述代碼。首先接連兩次調用pop()函數從堆棧中讀出先前輸入的運算數,存入整型數a和b中;然後執行除法運算,結果存入單元c中。這時需要考慮究竟誰是被除數,誰是除數。由於開始我們先將被除數入棧,根據堆棧「先進後出」的原則,被除數應該是第二次調用pop()函數得到的返回值。而除數則是第一次調用pop()函數得到的返回值。
最後程序列印出運算結果,並示提示用戶是否繼續運行程序:
printf("\t Continue?(y/n):");
l=getche();
if(l=='n')
exit(0);
如果用戶回答是"n",那麼結束程序,否則繼續循環。

完整的程序代碼如下:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define ERR -1
#define MAX 100 /*定義堆棧的大小*/
int stack[MAX]; /*用一維數組定義堆棧*/
int top=0; /*定義堆棧指示*/

int push(int i) /*存儲運算數,入棧操作*/
{
if(top<MAX)
{
stack[++top]=i; /*堆棧仍有空間,棧頂指示上移一個位置*/
return 0;
}
else
{
printf("The stack is full");
return ERR;
}
}
int pop() /*取出運算數,出棧操作*/
{
int var; /*定義待返回的棧頂元素*/
if(top!=NULL) /*堆棧中仍有元素*/
{
var=stack[top--]; /*堆棧指示下移一個位置*/
return var; /*返回棧頂元素*/
}
else
printf("The stack is empty!\n");
return ERR;
}
void main()
{
int m,n;
char l;
int a,b,c;
int k;
do{
printf("\tAriothmatic Operate simulator\n"); /*給出提示信息*/
printf("\n\tPlease input first number:"); /*輸入第一個運算數*/
scanf("%d",&m);
push(m); /*第一個運算數入棧*/
printf("\n\tPlease input second number:"); /*輸入第二個運算數*/
scanf("%d",&n);
push(n); /*第二個運算數入棧*/
printf("\n\tChoose operator(+/-/*//):");
l=getche(); /*輸入運算符*/
switch(l) /*判斷運算符,轉而執行相應代碼*/
{
case '+':
b=pop();
a=pop();
c=a+b;
printf("\n\n\tThe result is %d\n",c);
printf("\n");
break;
case '-':
b=pop();
a=pop();
c=a-b;
printf("\n\n\tThe result is %d\n",c);
printf("\n");
break;
case '*':
b=pop();
a=pop();
c=a*b;
printf("\n\n\tThe result is %d\n",c);
printf("\n");
break;
case '/':
b=pop();
a=pop();
c=a/b;
printf("\n\n\tThe result is %d\n",c);
printf("\n");
break;
}
printf("\tContinue?(y/n):"); /*提示用戶是否結束程序*/
l=getche();
if(l=='n')
exit(0);
}while(1);
}

:
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;

#define STACK_INIT_SIZE 100 //初始分配量
#define STACKINCREMENT 10 //存儲空間的分配增量

typedef char ElemType;
typedef ElemType OperandType; //操作數
typedef char OperatorType;

typedef struct
{
ElemType *base;
ElemType *top;
int stacksize;
}SqStack;

Status InitStack(SqStack &S)
{
//構造一個空棧S
S.base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
if(!S.base) exit (OVERFLOW);
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}

Status GetTop(SqStack S){
ElemType e;
if (S.top == S.base) return ERROR;
e = *(S.top-1);
return e;
}

Status Push (SqStack &S,ElemType e)
{
//插入元素e為新的棧頂元素
if (S.top - S.base >= S.stacksize){
S.base = (ElemType *) realloc ( S.base,
(S.stacksize + STACKINCREMENT) * sizeof(ElemType));
if(!S.base) exit (OVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top++ = e;
return OK;
}

Status Pop (SqStack &S,ElemType &e){
//若棧不空,則刪除S的棧頂元素,用e返回其值,並返回OK;否則返回ERROR
if(S.top == S.base) return ERROR;
e = * --S.top;
return OK;
}

char In(char c,char OP[])
{
if(c>=35 && c<=47)
return 1;
else return 0;
}

char OP[8]=;
int m[7][7]={1,1,2,2,2,1,1,

1,1,2,2,2,1,1,

1,1,1,1,2,1,1,
1,1,1,1,2,1,1,
2,2,2,2,2,0,-1,
1,1,1,1,-1,1,1,
2,2,2,2,2,-1,0};//1 > 2 < 0 = -1 不存在

char Precede(char i,char j)
{
int a,b; char *p;
for(p=OP,a=0;*p!='\0';p++,a++)
if(*p==i) break;
for(p=OP,b=0;*p!='\0';p++,b++)
if(*p==j) break;
if(m[a][b]==1) return '>';
else if(m[a][b]==2) return '<';
else if(m[a][b]==0) return '=';
else return 'O';
}

char Operate(char a,char theta,char b)
{
if(a>47) a=atoi(&a);
if(b>47) b=atoi(&b);
switch(theta)
{
case '+': return a+b;
break;
case '-': return a-b;
break;
case '*': return a*b;
break;
case '/': return a/b;
break;
}
}

OperandType EvaluateExpression()
{
SqStack OPTR,OPND;
OperandType a,b,c; OperatorType theta;
InitStack(OPTR); Push(OPTR,'#');
InitStack(OPND); c=getchar();
while (c!='#' || GetTop(OPTR)!='#')
{
if (!In(c,OP))
else
switch(Precede(GetTop(OPTR),c))
{
case '<' :
Push(OPTR,c); c = getchar();
break;
case '=' :
Pop(OPTR,c); c = getchar();
break;
case '>' :
Pop(OPTR,theta);
Pop(OPND,b); Pop(OPND,a);
Push(OPND,Operate(a,theta,b));
break;
}
}
return GetTop(OPND);
}

void main()
{
printf("(以#為結束符)\n");
printf("請輸入:\n");
int a;
a=(int)EvaluateExpression();
printf("%d",a);
getch();
}

:
ls都正確

:
C++ In Action這本書裡面有表達式求值的詳細項目分析.

:
數據結構的書裡面都有的,仔細看一下

:
studyall123的只能對0到9的數字運算才有效,對於10以上的數字就不行!不知道有沒有更好的方法!

:
現在的人,連google一下都懶啊

:
實際上是按照逆波蘭式的順序讓輸入的表達式入棧,再根據運算符優先順序來計算。

:
lenrning!

『肆』 財務計算器 為什麼RPN

RPN是什麼?為什麼使用RPN?

RPN計算器使用一個堆棧,在這個堆棧的表層上對所有的數學運算進行立即計算。這個堆棧被用作是記錄在以後的運算中要用到的中間結果的存儲器。因此,使用RPN計算器,你不再需要任何的括弧了。首先,輸入數字,壓入堆棧,然後就可以對這些數做你想做的操作了。比如說我們要計算:
((3+1)^2+1)*4要計算這個,你應該這么做:

3 enter
1 + (你會立刻看到這個操作的結果: 4)

x^2 (你會立刻看到這個操作的結果: 16)
1+ (你會立啟頌刻看到這個操作的結果: 17)
4* (最終結果: 68)

可以看到,輸入這個算式只需要9次擊鍵,而且你能看到所有的中間結果。這其實基本上就是如果你不是用計算器,而是進行口算時,在頭腦中演算的過程。換句話說,RPN計算器更加「自然」。它和你的大腦的工作方式是相同的。

如果你把RPN計算和一個算術計算器相比較的話,輸入相同的算式需要12次擊鍵,而且你看不到中間結果。換句話說,RPN計算器的優點在於:

閱讀全文

與堆棧計算器演算法相關的資料

熱點內容
java快遞介面 瀏覽:385
哪個app可以教新爸爸 瀏覽:206
如何查看伺服器系統版本信息 瀏覽:524
成都市土地出讓金演算法 瀏覽:702
鋼筋加密標記 瀏覽:575
ps中擴展功能在文件夾的什麼位置 瀏覽:903
雙極壓縮機為什麼要先高壓 瀏覽:527
蘋果手機伺服器填什麼 瀏覽:832
android移動動畫效果 瀏覽:691
電子和伺服器是什麼意思 瀏覽:691
phpurl中文亂碼問題 瀏覽:893
程序員那麼可愛大結局陸漓產子 瀏覽:538
java如何從雲伺服器讀取本地文件 瀏覽:923
壓縮空氣軟管製作方法 瀏覽:911
天河三號演算法 瀏覽:924
php隊列教程 瀏覽:632
洪水命令 瀏覽:529
安卓怎麼弄成蘋果在線 瀏覽:435
谷歌web伺服器地址 瀏覽:900
安卓鎖屏圖片如何刪除 瀏覽:721