導航:首頁 > 源碼編譯 > 24的源碼過程

24的源碼過程

發布時間:2022-12-10 02:43:36

㈠ 24點c語言源代碼

#include"math.h"
int total=0,count=0,page;
char temp;

main(){
float sum(float,float,char);
void test24(float [],char []);
int i,j,k,l,q,r,s,t,n=0;
float a[4];
char f[4]={'+','-','*','/'};
float x[4];
char y[3];
int go=1;
while(go==1){
printf("Please input how many resualts every break prints?\n");
scanf("%d",&page);
printf("Please input the 4 num to 24:\n");
scanf("%f%f%f%f",&a[0],&a[1],&a[2],&a[3]);
scanf("%c",&temp);
printf("\n******Resualt:******\n");
/*get 4 num*/
total=0;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
if(i==j) continue;
for(k=0;k<4;k++){
if(k==i||k==j) continue;
for(l=0;l<4;l++){
if(l==i||l==j||l==k) continue;
x[0]=a[i];
x[1]=a[j];
x[2]=a[k];
x[3]=a[l];
/*get +-*/
for(q=0;q<4;q++){
y[0]=f[q];
for(r=0;r<4;r++){
y[1]=f[r];
for(s=0;s<4;s++){
y[2]=f[s];
/*start*/
test24(x,y);
}
}
}
n++;
}
}
}
}
printf("total=%d\n",total);
printf("******end******\n");
printf("continue? 1:yes 2:no\n");
scanf("%d",&go);
}
printf("Bye!\n");
}

float sum(float xx,float yy,char mm){
switch(mm){
case '+':return (xx+yy); break;
case '-':return (xx-yy); break;
case '*':return (xx*yy); break;
case '/':
if(yy!=0){
return (xx/yy); break;
}
else{
return 0; break;
}
}
}

void test24(float x[],char m[]){
int ii;
float s[5];

s[0]=sum(sum(sum(x[0],x[1],m[0]),x[2],m[1]),x[3],m[2]);
s[1]=sum(sum(x[0],sum(x[1],x[2],m[1]),m[0]),x[3],m[2]);
s[2]=sum(x[0],sum(sum(x[1],x[2],m[1]),x[3],m[2]),m[0]);
s[3]=sum(x[0],sum(x[1],sum(x[2],x[3],m[2]),m[1]),m[0]);
s[4]=sum(sum(x[0],x[1],m[0]),sum(x[2],x[3],m[2]),m[1]);
for(ii=0;ii<5;ii++){
if(fabs(s[ii]-24.0)<0.1){
if(ii==0)
printf("((%1.0f%c%1.0f)%c%1.0f)%c%1.0f\n",x[0],m[0],x[1],m[1],x[2],m[2],x[3]);
else if(ii==1)
printf("(%1.0f%c(%1.0f%c%1.0f))%c%1.0f\n",x[0],m[0],x[1],m[1],x[2],m[2],x[3]);
else if(ii==2)
printf("%1.0f%c((%1.0f%c%1.0f)%c%1.0f)\n",x[0],m[0],x[1],m[1],x[2],m[2],x[3]);
else if(ii==3)
printf("%1.0f%c(%1.0f%c(%1.0f%c%1.0f))\n",x[0],m[0],x[1],m[1],x[2],m[2],x[3]);
else if(ii==4)
printf("(%1.0f%c%1.0f)%c(%1.0f%c%1.0f)\n",x[0],m[0],x[1],m[1],x[2],m[2],x[3]);
total++;
count++;
/*20 per break*/
if(count>=page){
printf("press ENTER continue\n");
scanf("%c",&temp);
count=0;
}
}
}
}

㈡ C語言編寫1~9數字加減乘除得24的源代碼!

#include<stdio.h>
double fun(double a1,double a2,int b)
{switch(b)
{case 0:return (a1+a2);
case 1:return (a1-a2);
case 2:return (a1*a2);
case 3:return (a1/a2);
}
}
void main()
{int i,j,k,l,n,m,r,save[4];
double num[4]={1,1,1,1},tem1,tem2,tem3,abc=1111;
char sign[5]="+-*/";
printf("input 4 numbers:");
for(i=0;i<4;i++)
{scanf("%lf",num+i); save[i]=num[i];}
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(j!=i)
{for(k=0;k<4;k++)
if(k!=i&&k!=j)
{for(l=0;l<4;l++)
if(l!=i&&l!=j&&l!=k)
{for(n=0;n<4;n++)
for(m=0;m<4;m++)
for(r=0;r<4;r++)
{tem1=fun(num[i],num[j],n);
tem2=fun(tem1,num[k],m);
tem3=fun(tem2,num[l],r);
if(tem3==24.0)printf("{(%d%c%d)%c%d}%c%d=24\n",save[i],sign[n],save[j],sign[m],save[k],sign[r],save[l]);
else if(tem3==-24.0)printf("{%d%c(%d%c%d)}%c%d=24\n",save[k],sign[m],save[i],sign[n],save[j],sign[r],save[l]);
else if(tem3==1.0/24.0)printf("%d%c{(%d%c%d)%c%d}=24\n",save[l],sign[r],save[i],sign[n],save[j],sign[m],save[k]);
else if(tem3==-1.0/24.0)printf("%d%c{%d%c(%d%c%d)}=24\n",save[l],sign[r],save[k],sign[n],save[i],sign[m],save[j]);
else
{tem1=fun(num[i],num[j],n);
tem2=fun(num[k],num[l],r);
tem3=fun(tem1,tem2,m);
if(tem3==24.0) printf("(%d%c%d)%c(%d%c%d)=24\n",save[i],sign[n],save[j],sign[m],save[k],sign[r],save[l]);
}
}
}
}
}
}

㈢ 24點游戲C++程序源代碼

給你看看,挺長的哦//程序作者:魏洪源
//版權所有,轉載請聯系:[email protected]
#include<iostream>
#include<string>
#include<time.h>
using namespace std;#define NUM 1000
int j=2;//定義為全局變數
int randNum[NUM];//因為rand()函數有一定的缺陷,所以在程序中定義了randNum數組來存放隨機數
//即使使用了種子函數srand(),由於程序運行時間比較短,也不太好設置種子。因此使用數組來存放隨機數class Poker
{
private:
int poker[53]; //撲克
int pokerValue[53]; //撲克代表的數值
string pokerName[53]; //撲克名

int money; //玩家錢數
int bet; //玩家的賭注 int pokerF[5]; //玩家手中的牌 F:Farmer L:Landlord
int pokerL[5]; //莊家手中的牌 F:Farmer L:Landlord
int pokerNumF; //玩家手中的牌數
int pokerNumL; //莊家手中的牌數
public:
Poker(); //構造函數,對牌初始化
void initPoker(); //洗牌,在每輪游戲開始前進行
string getPokerF(); //用字元串的形式返回玩家的牌
string getPokerL(); //用字元串的形式返回莊家的牌
int getSumF(); //返回玩家牌的點數,用以判斷是否超過21點
int getSumL(); //返回莊家牌的點數
void farmerAsk(); //玩家要牌
void landlordAsk(); //莊家要牌
void inputBet(); //玩家輸入賭注
void newGame(); //開始新游戲
void landlordProcess(); //在玩家不要牌時進行處理};Poker::Poker()
{ poker[0]=0;
for(int i=1;i<=13;i++) //|
{ //|
poker[i]=i; //|用構造函數對牌初始化
poker[i+13]=i; //|
poker[i+26]=i; //|
poker[i+39]=i; //|
}//for結束 pokerValue[0]=0;
for(i=1;i<=52;i++)
{
if(poker[i]<=10) pokerValue[i]=poker[i];
else pokerValue[i]=10;
}//for結束
pokerName[0]="";
for(i=0;i<4;i++)
{
pokerName[1+13*i]="A";
pokerName[2+13*i]="2";
pokerName[3+13*i]="3";
pokerName[4+13*i]="4";
pokerName[5+13*i]="5";
pokerName[6+13*i]="6";
pokerName[7+13*i]="7";
pokerName[8+13*i]="8";
pokerName[9+13*i]="9";
pokerName[10+13*i]="10";
pokerName[11+13*i]="J";
pokerName[12+13*i]="Q";
pokerName[13+13*i]="K";
}//for結束

money=200; //玩家開始玩游戲時錢數是200
bet=0;

for(i=0;i<5;i++)
{
pokerF[i]=0; //|對pokerOfFarmer初始化
pokerL[i]=0; //|對pokerOfLandlord初始化
}
pokerNumF=0;//玩家手中的牌數初始化為0
pokerNumL=0;//莊家手中的牌數初始化為0

srand((int)time(0));
for(i=0;i<NUM;i++)
{
randNum[i]=rand()*51/32767+1;//產生隨機數數組
}}//構造函數Poker()結束
void Poker::initPoker()
{
cout<<"新一局游戲開始,開始洗牌>>>>>"<<endl; pokerF[0]=randNum[j++]; //產生1-52的隨機數
pokerF[1]=randNum[j++]; //產生1-52的隨機數
pokerL[0]=randNum[j++]; //產生1-52的隨機數
pokerL[1]=randNum[j++]; //產生1-52的隨機數

pokerNumF=2;
pokerNumL=2;

cout<<"洗牌完成,你的牌為:"<<getPokerF()<<endl;
}//void Poker::initPoker()結束string Poker::getPokerF()//用字元串的形式返回玩家的牌
{
int i;
string result="";

for(i=0;i<pokerNumF;i++)
result=result+pokerName[pokerF[i]]+" ";

return result;
}//string Poker::getPokerF()結束string Poker::getPokerL()//用字元串的形式返回莊家的牌
{
int i;
string result="";

for(i=0;i<pokerNumL;i++)
result=result+pokerName[pokerL[i]]+" ";

return result;
}//string Poker::getPokerL()結束int Poker::getSumF() //返回玩家的總點數
{
int result=0;

for(int i=0;i<pokerNumF;i++)
result=result+pokerValue[pokerF[i]]; return result;
}int Poker::getSumL()//返回莊家的總點數
{ int result=0;

for(int i=0;i<pokerNumL;i++)
result=result+pokerValue[pokerL[i]];

return result;
}void Poker::farmerAsk()
{
if(pokerNumF>=5)
{
cout<<"你的牌數已夠5張,不能再要牌了"<<endl;
landlordProcess();
}
else
{
pokerF[pokerNumF++]=randNum[j++]; //產生1-52的隨機數
cout<<"你的牌為:"<<getPokerF()<<endl;
if(getSumF()>21)
{
cout<<"你撐死了,你輸了"<<bet<<"元"<<endl;
money=money-bet;
if(money<=0)
{
cout<<"你已經輸光了,哈哈"<<endl;
cout<<"游戲結束"<<endl;
exit(0);
}
inputBet();
initPoker();
}
else if(getSumF()==21)
{
landlordProcess();
}
}
}void Poker::landlordAsk()
{
if(pokerNumL>=5)
{
if(getSumF()>getSumL())
{
cout<<"莊家的牌為"<<getPokerL()<<endl;
cout<<"你贏了,你贏了"<<bet<<"元"<<endl;
money=money+bet;
inputBet();
initPoker();
}
else if(getSumF()==getSumL())
{
cout<<"莊家的牌為"<<getPokerL()<<endl;
cout<<"平手"<<endl;
inputBet();
initPoker();
}
else if(getSumF()<getSumL())
{
cout<<"莊家的牌為"<<getPokerL()<<endl;
cout<<"你輸了,你輸了"<<bet<<"元"<<endl;
money=money-bet;
if(money<=0)
{
cout<<"你已經輸光了,哈哈"<<endl;
cout<<"游戲結束"<<endl;
exit(0);
}
inputBet();
initPoker();
}
}
else
{
pokerL[pokerNumL++]=randNum[j++]; //產生1-52的隨機數
if(getSumL()>21)
{
cout<<"莊家的牌為"<<getPokerL()<<endl;
cout<<"莊家撐死了,你贏了"<<bet<<"元"<<endl;
money=money+bet;
inputBet();
initPoker();
}
else landlordProcess();
}
}
void Poker::inputBet()
{
cout<<"你現在有"<<money<<"元,請輸入賭注:";
do
{
cin>>bet;
if(bet>money)
cout<<"笨蛋,你沒那麼多錢,少來,重新輸入吧:";
}while(bet>money);}void Poker::newGame()
{
inputBet();
initPoker();
cout<<"你得到的牌為:"<<getPokerF()<<endl;
} void Poker::landlordProcess()
{
if(getSumL()>=17)
{
if(getSumL()>getSumF())
{
cout<<"莊家的牌為"<<getPokerL()<<endl;
cout<<"莊家獲勝,你輸了"<<bet<<"元"<<endl;
money=money-bet;
if(money<=0)
{
cout<<"你已經輸光了,哈哈"<<endl;
cout<<"游戲結束"<<endl;
exit(0);
}
inputBet();
initPoker();
}
else if(getSumF()==getSumL())
{
cout<<"莊家的牌為"<<getPokerL()<<endl;
cout<<"本次游戲平手"<<endl;
inputBet();
initPoker();
}
else
{
cout<<"莊家的牌為"<<getPokerL()<<endl;
cout<<"你贏了,你贏了"<<bet<<"元"<<endl;
money=money+bet;
inputBet();
initPoker();
}
}
else
{
landlordAsk();
}
}

int main()
{
int choose=1;
Poker poker;
cout<<"****************** 歡迎玩二十一點游戲 ******************"<<endl<<endl;
poker.inputBet();
poker.initPoker(); //洗牌

while(choose==1||choose==2||choose==3||choose==4)
{
cout<<"1.要牌 2.不要牌 3.重新開始 4.退出 >>請輸入數字選擇操作:";
cin>>choose;
if(choose==1) poker.farmerAsk();
else if(choose==2) poker.landlordProcess();
else if(choose==3) poker.newGame();
else if(choose==4) exit(0);
} return 0;
}//main函數結束

㈣ 一個數的原碼,反碼,補碼怎麼算

計算機中的存儲系統都是用2進制儲存的,對我們輸入的每一個信息它都會自動轉變成二進制的形式,而二進制在存儲的時候就會用到原碼,反碼和補碼例如:輸入25原碼是:0000000000011001反碼: 1111111111100110 補碼: 1111111111100111

數值在計算機中表示形式為機器數,計算機只能識別0和1,使用的是二進制,而在日常生活中人們使用的是十進制,"正如亞里士多德早就指出的那樣,今天十進制的廣泛採用,只不過我們絕大多數人生來具有10個手指頭這個解剖學事實的結果.盡管在歷史上手指計數(5,10進制)的實踐要比二或三進制計數出現的晚. "(摘自<<數學發展史>>有空大家可以看看哦~,很有意思的).為了能方便的與二進制轉換,就使用了十六進制(2 4)和八進制(23).下面進入正題.

數值有正負之分,計算機就用一個數的最高位存放符號(0為正,1為負).這就是機器數的原碼了.假設機器能處理的位數為8.即字長為1byte,原碼能表示數值的范圍為

(-127~-0 +0~127)共256個.

有了數值的表示方法就可以對數進行算術運算.但是很快就發現用帶符號位的原碼進行乘除運算時結果正確,而在加減運算的時候就出現了問題,如下: 假設字長為8bits

( 1 ) 10- ( 1 )10 = ( 1 )10 + ( -1 )10 = ( 0 )10

(00000001)原 + (10000001)原 = (10000010)原 = ( -2 ) 顯然不正確.

因為在兩個整數的加法運算中是沒有問題的,於是就發現問題出現在帶符號位的負數身上,對除符號位外的其餘各位逐位取反就產生了反碼.反碼的取值空間和原碼相同且一一對應. 下面是反碼的減法運算:

( 1 )10 - ( 1 ) 10= ( 1 ) 10+ ( -1 ) 10= ( 0 )10

(00000001) 反+ (11111110)反 = (11111111)反 = ( -0 ) 有問題.

( 1 )10 - ( 2)10 = ( 1 )10 + ( -2 )10 = ( -1 )10

(00000001) 反+ (11111101)反 = (11111110)反 = ( -1 ) 正確

問題出現在(+0)和(-0)上,在人們的計算概念中零是沒有正負之分的.(印度人首先將零作為標記並放入運算之中,包含有零號的印度數學和十進制計數對人類文明的貢獻極大).

於是就引入了補碼概念. 負數的補碼就是對反碼加一,而正數不變,正數的原碼反碼補碼是一樣的.在補碼中用(-128)代替了(-0),所以補碼的表示範圍為:

(-128~0~127)共256個.

注意:(-128)沒有相對應的原碼和反碼, (-128) = (10000000) 補碼的加減運算如下:

( 1 ) 10- ( 1 ) 10= ( 1 )10 + ( -1 )10 = ( 0 )10

(00000001)補 + (11111111)補 = (00000000)補 = ( 0 ) 正確

( 1 ) 10- ( 2) 10= ( 1 )10 + ( -2 )10 = ( -1 )10

(00000001) 補+ (11111110) 補= (11111111)補 = ( -1 ) 正確

所以補碼的設計目的是:

⑴使符號位能與有效值部分一起參加運算,從而簡化運算規則.

⑵使減法運算轉換為加法運算,進一步簡化計算機中運算器的線路設計

所有這些轉換都是在計算機的最底層進行的,而在我們使用的匯編、C等其他高級語言中使用的都是原碼

㈤ 適合初學者的24點游戲C語言源代碼

關於二十四點游戲的編程思路與基本演算法

漫長的假期對於我來說總是枯燥無味的,閑來無聊便和同學玩起童年時經常玩的二十四點牌游戲來。此游戲說來簡單,就是利用加減乘除以及括弧將給出的四張牌組成一個值為24的表達式。但是其中卻不乏一些有趣的題目,這不,我們剛玩了一會兒,便遇到了一個難題——3、6、6、10(其實後來想想,這也不算是個太難的題,只是當時我們的腦筋都沒有轉彎而已,呵呵)。

問題既然出現了,我們當然要解決。冥思苦想之際,我的腦中掠過一絲念頭——何不編個程序來解決這個問題呢?文曲星中不就有這樣的程序嗎?所以這個想法應該是可行。想到這里我立刻開始思索這個程序的演算法,最先想到的自然是窮舉法(後來發現我再也想不到更好的方法了,悲哀呀,呵呵),因為在這學期我曾經寫過一個小程序——計算有括弧的簡單表達式。只要我能編程實現四個數加上運算符號所構成的表達式的窮舉,不就可以利用這個計算程序來完成這個計算二十四點的程序嗎?確定了這個思路之後,我開始想這個問題的細節。
首先窮舉的可行性問題。我把表達式如下分成三類——
1、 無括弧的簡單表達式。
2、 有一個括弧的簡單表達式。
3、 有兩個括弧的較復4、 雜表達式。
窮舉的開始我對給出的四個數進行排列,其可能的種數為4*3*2*1=24。我利用一個嵌套函數實現四個數的排列,演算法如下:
/* ans[] 用來存放各種排列組合的數組 */
/* c[] 存放四張牌的數組 */
/* k[] c[]種四張牌的代號,其中k[I]=I+1。
用它來代替c[]做處理,考慮到c[]中有可能出現相同數的情況 */
/* kans[] 暫存生成的排列組合 */
/* j 嵌套循環的次數 */
int fans(c,k,ans,kans,j)
int j,k[],c[];char ans[],kans[];
{ int i,p,q,r,h,flag,s[4],t[4][4];
for(p=0,q=0;p<4;p++)
{ for(r=0,flag=0;r if(k[p]!=kans[r]) flag++;
if(flag==j) t[j][q++]=k[p];
}
for(s[j]=0;s[j]<4-j;s[j]++)
{ kans[j]=t[j][s[j>;
if(j==3) { for(h=0;h<4;h++)
ans[2*h]=c[kans[h]-1]; /* 調整生成的排列組合在最終的表
達式中的位置 */
for(h=0;h<3;h++)
symbol(ans,h); /* 在表達式中添加運算符號 */
}
else { j++;
fans(c,k,ans,kans,j);
j--;
}
}
}

正如上面函數中提到的,在完成四張牌的排列之後,在表達式中添加運算符號。由於只有四張牌,所以只要添加三個運算符號就可以了。由於每一個運算符號可重復,所以計算出其可能的種數為4*4*4=64種。仍然利用嵌套函數實現添加運算符號的窮舉,演算法如下:

/* ans[],j同上。sy[]存放四個運算符號。h為表達式形式。*/
int sans(ans,sy,j,h)
char ans[],sy[];int j,h;
{ int i,p,k[3],m,n; char ktans[20];
for(k[j]=0;k[j]<4;k[j]++)
{ ans[2*j+1]=sy[k[j>; /* 剛才的四個數分別存放在0、2、4、6位
這里的三個運算符號分別存放在1、3、5位*/
if(j==2)
{ ans[5]=sy[k[j>;
/* 此處根據不同的表達式形式再進行相應的處理 */
}
else { j++; sans(ans,sy,j--,h); }
}
}

好了,接下來我再考慮不同表達式的處理。剛才我已經將表達式分為三類,是因為添加三個括弧對於四張牌來說肯定是重復的。對於第一種,無括弧自然不用另行處理;而第二種情況由以下代碼可以得出其可能性有六種,其中還有一種是多餘的。
for(m=0;m<=4;m+=2)
for(n=m+4;n<=8;n+=2)
這個for循環給出了添加一個括弧的可能性的種數,其中m、n分別為添加在表達式中的左右括弧的位置。我所說的多餘的是指m=0,n=8,也就是放在表達式的兩端。這真是多此一舉,呵呵!最後一種情況是添加兩個括弧,我分析了一下,發現只可能是這種形式才不會是重復的——(a b)(c d)。為什麼不會出現嵌套括弧的情況呢?因為如果是嵌套括弧,那麼外面的括弧肯定是包含三個數字的(四個沒有必要),也就是說這個括弧裡麵包含了兩個運算符號,而這兩個運算符號是被另外一個括弧隔開的。那麼如果這兩個運算符號是同一優先順序的,則肯定可以通過一些轉換去掉括弧(你不妨舉一些例子來試試),也就是說這一個括弧沒有必要;如果這兩個運算符號不是同一優先順序,也必然是這種形式((a+-b)*/c)。而*和/在這幾個運算符號中優先順序最高,自然就沒有必要在它的外面添加括弧了。

綜上所述,所有可能的表達式的種數為24*64*(1+6+1)=12288種。哈哈,只有一萬多種可能性(這其中還有重復),這對於電腦來說可是小case喲!所以,對於窮舉的可行性分析和實現也就完成了。

接下來的問題就是如何對有符號的簡單表達式進行處理。這是棧的一個著名應用,那麼什麼是棧呢?棧的概念是從日常生活中貨物在貨棧種的存取過程抽象出來的,即最後存放入棧的貨物(堆在靠出口處)先被提取出去,符合「先進後出,後進先出」的原則。這種結構猶如子彈夾。
在棧中,元素的插入稱為壓入(push)或入棧,元素的刪除稱為彈出(pop)或退棧。

棧的基本運算有三種,其中包括入棧運算、退棧運算以及讀棧頂元素,這些請參考相關數據結構資料。根據這些基本運算就可以用數組模擬出棧來。

那麼作為棧的著名應用,表達式的計算可以有兩種方法。

第一種方法——
首先建立兩個棧,操作數棧OVS和運算符棧OPS。其中,操作數棧用來記憶表達式中的操作數,其棧頂指針為topv,初始時為空,即topv=0;運算符棧用來記憶表達式中的運算符,其棧頂指針為topp,初始時,棧中只有一個表達式結束符,即topp=1,且OPS(1)=『;』。此處的『;』即表達式結束符。
然後自左至右的掃描待處理的表達式,並假設當前掃描到的符號為W,根據不同的符號W做如下不同的處理:
1、 若W為操作數
2、 則將W壓入操作數棧OVS
3、 且繼續掃描下一個字元
4、 若W為運算符
5、 則根據運算符的性質做相應的處理:
(1)、若運算符為左括弧或者運算符的優先順序大於運算符棧棧頂的運算符(即OPS(top)),則將運算符W壓入運算符棧OPS,並繼續掃描下一個字元。
(2)、若運算符W為表達式結束符『;』且運算符棧棧頂的運算符也為表達式結束符(即OPS(topp)=』;』),則處理過程結束,此時,操作數棧棧頂元素(即OVS(topv))即為表達式的值。
(3)、若運算符W為右括弧且運算符棧棧頂的運算符為左括弧(即OPS(topp)=』(『),則將左括弧從運算符棧談出,且繼續掃描下一個符號。
(4)、若運算符的右不大於運算符棧棧頂的運算符(即OPS(topp)),則從操作數棧OVS中彈出兩個操作數,設先後彈出的操作數為a、b,再從運算符棧OPS中彈出一個運算符,設為+,然後作運算a+b,並將運算結果壓入操作數棧OVS。本次的運算符下次將重新考慮。

第二種方法——
首先對表達式進行線性化,然後將線性表達式轉換成機器指令序列以便進行求值。

那麼什麼是表達式的線性化呢?人們所習慣的表達式的表達方法稱為中綴表示。中綴表示的特點是運算符位於運算對象的中間。但這種表示方式,有時必須藉助括弧才能將運算順序表達清楚,而且處理也比較復雜。

1929年,波蘭邏輯學家Lukasiewicz提出一種不用括弧的邏輯符號體系,後來人們稱之為波蘭表示法(Polish notation)。波蘭表達式的特點是運算符位於運算對象的後面,因此稱為後綴表示。在對波蘭表達式進行運算,嚴格按照自左至右的順序進行。下面給出一些表達式及其相應的波蘭表達式。
表達式 波蘭表達式
A-B AB-
(A-B)*C+D AB-C*D+
A*(B+C/D)-E*F ABCD/+*EF*-
(B+C)/(A-D) BC+AD-/

OK,所謂表達式的線性化是指將中綴表達的表達式轉化為波蘭表達式。對於每一個表達式,利用棧可以把表達式變換成波蘭表達式,也可以利用棧來計算波蘭表達式的值。

至於轉換和計算的過程和第一種方法大同小異,這里就不再贅述了。

下面給出轉換和計算的具體實現程序——

/* first函數給出各個運算符的優先順序,其中=為表達式結束符 */
int first(char c)
{ int p;
switch(c)
{ case '*': p=2; break;
case '/': p=2; break;
case '+': p=1; break;
case '-': p=1; break;
case '(': p=0; break;
case '=': p=-1; break;
}
return(p);
}
/* 此函數實現中綴到後綴的轉換 */
/* M的值宏定義為20 */
/* sp[]為表達式數組 */
int mid_last()
{ int i=0,j=0; char c,sm[M];
c=s[0]; sm[0]='='; top=0;
while(c!='\0')
{ if(islower(c)) sp[j++]=c;
else switch(c)
{ case '+':
case '-':
case '*':
case '/': while(first(c)<=first(sm[top]))
sp[j++]=sm[top--];
sm[++top]=c; break;
case '(': sm[++top]=c; break;
case ')': while(sm[top]!='(')
sp[j++]=sm[top--];
top--; break;
default :return(1);
}
c=s[++i];
}
while(top>0) sp[j++]=sm[top--];
sp[j]='\0'; return(0);
}
/* 由後綴表達式來計算表達式的值 */
int calc()
{ int i=0,sm[M],tr; char c;
c=sp[0]; top=-1;
while(c!='\0')
{ if(islower(c)) sm[++top]=ver[c-'a'];/*在轉換過程中用abcd等來代替數,
這樣才可以更方便的處理非一位數,
ver數組中存放著這些字母所代替的數*/
else switch(c)
{ case '+': tr=sm[top--]; sm[top]+=tr; break;
case '-': tr=sm[top--]; sm[top]-=tr; break;
case '*': tr=sm[top--]; sm[top]*=tr; break;
case '/': tr=sm[top--];sm[top]/=tr;break;
default : return(1);
}
c=sp[++i];
}
if(top>0) return(1);
else { result=sm[top]; return(0); }
}

這樣這個程序基本上就算解決了,回過頭來拿這個程序來算一算文章開始的那個問題。哈哈,算出來了,原來如此簡單——(6-3)*10-6=24。

最後我總結了一下這其中容易出錯的地方——

1、 排列的時候由於一個數只能出現一次, 所以必然有一個判斷語句。但是用什麼來判斷,用大小顯然不行,因為有可能這四個數中有兩個或者以上的數是相同的。我的方法是給每一個數設置一個代號,在排列結束時,通過這個代號找到這個數。

2、在應用嵌套函數時,需仔細分析程序的執行過程,並對個別變數進行適當的調整(如j的值),程序才能正確的執行。

3、在分析括弧問題的時候要認真仔細,不要錯過任何一個可能的機會,也要盡量使程序變得簡單一些。不過我的分析可能也有問題,還請高手指點。

4、在用函數對一個數組進行處理的時候,一定要注意如果這個數組還需要再應用,就必須將它先保存起來,否則會出錯,而且是很嚴重的錯誤。

5、在處理用戶輸入的表達式時,由於一個十位數或者更高位數是被分解成各位數存放在數組中,所以需對它們進行處理,將它們轉化成實際的整型變數。另外,在轉化過程中,用一個字母來代替這個數,並將這個數存在一個數組中,且它在數組中的位置和代替它的這個字母有一定的聯系,這樣才能取回這個數。

6、由於在窮舉過程難免會出現計算過程中有除以0的計算,所以我們必須對calc函數種對於除的運算加以處理,否則程序會因為出錯而退出(Divide by 0)。

7、最後一個問題,本程序尚未解決。對於一些比較著名的題目,本程序無法解答。比如說5、5、5、1或者8、8、3、3。這是由於這些題目在計算的過程用到了小數,而本程序並沒有考慮到小數。

㈥ 24點游戲演算法

看了N個24點的源碼了,雖然都能正確的得到結果,不過從效率和智能上來說都很垃圾。(國內的程序員,大多也就是在源碼基礎上改改而已,這也是企業追逐經濟利益的趨勢。真正寫底層演算法的高手就沒多少了。。。如果A*,8皇後和跳馬的演算法對你來說沒什麼難度,可以嘗試寫下。很多人應該可以略過看下面的內容了,或者只看不思考,免得傷腦筋)。 這些演算法的通病,也正是我目前想解決的問題是:1 效率性把24點擴展一下,就是要寫一個函數。function fun(arr:Array,num):Array{ //arr參數為[a,b,c,d,e....] //N個數字,在24點游戲里,為[a,b,c,d] 4個數 //num //要匹配的結果 24點游戲里,num=24 return Array //輸出結果存在數組里,如["(3+3)*(2+2)","(3*2+2)*3".........]}如果是N個數字的計算,用N來計算程序的復雜度。那麼24點的很多演算法是屬於窮舉排列,無法擴展,並且重復計算量很多。沒效率可言2 結果的正確性這個也能說明為什麼連把公式窮舉出來,作為類似索引表的這樣典型空間換時間的方法,效率還是很低。這里還涉及到一點智能問題。
AI很難識別相同的運算。
如 a+b+c+d 和 a+c+b+d 按游戲規則來說屬於同種方法 但是在很多方法里,會得出重復的,如同時會輸出 ((a+b)+c)*d 和 ((a+c)+b)*d這樣同樣的公式。在我們玩24點撲克游戲時,這點明顯是不允許的。雖然24點這游戲並不是那麼嚴謹,但是有這樣的潛規則 在別人講他的演算法時,如果你馬上能想出同樣能算出24的不同類的方法,可以視為平手 如 2*4*(4-1) 和 (4+4)*(2+1) 可以視為不同的演算法。 特殊情況,當牌有點數相同的,花色不同時, 相同點數的位置替代,也應屬於同類運算,但是沒有一個代碼能夠識別這些的。 另外(8-(1+3))*6 和 (8-1-3)*6 理應屬於同種演算法。在程序中理應執行一遍,並且也只屬於(8-1-3)*6這種括弧數較少的公式才合理。 程序一次是只能計算兩個數的運算的。用遞歸回溯的思路,可以方便的遍歷所有的執行順序和符號組合。但是實際寫起來,在程序中,用條件判斷,剔除種種不必要的運算和生成簡捷正確的公式,難度非常大。另外就是遞歸的層級相當多,代碼設計難度也很大。 這個程序執行所費的時間,花在公式上的存儲讀取時間和條件判斷所花費的時間也是相當可觀的。3 智能性 還是回到24點來說了。擬人的思路。 當我們玩24點的游戲,很多時候,大家都不願意多看,馬上要求換牌。比如說A,A,2,2。在程序里可以這樣解釋,if(a*b*c*d<24){return} 牌太小了不可能有計算結果。 這時我們換了一張牌,結果大家都搶著報自己的答案了。為什麼能這么快呢?這和人工智慧里的學習記憶機制掛點鉤。人算時,並不會像通常的程序那樣去排列組合,直到得到滿意的結果為止。而是有很多優先的成分。比如說4張牌裡面,有一張牌是3,那麼,我們馬上會想到的是把其它3張牌組合成8。而如果裡面有張牌是4,我們會想到把其它3張牌組合成6。而且24點這游戲一般兩人玩,手動出牌也很難保證4張牌同時出。不同人的注意力也集中在不同地方。就生成了一個優先度的問題。 如上所訴,那麼在計算24點的程序里,如果a,b,c,d裡面,有數字=2,3,4,6,8,12這樣的12的因數在裡面,我們一般應該將這樣的數字放在最後去計算,優先組合其它的3個數字。如果數字在數組的位置和優先計算有關系的話,即是 for(var i in arr){ if(arr[i]==24的因數){ arr.push(arr.splice(i,1)) } } 如果要換其中某一張牌時,這時我們其實已經將其他3張牌的種種排列組合已經計算好了。只能與換的那種牌組合了。如果其他3張牌組合好了與第4張牌在一起並不能得到結果,那麼也並不代表無解。只是這種方法行不通。那麼應該拋棄這樣的組合方式,並重新計算(從效率上來說,等同於這樣的演算法不需要再計算,程序的表達上,這點也較有難度)。 人腦計算時,如果4張牌裡面有相同的牌的話, 如果相同的牌不是24的因數,通常是優先把這樣的牌給計算掉,假設4張牌為[a1,b1,c,d](後接數字,數字相同的代表數值相等),那麼一般會先這樣拆 (a1?c)?(b1?d) ,把相同的牌盡量和其他的牌組合,生成24的因數。如 5,5,3,2 這樣的牌,我們會馬上反映出 5+3=8 5-2=3 3*8=24,那麼換成程序來說,4張牌的優先順序可能為[a1,c,b1,d],當a1,c經過計算得到新值e時,排列為[b1,d,e] 如果相同的牌是24的因數。那麼我們可能會保留一個,並計算其他3張能否湊成另一個需要的因數。如牌8,8,2,3 我們會優先計算 8*(8-2-2)。而程序上來說,4個數的優先程度是[a1,c,d,b1]上面只分析了部分常見情況,細分下來非常多,並且在程序里實現起來有點難度。不過如果分得很細了。條件判斷所用的時間視為0。而每次擬人的計算過程用setInterval(時間周期模擬人腦的一個計算周期),而不是簡單的for來算的話。可能那個24點的程序就很完善了。輸入一些參數,設置能模擬出不同的人在牌放置的位置時,計算所用的時間。如果下一次的4張牌剛好和上盤的4張牌一樣或重復了3張優先計算的牌,就會像人一樣馬上靠回憶而不是計算得出結果。 24點的撲克游戲,一個很簡單的游戲,如果想復雜了,也是個不得了的東西。
這樣可以么?

㈦ 求「日梭萬年歷」網路版源碼,或計算24節氣方法

struct ConvDate
{
int Source;
int SolarYear;
int SolarMonth;
int SolarDate;
int LunarYear;
int LunarMonth;
int LunarDate;
int Weekday;
int Kan;
int Chih;
};

unsigned __int64 m_ui64SolarTerms[24];
unsigned __int64 m_ui64MonthDays[13];

m_ui64MonthDays[0] = 0ui64;
m_ui64MonthDays[1] = 31ui64;
m_ui64MonthDays[2] = 28ui64;
m_ui64MonthDays[3] = 31ui64;
m_ui64MonthDays[4] = 30ui64;
m_ui64MonthDays[5] = 31ui64;
m_ui64MonthDays[6] = 30ui64;
m_ui64MonthDays[7] = 31ui64;
m_ui64MonthDays[8] = 31ui64;
m_ui64MonthDays[9] = 30ui64;
m_ui64MonthDays[10] = 31ui64;
m_ui64MonthDays[11] = 30ui64;
m_ui64MonthDays[12] = 31ui64;

m_ui64SolarTerms[0] = 0ui64;
m_ui64SolarTerms[1] = 21208ui64;
m_ui64SolarTerms[2] = 42467ui64;
m_ui64SolarTerms[3] = 63836ui64;
m_ui64SolarTerms[4] = 85337ui64;
m_ui64SolarTerms[5] = 107014ui64;
m_ui64SolarTerms[6] = 128867ui64;
m_ui64SolarTerms[7] = 150921ui64;
m_ui64SolarTerms[8] = 173149ui64;
m_ui64SolarTerms[9] = 195551ui64;
m_ui64SolarTerms[10] = 218072ui64;
m_ui64SolarTerms[11] = 240693ui64;
m_ui64SolarTerms[12] = 263343ui64;
m_ui64SolarTerms[13] = 285989ui64;
m_ui64SolarTerms[14] = 308563ui64;
m_ui64SolarTerms[15] = 331033ui64;
m_ui64SolarTerms[16] = 353350ui64;
m_ui64SolarTerms[17] = 375494ui64;
m_ui64SolarTerms[18] = 397447ui64;
m_ui64SolarTerms[19] = 419210ui64;
m_ui64SolarTerms[20] = 440795ui64;
m_ui64SolarTerms[21] = 462224ui64;
m_ui64SolarTerms[22] = 483532ui64;
m_ui64SolarTerms[23] = 504758ui64;

/* 24節氣計算 */

int __fastcall IsLeapYear(int iYear)
{
if ((iYear & 3) != 0)
{
return 0;
}
else if (iYear % 100 != 0)
{
return 1;
}
else if (iYear % 400 == 0)
{
return 1;
}
else
{
return 0;
}
}

int __fastcall TheSolarTerm(int iYear, int n)
{
unsigned __int64 k;
unsigned __int64 ddate_utc = 22085493000000ui64;
unsigned __int64 doffdate, dadddate;

doffdate = m_ui64SolarTerms[n] * 600000ui64;
doffdate += static_cast<unsigned __int64>(iYear - 1900) * 315569259747ui64;
doffdate -= ddate_utc;

doffdate /= 864000000ui64; //86400: 60 * 60 * 24 * 1000

int i = 1969;
dadddate = 0ui64;
while (dadddate < doffdate)
{
i++;
k = dadddate;
dadddate += 365ui64 + static_cast<unsigned __int64>(IsLeapYear(i));
};

if (dadddate > doffdate)
{
int j = 0;
dadddate = k;
while (dadddate < doffdate && j < 12)
{
j++;
k = dadddate;
dadddate += m_ui64MonthDays[j];
if (j == 2 && (IsLeapYear(i) != 0))
{
dadddate++;
}
};
return static_cast<int>(doffdate - k + 1ui64);
}
else // j = doffdate
{
return 1;
}
}

int CalConv(struct ConvDate &cd)
{
int leap, d, sm, y, im, l1, l2, acc, i, lm, kc;
if (cd.Source == 0) /* Solar */
{
if (cd.SolarYear <= FIRSTYEAR || cd.SolarYear > LASTYEAR)
{
return 1;
}
sm = cd.SolarMonth - 1;
if (sm < 0 || sm > 11)
{
return 2;
}
leap = GetLeap(cd.SolarYear);
d = (sm == 1) ? (leap + 28) : SolarCal[sm];
if (cd.SolarDate < 1 || cd.SolarDate > d)
{
return 3;
}
y = cd.SolarYear - FIRSTYEAR;
acc = SolarDays[leap][sm] + cd.SolarDate;
cd.Weekday = (acc + LunarCal[y].BaseWeekday) % 7;
kc = acc + LunarCal[y].BaseKanChih;
cd.Kan = kc % 10;
cd.Chih = kc % 12;
if (acc <= LunarCal[y].BaseDays)
{
y--;
cd.LunarYear = cd.SolarYear - 1;
leap = GetLeap(cd.LunarYear);
sm += 12;
acc = SolarDays[leap][sm] + cd.SolarDate;
}
else
{
cd.LunarYear = cd.SolarYear;
}
l1 = LunarCal[y].BaseDays;
for (i = 0; i < 13; i++)
{
l2 = l1 + LunarCal[y].MonthDays[i] + 29;
if (acc <= l2)
{
break;
}
l1 = l2;
}
cd.LunarMonth = i + 1;
cd.LunarDate = acc - l1;
im = LunarCal[y].Intercalation;
if (im != 0 && cd.LunarMonth > im)
{
cd.LunarMonth--;
if (cd.LunarMonth == im)
{
cd.LunarMonth = -im;
}
}
if (cd.LunarMonth > 12)
{
cd.LunarMonth -= 12;
}
}
else /* Lunar */
{
if (cd.LunarYear < FIRSTYEAR || cd.LunarYear >= LASTYEAR)
{
return 1;
}
y = cd.LunarYear - FIRSTYEAR;
im = LunarCal[y].Intercalation;
lm = cd.LunarMonth;
if (lm < 0)
{
if (lm != -im)
{
return 2;
}
}
else if (lm < 1 || lm > 12)
{
return 2;
}
if (im != 0)
{
if (lm > im)
{
lm++;
}
else if (lm == -im)
{
lm = im + 1;
}
}
lm--;
if (cd.LunarDate > LunarCal[y].MonthDays[lm] + 29)
{
return 3;
}
acc = LunarCal[y].BaseDays;
for (i = 0; i < lm; i++)
{
acc += LunarCal[y].MonthDays[i] + 29;
}
acc += cd.LunarDate;
leap = GetLeap(cd.LunarYear);
for (i = 13; i >= 0; i--)
{
if (acc > SolarDays[leap][i])
{
break;
}
}
cd.SolarDate = acc - SolarDays[leap][i];
if (i <= 11)
{
cd.SolarYear = cd.LunarYear;
cd.SolarMonth = i + 1;
}
else
{
cd.SolarYear = cd.LunarYear + 1;
cd.SolarMonth = i - 11;
}
leap = GetLeap(cd.SolarYear);
y = cd.SolarYear - FIRSTYEAR;
acc = SolarDays[leap][cd.SolarMonth - 1] + cd.SolarDate;
cd.Weekday = (acc + LunarCal[y].BaseWeekday) % 7;
kc = acc + LunarCal[y].BaseKanChih;
cd.Kan = kc % 10;
cd.Chih = kc % 12;
}

return 0;
}

㈧ 二進制的原碼、補碼、反碼詳解

計算機中,並沒有原碼和反碼,只是使用補碼,代表正負數。

使用補碼的意義:可以把減法或負數,轉換為加法運算。從而簡化計算機的硬體。

------------

比如鍾表,時針轉一圈,周期是 12 小時。

倒撥 3 小時,可以用正撥 9 小時代替。

9,就稱為-3 的補數。

計算方法:12-3 = 9。

對於分針,倒撥 X 分,就可以用正撥 60-X 代替。

------------

如果,限定了兩位十進制數 (0~99),周期就是 100。

那麼,減一,就可以用 +99 代替。

24-1 = 23

24 + 99 = (1) 23

忽略進位,只取兩位數,這兩種演算法,結果就是相同的。

於是,99 就是 -1 的補數。

其它負數的補數,大家可以自己求!

求出了負數的補數,就可用加法,代替減法了。

------------

計算機中使用二進制,補數,就改稱為【補碼】。

常用的八位二進制是:0000 0000~1111 1111。

它們代表了十進制:0~255,周期就是 256。

那麼,-1,就可以用 255 = 1111 1111 代替。

所以:-1 的補碼,就是 1111 1111 = 255。

同理:-2 的補碼,就是 1111 1110 = 254。

繼續:-3 的補碼,就是 1111 1101 = 253。

。。。

最後:-128,補碼是 1000 0000 = 128。

計算公式:負數的補碼=256+這個負數。

正數,直接運算即可,不需要求補碼。

也可以說,正數本身就是補碼。

------------

補碼的應用如: 7-3 = 4。

用補碼的計算過程如下:

7 的補碼=0000 0111

-3的補碼=1111 1101

--相加-------------

得:(1) 0000 0100 = 4 的補碼

舍棄進位,只保留八位,作為結果即可。

這就是:使用補碼,加法就代替了減法。

所以,在計算機中,有一個加法器,就夠用了。

原碼和反碼,都沒有這種功能。

------------

原碼和反碼,毫無用處。計算機中,根本就沒有它們。

閱讀全文

與24的源碼過程相關的資料

熱點內容
歐洲cf玩什麼伺服器 瀏覽:527
如何連接另一台電腦上的共享文件夾 瀏覽:679
如何讓桌面文件夾搬家到e盤 瀏覽:71
java自動格式化 瀏覽:617
ipad怎麼查看文件夾大小 瀏覽:581
手工粘土解壓球 瀏覽:550
在線視頻教育源碼 瀏覽:39
快四十學什麼編程 瀏覽:754
gnumakelinux 瀏覽:537
視易峰雲伺服器怎麼改系統 瀏覽:535
javamap取值 瀏覽:768
mac和win磁碟加密軟體 瀏覽:474
蘋果為什麼會連接不到伺服器 瀏覽:726
pdf格式文件如何保存 瀏覽:303
小霸王伺服器tx什麼意思 瀏覽:75
解釋dns命令 瀏覽:584
dmx512怎麼編程 瀏覽:744
北京雲主機17t雲伺服器 瀏覽:232
php伺服器url地址 瀏覽:440
哪裡看書免費app 瀏覽:437