如果覺得對你有幫助,能否點個贊或關個注,以示鼓勵筆者呢?!博客目錄 | 先點這里
偶然翻到了自己大一時候寫的一些代碼,代碼冗余,但還是想保存下來,以作紀念,
文章目錄
- 1.運行效果
- 2.運行環境
- 3.完整代碼
1.運行效果



2.運行環境
原始碼(Dev5.4.0版本下可直接(.cpp檔案)運行 gcc 4.7.2)
注意:由于部分代碼為C11標準,后綴名應改為cpp運行

編譯器下載鏈接:https://pan.baidu.com/s/1Hywq6hxzxMzX1-22ig2HdA
提取碼:kd65
下載后解壓即可使用

3.完整代碼
#include<bits/stdc++.h>
#include<conio.h>
#include<windows.h>
using namespace std;
typedef long long ll;
/************全域變數*****************/
typedef struct
{
int x,y;
}pos;
string op="0123456789+-*/C()E";
int key[10][10]={
{0,0,0,0,0},
{0,14,13,12,11},
{0,7,8,9,10},
{0,4,5,6,10},
{0,1,2,3,17},
{0,0,15,16,17}
};
char mp[500][1000] = {
{" C語言計算器1.0"},
{""},
{" 作者:山河"},
{""},
{" 說明"},
{"┌───────────────────────────────────┐ "},
{"│┌─────────────────────────────────┐│ WASD或者↑↓←→可操作虛擬游標的移動"},
{"││ ││ "},
{"│└─────────────────────────────────┘│ 當游標在虛擬鍵盤上時,按下空格可以將虛擬鍵盤上的數字輸入 "},
{"├────────┬────────┬────────┬────────┤ "},
{"│ │ │ │ │ 讓游標移動在Enter上面按下空格可計算結果 "},
{"│ C │ / │ * │ - │ "},
{"│ │ │ │ │ 支持括號等混合運算(除法自動向下取整,懶得施工了)"},
{"├────────┼────────┼────────┼────────┤"},
{"│ │ │ │ │ 小彩蛋:按F可進入輸入模式(不建議使用,未施工完畢)"},
{"│ 7 │ 8 │ 9 │ │"},
{"│ │ │ │ │ 健壯性未完善(懶得修復),刷演算法的一個小玩意(懶)"},
{"├────────┼────────┼────────┤ + │"},
{"│ │ │ │ │ 其它小游戲用H5寫去咯,隨緣更新,對C的一點愛好吧,畢竟不能總是黑框框"},
{"│ 4 │ 5 │ 6 │ │"},
{"│ │ │ │ │ "},
{"├────────┼────────┼────────┼────────┤"},
{"│ │ │ │ │ "},
{"│ 1 │ 2 │ 3 │ E │"},
{"│ │ │ │ n │ "},
{"├────────┼────────┼────────│ t │"},
{"│ │ │ │ e │ "},
{"│ 0 │ ( │ ) │ r │"},
{"│ │ │ │ │ "},
{"└────────┴────────┴────────┴────────┘"}
};
/************函式宣告*****************/
void gotoxy(int x, int y);//坐標函式
void HideCursor();//隱藏游標
void ShowCursor();//顯示游標
void move();//控制虛擬鍵盤的指標移動函式
void load();//加載畫面
void init();//初始化設定顏色和視窗大小
int pr(char o);//傳入運算子,回傳優先級
int find(char o);//判斷是否為符號
string exp_deal(string in);//對運算式進行處理,避免多個數字相連
string exp_to_postexp(string in);//中綴運算式轉為后綴運算式
ll calc(ll x,ll y,char o);//x為堆疊頂數,y為次頂數 y在算式前,x在后
string postexp_val(string in);//后綴運算式求值
string calc_res(string in);//傳入輸入的中綴運算式,計算結果
void gotoxy(int x, int y) //坐標函式
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
}
void HideCursor()//隱藏游標
{
CONSOLE_CURSOR_INFO cursor_info={1,0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
void ShowCursor()//顯示游標
{
CONSOLE_CURSOR_INFO cursor_info={1,1};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
//控制虛擬鍵盤的指標移動函式
void move()
{
int flag=0;
string in="";//輸入的字串
char ch1,ch2;
pos now_key,now_mp,last_key,last_mp;//key用來獲取符號值,mp用來獲取圖上的位置
now_key.x=1,now_key.y=1;
now_mp.x=20,now_mp.y=17;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),57);
gotoxy(now_mp.x,now_mp.y);
cout<<"C";
//同時啟用wasd和方向鍵
while(1){
ch1=getch();
if(ch1==-32)//方向鍵為雙鍵值
{
flag=0;
ch2=getch();
switch(ch2)
{
case 72:ch1='w';break;//上
case 80:ch1='s';break;//下
case 75:ch1='a';break;//左
case 77:ch1='d';break;//右
default: break;
}
}
switch(ch1)
{
case 'w':
case 'W':
if(now_key.x>1){
last_key.x=now_key.x,last_key.y=now_key.y;
last_mp.x=now_mp.x,last_mp.y=now_mp.y;
if(now_key.x==5&&now_key.y==4)break;
if(key[now_key.x][now_key.y]==10){now_key.x-=2,now_mp.y-=6;break;}
if(key[now_key.x][now_key.y]==17){now_key.x--,now_mp.y-=6;break;}
now_key.x--;
now_mp.y-=4;
}
break;
case 's':
case 'S':
if(now_key.x<5){
if(now_key.x==4&&now_key.y==4)break;
last_key.x=now_key.x,last_key.y=now_key.y;
last_mp.x=now_mp.x,last_mp.y=now_mp.y;
if(key[now_key.x][now_key.y]==11){now_key.x+=2,now_mp.y+=6;break;}
if(key[now_key.x][now_key.y]==10){now_key.x++,now_mp.y+=6;break;}
now_key.x++;
now_mp.y+=4;
}
break;
case 'a':
case 'A':
if(now_key.y>1){
last_key.x=now_key.x,last_key.y=now_key.y;
last_mp.x=now_mp.x,last_mp.y=now_mp.y;
now_key.y--;
if(key[now_key.x][now_key.y]==9){now_mp.x-=9,now_mp.y-=2;break;}
if(key[now_key.x][now_key.y]==6){now_mp.x-=9,now_mp.y+=2;break;}
now_mp.x-=9;
}
break;
case 'd':
case 'D':
if(now_key.y<4){
last_key.x=now_key.x,last_key.y=now_key.y;
last_mp.x=now_mp.x,last_mp.y=now_mp.y;
if(key[now_key.x][now_key.y]==9){now_key.y++,now_key.x++,now_mp.x+=9,now_mp.y+=2;break;}
if(key[now_key.x][now_key.y]==6){now_key.y++,now_mp.x+=9,now_mp.y-=2;break;}
if(key[now_key.x][now_key.y]==16){now_key.y++,now_key.x--,now_mp.x+=9,now_mp.y-=4;break;}
now_key.y++;
now_mp.x+=9;
}
break;
case 'F'://啟動鍵盤輸入模式,提示游標閃爍
case 'f':
flag=1;
system("color 70");//設定顏色
gotoxy(50,13);
ShowCursor();//顯示游標
char c;
while(1){
while((c=getch())!='k')
{
in+=c;
gotoxy(50-32,13);
for(int i=0;i<32;i++)cout<<" ";
gotoxy(50-in.length(),13);
cout<<in;
}
HideCursor();
gotoxy(50-32,13);
for(int i=0;i<32;i++)cout<<" ";
in=calc_res(in);
gotoxy(50-in.length(),13);
cout<<in;
in="";//清空
}
break;
case ' '://選中小鍵盤時
system("color 70");//設定顏色
flag=1;
int val=key[now_key.x][now_key.y];
if(val==14){
gotoxy(50-32,13);
for(int i=0;i<32;i++)cout<<" ";
in="";//清空
}
else if(val==17){//提交
int len=in.length();
in=calc_res(in);
gotoxy(50-len,13);
for(int i=0;i<len;i++)cout<<" ";
gotoxy(50-in.length(),13);
cout<<in;
in="";
break;
}
else in+=op[val];//填入中綴運算式
gotoxy(50-in.length(),13);
cout<<in;
break;
}
if(!flag){
//先繪制移動前的符號
system("color 70");//設定顏色
gotoxy(last_mp.x,last_mp.y);
cout<<op[key[last_key.x][last_key.y]];
//繪制當前移動到的符號
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),57);
if(key[now_key.x][now_key.y]==17){
string s="Enter";
for(int i=0;i<5;i++)
{
gotoxy(now_mp.x,now_mp.y+i);
cout<<s[i];
}
}
else{
gotoxy(now_mp.x, now_mp.y);
cout<<op[key[now_key.x][now_key.y]];
}
}
}
}
void load()
{
for (int i = 0; i <= 30; i++)
{
gotoxy(15,6+i);
cout<<mp[i]<<endl;
}
}
void init()
{
system(" mode con cols=150 lines=40");//設定寬高
system("color 70");//設定顏色
HideCursor();
load();
move();
}
int pr(char o)//傳入運算子,回傳優先級
{
int pri[6]={0,1,1,2,2,0};//左括號加減乘除 優先級
char op[6]={'(','+','-','*','/','#'};//#做堆疊底使用
for(int i=0;i<6;i++)
if(op[i]==o)return pri[i];
}
int find(char o)
{
char op[10]={'#','(','+','-','*','/','^',')'};
for(int i=0;i<10;i++)
if(op[i]==o)return 1;
return 0;
}
string exp_deal(string in)//對運算式進行處理,避免多個數字相連
{
string t="";
for(int i=0;i<in.length();i++)
{
t+=in[i];
if(in[i]>='0'&&in[i]<='9'&&find(in[i+1]))t+='@';
}
return t;
}
string exp_to_postexp(string in)//中綴轉后綴
{
int pri[6]={0,1,1,2,2,0};//左括號加減乘除 優先級
char op[6]={'(','+','-','*','/','#'};//#做堆疊底使用
stack<char>s;
string res="";
s.push('#');
for(int i=0;i<in.length();i++)
{
if((in[i]>='0'&&in[i]<='9'||in[i]=='@')){
res+=in[i];
}
else {//處理符號
if(in[i]=='(')s.push(in[i]);
else{
if(in[i]==')'){
while(s.top()!='('){
res+=s.top();s.pop();
}
s.pop();//彈出左括號
continue;
}
//當前掃描到的符號
if(pr(in[i])>pr(s.top()))s.push(in[i]);//優先級大于堆疊頂
else if(pr(in[i])<=pr(s.top())){//優先級小于等于堆疊頂
while(pr(in[i])<=pr(s.top())){res+=s.top();s.pop();}
s.push(in[i]);
}
}
}
}
while(s.top()!='#'){
res+=s.top();s.pop();
}
return res;
}
ll calc(ll x,ll y,char o)//x為堆疊頂數,y為次頂數 y在算式前,x在后
{
switch(o){
case '+':return x+y;
case '-':return y-x;
case '*':return x*y;
case '/':return y/x;
case '^':return pow(y,x);//雖然我忘記搞這個的界面了,以后再加?
}
}
string postexp_val(string in)//后綴運算式求值,維護一個堆疊即可
{
stack<ll>s;
ll m,n,now=0;
for(int i=0;i<in.length();i++){
if(in[i]>='0'&&in[i]<='9'){//讀入數字
now*=10;now+=in[i]-'0';
}
else if(in[i]=='@')s.push(now),now=0;
if(find(in[i])){
m=s.top();s.pop();
n=s.top();s.pop();
s.push(calc(m,n,in[i]));
}
}
ll num=s.top();
stringstream ss;
ss<<num;
return ss.str();
}
string calc_res(string in)//傳入輸入的中綴運算式,計算結果
{
in=exp_deal(in);//把中綴運算式進行處理
in=exp_to_postexp(in);//轉為后綴運算式
return postexp_val(in);//后綴運算式求值
}
int main()
{
init();
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/400659.html
標籤:其他
