c語言24i
① c語言紙牌速算24原理
/* 計算24是流行的撲克游戲。其方法是任意取出4張牌,A J Q K 王牌 算 1,其它牌按點數計算,花色不計。
目標是通過加、減、乘、除和括弧最終算出24。設計一個程序,輸入4個數字(1~10),則列出所有可能計算
結果為24的方案。要求:
方案不能重復(加法乘法交換律等算不同方案)。
計算中局部可以為分數,結果為整數即可(如 3 3 7 7 演算法: (3 + 3/7)*7)
如果沒有找到方案輸出:無解。
在某些可不用括弧的地方不用括弧(即去掉括弧後等式的解不變)
待完善:
1)除數不能為零沒考慮(不用考慮可正常運行)
*/
#include<stdio.h>
#include<malloc.h>
int zuheshu(float s[],int n); // 組合數的函數
float zuhe[4]={0}; // 暫時存放組合
int sum=0; // 用於計數
// 動態分配n個float變數的數組
float * fsz(int n)
{
return (float *)malloc(sizeof(float)*n);
}
int zuhefu(); //符號組合
int yunsuan(float s[],char p[],int k0[],int k1[]); // 算式組合
float qiujie(float suanshi[],int n); // 算式求解
int hefa(float suanshi[],int r); // 算式正確性檢查
float jianjie(float suanshi[],int r); // 算式簡潔性檢查
int fuhe=0; // 計數符合算式數
void main()
{
// 輸入四個數
//float shu[4]={0};
//printf("請輸入4個數字(1~10):\n");
//scanf("%f",&shu[0]);
//scanf("%f",&shu[1]);
//scanf("%f",&shu[2]);
//scanf("%f",&shu[3]);
//float shu[4]={1,2,3,4};
//printf("輸入的4個數字依此是: %.0f %.0f %.0f %.0f\n",shu[0],shu[1],shu[2],shu[3]);
//float s[4]={3,3,3,3},shu[4]={0};
//printf("請輸入四個數(0-9):\n");
for(int i=0;i<4;i++)
{
scanf("%f",&s[i]);
for(int j=i;j>0;j--)
{
if(s[j]<=s[j-1])
{
float s0=s[j-1];
s[j-1]=s[j];
s[j]=s0;
}
}
}
printf("四個數是:");
for(i=0;i<4;i++)
{
printf("%.0f ",s[i]);
}
printf("\n");
zuheshu(s,4);
printf("有%d個算式符合\n",fuhe);
}
// 組合數,並調用yunsuan
int zuheshu(float s[],int n)
{
if(n==1)
{
zuhe[4-n]=s[0];
zuhefu();
return 1;
}
for(int i=0;i<n;i++)
{
if(i==0)
{
// 直接填入s[0],數組和候選數中去除該數,遞歸
zuhe[4-n]=s[i];
float *p=fsz(n-1);
int o=0;
for(int k=0;k<n;k++)
{
if(k!=i)
p[o++]=s[k];
}
zuheshu(p,n-1);
free(p);
}
else if(s[i]!=s[i-1])
{
// 直接填入s[0],數組和候選數中去除該數,遞歸
zuhe[4-n]=s[i];
float *p=fsz(n-1);
int o=0;
for(int k=0;k<n;k++)
{
if(k!=i)
p[o++]=s[k];
}
zuheshu(p,n-1);
free(p);
}
}
}
// 組合運算符號,並調用yunsuan
int zuhefu()
{
// 對操作符'+','—','*','/'組合
char opter[4]={'+','-','*','/'};
for(int h=0;h<4;h++) // 第一個操作符
{
for(int i=0;i<4;i++) // 第二個操作符
{
for(int j=0;j<4;j++) // 第三個操作符
{
char op[3]; // 放置操作符
op[0]=opter[h];
op[1]=opter[i];
op[2]=opter[j];
// 對括弧組合
// 0 1 1 1 2 2 2 3
int khzh[8][3]={{0,0,0},{0,0,1},{0,1,0},{1,0,0},{0,1,1},{1,0,1},{1,1,0},{1,1,1}}; // 正或反括弧
for(int k=0;k<=3;k++)
{
switch(k)
{
case 0: // 有0個括弧
{
yunsuan(zuhe,op,khzh[0],khzh[0]);
}
break;
case 1: // 有1個括弧
{
for(int m=1;m<=3;m++) // 正括弧
{
for(int n=1;n<=3;n++) //反括弧
{//代碼將算式組合,並判斷正確性;其中(括弧)010和100為錯誤組合,010和010無錯誤組合,001和100為錯誤組合,
//同時100和001可視做無括弧應過濾(即正括弧後接操作數,操作符,不能是操作數,反括弧)
//正確組合有六組
if((m==2&&n==3)||(m==1&&n==2)||(m==3&&n==1)||(m==1&&n==3))
continue;
yunsuan(zuhe,op,khzh[m],khzh[n]);
}
}
}
break;
case 2: // 有2個括弧
{
//代碼將算式組合,並判斷正確性;其中(括弧)*1*和1**為錯誤組合,**1和*1*為錯誤組合,
//應過濾(即正括弧後接操作數,操作符,不能是操作數,反括弧)同時出現1**和**1也應視為0**和**0
//正確括法只有一種即101和101
yunsuan(zuhe,op,khzh[5],khzh[5]);
}
break;
case 3: //有3個括弧,不可能
//利用khzu[7]代碼將算式組合,並判斷正確性(不正確)
break;
}
}
}
}
}
return 1;
}
// 對s[]中的四個數按照p[]和k[]中的運算符進行組合並調用qiujie()函數運算判斷結果是否為24
int yunsuan(float s[],char p[],int k0[],int k1[])
{
float suanshi0[13]={'0'}; // 合成等式
int r=0; // 等式的長度
// 組合等式
for(int q=0;q<13;q++)
{
switch(q)
{
case 0:
{
if(k0[0]==1)
suanshi0[r++]='(';
}
break;
case 1:
{
suanshi0[r++]=s[0];
}
break;
case 2:
{
suanshi0[r++]=p[0];
}
break;
case 3:
{
if(k0[1]==1)
suanshi0[r++]='(';
}
break;
case 4:
{
suanshi0[r++]=s[1];
}
break;
case 5:
{
if(k1[0]==1)
suanshi0[r++]=')';
}
break;
case 6:
{
suanshi0[r++]=p[1];
}
break;
case 7:
{
if(k0[2]==1)
suanshi0[r++]='(';
}
break;
case 8:
{
suanshi0[r++]=s[2];
}
break;
case 9:
{
if(k1[1]==1)
suanshi0[r++]=')';
}
break;
case 10:
{
suanshi0[r++]=p[2];
}
break;
case 11:
{
suanshi0[r++]=s[3];
}
break;
case 12:
{
if(k1[2]==1)
suanshi0[r++]=')';
}
break;
}
}
float * suanshi=fsz(r); // 動態空間申請
for(int i=0;i<r;i++)
{
suanshi[i]=suanshi0[i];
}
// 組合算式的正確性檢查
float f=hefa(suanshi,r);
if(f==0)
{
return 0;
}
// 組合算式的簡潔性檢查
f=jianjie(suanshi,r);
if(f==0)
{
return 0;
}
// 調用函數求解結果為24則輸出等式
float sum0=qiujie(suanshi,r);
if(sum0==24)
{
fuhe++;
for(int t=0;t<r;t++)
{
if(suanshi[t]>10)
printf("%c",char(suanshi[t]));
else
printf("%0.0f",suanshi[t]);
}
printf("=%0.0f\n",sum0);
}
free(suanshi);
return 1;
}
// 算式正確性檢查
int hefa(float suanshi[],int r)
{
float * p=&suanshi[0]; // 為當前指針
float * q=&suanshi[1]; // 為下一指針
int flag=1; // 等式正確標記
while(1)
{
if(*p==40) // 判斷是否為'('
{
if((*q>=0)&&(*q<=9))
{
p++;
q++;
}
else
{
flag=0;
break;
}
}
if((*p>=0)&&(*p<=9)) // 判斷是否為數
{
if((p-suanshi)>=(r-1))
{
break;
}
if(*q==')'||((*q>41)&&(*q<48))) // '+','-','*','/'在次范圍內
{
p++;
q++;
}
else
{
flag=0;
break;
}
}
if(*p==41) // 判斷是否為')'
{
if((p-suanshi)>=(r-1))
{
break;
}
if((*q>41)&&(*q<48)) // '+','-','*','/'在次范圍內
{
p++;
q++;
}
else
{
flag=0;
break;
}
}
if((*p>41)&&(*p<48)) // // 判斷是否為符號
{
if(*q==40||((*q>=0)&&(*q<=9)))
{
p++;
q++;
}
else
{
flag=0;
break;
}
}
}
return flag;
}
// 算式簡潔性檢查
float jianjie(float suanshi[],int r)
{
float re=1; // 是否括弧不影響算式求解
float *p=&re,*q=&re;
int k=0; // 括弧數目
int k1=0; // 運算符的個數
float r0=0; // '('前的運算符優先順序
float r2=1; // 算式運算符優先順序
float r1=0; // ')'後的運算符優先順序
int r3=0;
for(int i=0;i<r;i++)
{
if(suanshi[i]=='(')
{
k++;
if(*p!='('||k==1)
{
p=&suanshi[i];
if(i!=0)
{
if(*(p-1)=='+'||*(p-1)=='-')
{
r0=1;
}
else if(*(p-1)=='*'||*(p-1)=='/')
{
r0=2;
}
if(*(p-1)=='-')
{
r0+=100;
}
else if(*(p-1)=='/')
{
r0+=1000;
}
}
}
}
else if(suanshi[i]==')')
{
if(k--==1)
{
q=&suanshi[i];
if(i!=r-1)
{
if(*(q+1)=='+'||*(q+1)=='-')
{
r1=1;
}
else if(*(q+1)=='*'||*(q+1)=='/')
{
r1=2;
}
}
//遞歸
re=jianjie(p+1,q-p-1); // 返回括弧內的優先順序
if(int(r0/100)>=1) // 括弧'('外出現減號或除號
{
if((int(r0/100))==1&&(int(re/100))==1) // 括弧'('外出現減號,括弧內出現+或-
{
continue;
}
else if((int(r0/1000))==1&&(int(re/1000))==1) // 括弧'('外出現除號,括弧內出現*或/
{
continue;
}
}
if(int(re/100)==1)
re-=100;
if(int(re/1000)==1)
re-=1000;
if(int(r0/100)==1)
r0-=100;
else if(int(r0/1000)==1)
r0-=1000;
if(re==0)
return 0;
if(re>=r0&&re>=r1)
return 0;
}
}
else if(k==0)
{
if(suanshi[i]=='+'||suanshi[i]=='-')
{
r2=((r2*k1)+1)/(++k1);
r3=r3/10+1;
}
else if(suanshi[i]=='*'||suanshi[i]=='/')
{
r2=(r2*k1+2)/(++k1);
r3=r3%10+10;
}
}
}
if(r3%10==1)
r2+=100;
if(r3/10==1)
r2+=1000;
return r2;
}
// 調用函數求解結果為24則輸出等式
float qiujie(float suanshi[],int n)
{
if(n==3)
{
float a=0;
switch(char(suanshi[1]))
{
case '+':
return (suanshi[0]+suanshi[2]);
case '-':
return (suanshi[0]-suanshi[2]);
case '*':
return (suanshi[0]*suanshi[2]);
case '/':
return (suanshi[0]/suanshi[2]);
}
}
// 過濾掉括弧項
float pq='0';
float * p=&pq; // 指向算式的第一個正括弧
float * q=&pq; // 指向算式的與第一個正括弧配對的反括弧
int k=0;
float suanshi1[7]={'0'}; // 除去括弧後的算式
int s=0; // 用來記錄suanshi1數組的長度
float sum=0; // 算式的值
for(int m=0;m<n;m++)
{
if(suanshi[m]=='(')
{
k++;
if((*p)!='(')
{
p=&suanshi[m];
}
continue;
}
if(suanshi[m]==')')
{
if(k--==1)
{
q=&suanshi[m];
suanshi1[s++]=qiujie(p+1,q-p-1);
p=&pq;
q=&pq;
}
continue;
}
if(k==0)
{
suanshi1[s++]=suanshi[m];
continue;
}
}
if(s==3)
{
sum=qiujie(suanshi1,s);
}
else
{
p=&suanshi1[0]; // 指向第一個數
q=&suanshi1[2]; // 只想第二個數
for(m=0;m<(s-1)/2;m++)
{
switch(char(suanshi1[2*m+1]))
{
case '+':
if((s-1)/2!=1&&(suanshi1[2*(m+1)+1]=='*'||suanshi1[2*(m+1)+1]=='/'))
{
*q=qiujie(p+2,3);
int ws=&suanshi1[s-1]-&suanshi1[2*(m+1)];
for(int w=1;w<=ws;w++)
{
if(((q+w+2)-(q+ws))>0)
{
*(q+w)=-1;
}
else
{
*(q+w)=*(q+w+2);
}
}
s=s-2;
m--;
}
else
{
if(m==0)
{
sum+=*p+*q;
}
else
{
sum+=*q;
}
p=p+2;
q=q+2;
}
break;
case '-':
if((s-1)/2!=1&&(suanshi1[2*(m+1)+1]=='*'||suanshi1[2*(m+1)+1]=='/'))
{
*q=qiujie(p+2,3);
int ws=&suanshi1[s-1]-&suanshi1[2*(m+1)];
for(int w=1;w<=ws;w++)
{
if(((q+w+2)-(q+ws))>0)
{
*(q+w)=-1;
}
else
{
*(q+w)=*(q+w+2);
}
}
s=s-2;
m=-1;
}
else
{
if(m==0)
sum+=*p-*q;
else
sum-=*q;
p=p+2;
q=q+2;
}
break;
case '*':
if(m==0)
sum+=(*p)*(*q);
else
sum*=*q;
p=p+2;
q=q+2;
break;
case '/':
if(m==0)
{
sum+=(*p)/(*q);
}
else
{
sum/=*q;
}
p=p+2;
q=q+2;
break;
}
}
}
return sum;
}
② 用c語言編寫,關於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]);
}
}
}
}
}
}
③ 如何用C語言編寫一個24點的游戲
(已經調試)
#define N 20
#define COL 100
#define ROW 40
#include "stdio.h"
#include "time.h" /*系統時間函數*/
#include "graphics.h" /*圖形函數*/
#include "alloc.h"/*動態地址分配函數*/
#include "stdlib.h" /*庫函數*/
#include "string.h" /*字元串函數*/
#include "ctype.h" /*字元操作函數*/
char p[4][13]={
{'A','2','3','4','5','6','7','8','9','0','J','Q','K'},/*撲克牌,10用0來表示*/
{'A','2','3','4','5','6','7','8','9','0','J','Q','K'},
{'A','2','3','4','5','6','7','8','9','0','J','Q','K'},
{'A','2','3','4','5','6','7','8','9','0','J','Q','K'}};
typedef struct node
{
int data;
struct node *link;
}STACK1; /*棧1*/
typedef struct node2
{
char data;
struct node2 *link;
}STACK2; /*棧2*/
void init(void);/*圖形驅動*/
void close(void);/*圖形關閉*/
void play(void);/*發牌的具體過程*/
void rand1(int j);/*隨機發牌函數*/
void change(char *e,char *a); /*中綴變後綴函數*/
int computer(char *s); /*後綴表達式計算函數*/
STACK1 *initstack1(STACK1 *top); /*棧1初始化*/
STACK1 *push(STACK1 *top,int x); /*棧1入棧運算*/
STACK1 *pop(STACK1 *top); /*棧1刪除棧頂元素*/
int topx(STACK1 *top); /*棧1讀棧頂元素*/
STACK1 *ptop(STACK1 *top,int *x); /*棧1讀出棧頂元素值並刪除棧頂元素*/
int empty(STACK1 *top); /*判棧1是否為空函數*/
STACK2 *initstack2(STACK2 *top); /*棧2初始化*/
STACK2 *push2(STACK2 *top,char x); /*棧2入棧運算*/
STACK2 *pop2(STACK2 *top); /*棧2刪除棧頂元素*/
char topx2(STACK2 *top); /*棧2讀棧頂元素*/
STACK2 *ptop2(STACK2 *top,char *x); /*棧2讀出棧頂元素值並刪除棧頂元素*/
int empty2(STACK2 *top); /*判棧2是否為空函數*/
int text1(char *s) ; /*顯示文本*/
main()
{
char s[N],s1[N],ch;
int i,result;
int gdriver, gmode;
clrscr(); /*清屏*/
init(); /*初始化函數*/
while(1)
{
setbkcolor(BLACK); /*設置背景顏色*/
cleardevice();/*清屏*/
play(); /*發牌*/
gotoxy(1,15); /*移動游標*/
printf("--------------------Note-------------------\n");
printf(" Please enter express accroding to above four number\n"); /*提示信息*/
printf(" Format as follows:2.*(5.+7.)\n");/*提示輸入字元串格式*/
printf(" ----------------------------------------------\n");
scanf("%s%c",s1,&ch); /*輸入字元串壓回車鍵*/
change(s1,s); /*調用change函數將中綴表達式s1轉換為後綴表達式s*/
result=computer(s); /*計算後綴表達式的值,返回結果result */
if(result==24) /*如果結果等於24*/
text1("very good"); /*調用函數text1顯示字元串"very good"*/
else
text1("wrong!!!");/*否則函數text1顯示字元串"wrong!!!"*/
printf("Continue (y/n)?\n"); /*提示信息,是否繼續*/
scanf("%c",&ch); /*輸入一字元*/
if(ch=='n'||ch=='N') /*如果該字元等於n或N*/
break; /*跳出循環,程序結束*/
} /*否則,開始下一輪循環*/
close();
return; /*返回*/
}
void rand1(int j)/*隨機發牌函數*/
{
int kind,num;
char str[3],n;
randomize();
while(1)/*循環直到有牌發*/
{
kind=random(4); /*花色隨機數*/
num=random(13); /*大小隨機數*/
if(p[kind][num]!=-1) /*該數未取過*/
{
n=p[kind][num]; /*取相應位置的撲克牌數*/
p[kind][num]=-1; /*牌發好以後相應位置的元素置-1*/
break;
}
}
switch(kind)/*花式的判斷*/
{
case 0:setcolor(RED);sprintf(str,"%c",3);break; /*紅桃*/
case 1:setcolor(BLACK);sprintf(str,"%c",3);break; /*黑桃*/
case 2:setcolor(RED);sprintf(str,"%c",4);break; /*方片*/
case 3:setcolor(BLACK);sprintf(str,"%c",5);break; /*草花*/
}
settextstyle(0,0,2);
outtextxy(COL+j*100-30,ROW+100-46,str);/*顯示左上角花色*/
outtextxy(COL+j*100+16,ROW+100+32,str); /*顯示右下角花色*/
if(n!='0')/*輸出其他牌*/
{
settextstyle(0,0,3);
sprintf(str,"%c",n);
outtextxy(COL+j*100-5,ROW+100-5,str);/*顯示牌的大小*/
}
else/*輸出10的時候*/
{
sprintf(str,"%d",10);
outtextxy(COL+j*100-6,ROW+100-5,str);
}
}
void play(void)/*發牌的具體過程*/
{
int j;
for(j=0;j<4;j++)
{
bar(COL+j*100-35,ROW+100-50,COL+j*100+35,ROW+1*100+50);/*畫空牌*/
setcolor(BLUE);
rectangle(COL+j*100-32,ROW+100-48,COL+j*100+32,ROW+100+48); /*畫矩形框*/
rand1(j); /*隨機取牌*/
delay(10000); /*延時顯示*/
}
}
void init(void)/*圖形驅動*/
{
int gd=DETECT,gm;
initgraph(&gd,&gm,"c:\\tc");
cleardevice();
}
void close(void)/*圖形關閉*/
{
closegraph();
}
void change(char *e,char *a) /*中綴字元串e轉後綴字元串a函數*/
{
STACK2 *top=NULL; /* 定義棧頂指針*/
int i,j;char w;
i=0;
j=0;
while(e[i]!='\0') /*當字元串沒有結束時*/
{
if(isdigit(e[i])) /*如果字元是數字*/
{
do{
a[j]=e[i]; /*將數字原樣拷貝到數組a中*/
i++; /*e數組的下標加1*/
j++; /*a數組的下標加1*/
}while(e[i]!='.'); /*直到字元為數字結束符「.」為止*/
a[j]='.';j++; /*將數字結束符「.」拷貝到a數組依然保持結束標記*/
}
if(e[i]=='(') /*如果字元是「(」時*/
top=push2(top,e[i]); /*將其壓入堆棧*/
if(e[i]==')') /*如果字元是「)」時*/
{
top=ptop2(top,&w); /*取出棧頂元素,並從棧頂刪除該元素*/
while(w!='(') /*如果字元不是「(」時反復循環*/
{
a[j]=w; /*將棧頂元素存入a數組*/
j++; /*下標加1*/
top=ptop2(top,&w) ; /*取出棧頂元素,並從棧頂刪除該元素*/
}
}
if(e[i]=='+'||e[i]=='-') /*如果字元是加或減號時*/
{
if(!empty2(top)) /*如棧不為空*/
{
w=topx2(top);
while(w!='(') /*當棧頂元素不是「(」時反復循環*/
{
a[j]=w;
j++; /*將棧頂元素存入表達式a中,a的下標加1*/
top=pop2(top); /*刪除棧頂元素*/
if(empty2(top)) /*如果棧為空*/
break; /*跳出循環*/
else
w=topx2(top); /*否則讀棧頂元素*/
}
}
top=push2(top,e[i]); /*將當前e的字元元素壓入堆棧*/
}
if(e[i]=='*'||e[i]=='/') /*如果字元是乘或除號時*/
{
if(!empty2(top)) /*如棧不為空*/
{
w=topx2(top); /*讀棧頂元素存入w*/
while(w=='*'||w=='/')/*當棧頂元素是乘或除時反復循環*/
{
a[j]=w;
j++; /*將棧頂元素存入字元串a中,a的下標加1*/
top=pop2(top); /*刪除棧頂元素*/
if(empty2(top)) /*如果棧為空*/
break; /*跳出循環*/
else
w=topx2(top); /*否則讀棧頂元素*/
}
}
top=push2(top,e[i]); /*將當前e字元元素壓入堆棧*/
}
i++; /*e的下標加1*/
}
while(!empty2(top)) /*當不為空時反復循環*/
top=ptop2(top,&a[j++]); /*將棧頂元素存入數組a中*/
a[j]='\0'; /*將字元串結束標記寫入最後一個數組元素中構成字元串*/
}
int computer(char *s) /* 計算函數*/
{
STACK1 *top=NULL;
int i,k,num1,num2,result;
i=0;
while(s[i]!='\0') /*當字元串沒有結束時作以下處理*/
{
if(isdigit(s[i])) /*判字元是否為數字*/
{
k=0; /*k初值為0*/
do{
k=10*k+s[i]-'0'; /*將字元連接為十進制數字*/
i++; /*i加1*/
}while(s[i]!='.'); /*當字元不為『.』時重復循環*/
top=push(top,k); /*將生成的數字壓入堆棧*/
}
if(s[i]=='+') /*如果為'+'號*/
{
top=ptop(top,&num2); /*將棧頂元素取出存入num2中*/
top=ptop(top,&num1); /*將棧頂元素取出存入num1中*/
result=num2+num1; /*將num1和num2相加存入result中*/
top=push(top,result); /*將result壓入堆棧*/
}
if(s[i]=='-') /*如果為'-'號*/
{
top=ptop(top,&num2); /*將棧頂元素取出存入num2中*/
top=ptop(top,&num1); /*將棧頂元素取出存入num1中*/
result=num1-num2; /*將num1減去num2結果存入result中*/
top=push(top,result); /*將result壓入堆棧*/
}
if(s[i]=='*') /*如果為'*'號*/
{
top=ptop(top,&num2); /*將棧頂元素取出存入num2中*/
top=ptop(top,&num1); /*將棧頂元素取出存入num1中*/
result=num1*num2; /*將num1與num2相乘結果存入result中*/
top=push(top,result); /*將result壓入堆棧*/
}
if(s[i]=='/') /*如果為'/'號*/
{
top=ptop(top,&num2); /*將棧頂元素取出存入num2中*/
top=ptop(top,&num1); /*將棧頂元素取出存入num1中*/
result=num1/num2; /*將num1除num2結果存入result中*/
top=push(top,result); /*將result壓入堆棧*/
}
i++; /*i加1*/
}
top=ptop(top,&result); /*最後棧頂元素的值為計算的結果*/
return result; /*返回結果*/
}
STACK1 *initstack1(STACK1 *top) /*初始化*/
{
top=NULL; /*棧頂指針置為空*/
return top; /*返回棧頂指針*/
}
STACK1 *push(STACK1 *top,int x) /*入棧函數*/
{
STACK1 *p; /*臨時指針類型為STACK1*/
p=(STACK1 *)malloc(sizeof(STACK1)); /*申請STACK1大小的空間*/
if(p==NULL) /*如果p為空*/
{
printf("memory is overflow\n!!"); /*顯示內存溢出*/
exit(0); /*退出*/
}
p->data=x; /*保存值x到新空間*/
p->link=top; /*新結點的後繼為當前棧頂指針*/
top=p; /*新的棧頂指針為新插入的結點*/
return top; /*返回棧頂指針*/
}
STACK1 *pop(STACK1 *top) /*出棧*/
{
STACK1 *q; /*定義臨時變數*/
q=top; /*保存當前棧頂指針*/
top=top->link; /*棧頂指針後移*/
free(q); /*釋放q*/
return top; /*返回棧頂指針*/
}
int topx(STACK1 *top) /*讀棧頂元素*/
{
if(top==NULL) /*棧是否為空*/
{
printf("Stack is null\n"); /*顯示棧為空信息*/
return 0; /*返回整數0*/
}
return top->data; /*返回棧頂元素*/
}
STACK1 *ptop(STACK1 *top,int *x) /*取棧頂元素,並刪除棧頂元素*/
{
*x=topx(top); /*讀棧頂元素*/
top=pop(top); /*刪除棧頂元素*/
return top; /*返回棧頂指針*/
}
int empty(STACK1 *top) /*判棧是否為空*/
{
if(top==NULL) /*如果為空*/
return 1; /*返回1*/
else
return 0; /*否則返回0*/
}
STACK2 *initstack2(STACK2 *top) /*初始化*/
{
top=NULL; /*棧頂指針置為空*/
return top; /*返回棧頂指針*/
}
STACK2 *push2(STACK2 *top,char x) /*入棧函數*/
{
STACK2 *p; /*臨時指針類型為STACK2*/
p=(STACK2 *)malloc(sizeof(STACK2)); /*申請STACK2大小的空間*/
if(p==NULL) /*如果p為空*/
{
printf("memory is overflow\n!!"); /*顯示內存溢出*/
exit(0); /*退出*/
}
p->data=x; /*保存值x到新空間*/
p->link=top; /*新結點的後繼為當前棧頂指針*/
top=p; /*新的棧頂指針為新插入的結點*/
return top; /*返回棧頂指針*/
}
STACK2 *pop2(STACK2 *top) /*出棧*/
{
STACK2 *q; /*定義臨時變數*/
q=top; /*保存當前棧頂指針*/
top=top->link; /*棧頂指針後移*/
free(q); /*釋放q*/
return top; /*返回棧頂指針*/
}
char topx2(STACK2 *top) /*讀棧頂元素*/
{
if(top==NULL) /*棧是否為空*/
{
printf("Stack is null\n"); /*顯示棧為空信息*/
return ''; /*返回空字元*/
}
return top->data; /*返回棧頂元素*/
}
STACK2 *ptop2(STACK2 *top,char *x) /*取棧頂元素,並刪除棧頂元素*/
{
*x=topx2(top); /*讀棧頂元素*/
top=pop2(top); /*刪除棧頂元素*/
return top; /*返回棧頂指針*/
}
int empty2(STACK2 *top) /*判棧是否為空*/
{
if(top==NULL) /*如果為空*/
return 1; /*返回1*/
else
return 0; /*否則返回0*/
}
int text1(char *s)
{
setbkcolor(BLUE); /*設置背景顏色為藍色*/
cleardevice(); /*清除屏幕*/
setcolor(12); /*設置文本顏色為淡紅色*/
settextstyle(1, 0, 8);/*三重筆劃字體, 放大8倍*/
outtextxy(120, 120, s); /*輸出字元串s*/
setusercharsize(2, 1, 4, 1);/*水平放大2倍, 垂直放大4倍*/
setcolor(15); /*設置文本顏色為白色*/
settextstyle(3, 0, 5); /*無襯字筆劃, 放大5倍*/
outtextxy(220, 220, s); /*輸出字元串s*/
getch(); /*鍵盤輸入任一字元*/
return ; /*返回*/
}
④ C語言算24點
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
char op[3], o[5]="+-*/";
float n[4], on[10];
int used[4] = {0}, top=0, tp=0, x;
void chk(float k);
void search24(int d);
float calc(float n1, float n2, char o);
void make(int i, float p, float q, char o, int d);
int main( void )
{
printf("please input 4 card number: ");
scanf("%f%f%f%f", &n[0], &n[1], &n[2], &n[3]);
search24(0);
printf("No answer. ");
return 0;
}
void chk(float k)
{
if( (tp != 3) || ( fabs(k-24.0) > 0.000001 )) //沒有用完3個運算符或者結果不為24就退出.
return;
for(x=0; x<5; x+=2) //這樣設計是為了使3個選中的符號都可以得到輸出.
printf("%g%c%g=%g ", on[x], op[x/2], on[x+1], //分析得到的.
calc(on[x], on[x+1], op[x/2]));
system("pause");
exit(0);
}
float calc(float n1, float n2, char o)
{
switch(o){
case '+': return (n1+n2);
case '-': return (n1-n2);
case '*': return (n1*n2);
case '/': return (n1/n2);
default: exit(0);
}
}
void make(int i, float p, float q, char o, int d)
{
if(fabs(q)>0.000001 || o!='/') //除數不為0,或者為0的時候不能為除數.
n[i] = calc(p, q, o);
op[tp++] = o;
chk(n[i]);
search24(d+1);
tp--; //因為是全是全局變數,所以在做試驗性的循環遞歸問題時,如果失敗,要在遞歸函數後面重新恢復回原來的值
}
void search24(int d)
{
int i, j, k;
float p, q;
if(d>=3) //控制遞歸深度,就是運算符的輸出個數.
return;
for(i=0; i<4; i++)
for(j=0; j<4; j++)
if( (i!=j)&& (used[i]+used[j] == 0) ) //i!=j是防止重復,(used[i]+used[j] == 0)是防止又再匹配已經用過的j,
//但是i可以新來.
{
used[j] = 1; //j得到匹配之後,賦值為1,表示已經使用
p=n[i];
q=n[j];
on[top++] = p;
on[top++] = q;
for(k=0; k<4; k++) //運算符的循環試用.
make(i, p, q, o[k], d);
n[i] = p; //因為是全是全局變數,所以在做試驗性的循環遞歸問題時,
used[j] = 0; //如果失敗,要在遞歸函數後面重新恢復回原來的值
top -= 2; //
}
}
出處:http://blog.sina.com.cn/s/blog_491de9d60100d5er.html
⑤ C語言24點的演算法
下面是我自己寫的一個程序:
我的解法是把這個問題分解成了兩個子問題,首先求出4個數字的無重復全排列,放到一個數組裡面,再對沒一個排列情況,從頭到尾窮舉所有的四則運算情況。注意到除法是特殊的,我用x/y表示x除以y,用x|y表示x分之y。注意到,如果窮舉的解得到-24的話,只需要把有減法的地方調換一下順序就可以了,代碼如下
/***********************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int index[4]={0,1,2,3};//used to generate subscription collection
int sub[4]; //used in p() only
float f[4]={8.0f,3.0f,3.0f,8.0f};//the 24 point numbers
float fs[24][4];//all possible permutaions of f
float tmp[4]; //used for buf
int g_number=0; //number of permutations
float RES[4];
char op[3];
void p(int idx){//求全排列的函數
if(idx==4){
for(int i=0;i<4;++i){tmp[i]=f[sub[i]];}
for(int g=0;g<g_number;++g){if(memcmp(fs[g],tmp,sizeof(float)*4)==0)return;}
for(int i=0;i<4;++i){fs[g_number][i]=f[sub[i]];}
g_number++;
return;
}
for(int i=0;i<4;++i){//make subscription collections
bool pflag=false;
for(int j=0;j<idx;++j){if(sub[j]==i)pflag=true;}
if(pflag==true)continue;
sub[idx]=index[i];
p(idx+1);
}
}
void solve(int L){//對某個排列,遞歸求所有四則運算的結果,找到就退出
if(L==3){
if(fabs(fabs(RES[L])-24.0f)<0.01f){
printf("Found solution,RES=%f,((%d%c%d)%c%d)%c%d\n",RES[L],
(int)f[0],op[0],
(int)f[1],op[1],
(int)f[2],op[2],
(int)f[3]);
exit(0);
}
return;
}
for(int j=0;j<5;++j){//j judges for operators
if(j==0){RES[L+1]=RES[L]+tmp[L+1];op[L]='+';solve(L+1);}
if(j==1){RES[L+1]=RES[L]-tmp[L+1];op[L]='-';solve(L+1);}
if(j==2){RES[L+1]=RES[L]*tmp[L+1];op[L]='*';solve(L+1);}
if(j==3&&tmp[L+1]!=0)
{RES[L+1]=RES[L]/tmp[L+1];op[L]='/';solve(L+1);}
if(j==4&&RES[L+1]!=0)
{RES[L+1]=tmp[L+1]/RES[L];op[L]='|';solve(L+1);}
}
}
int main(int argc,char* argv[]){//should avoid 0
f[0]=atoi(argv[1]);
f[1]=atoi(argv[2]);
f[2]=atoi(argv[3]);
f[3]=atoi(argv[4]);
p(0);
for(int i=0;i<g_number;++i){
memcpy(tmp,fs[i],sizeof(float)*4);
RES[0]=tmp[0];
for(int t=0;t<4;++t){ printf("%d,",(int)tmp[t]); }
printf("\n");
solve(0);
}
printf("Found no solution :( \n");
return 0;
}
----------編譯運行,運行時的參數就是4個數字
g++ p.cpp && ./a.out 1 5 5 5
1,5,5,5,
Found solution,RES=-24.000000,((1/5)-5)*5
g++ p.cpp && ./a.out 8 3 3 8
8,3,3,8,
Found solution,RES=-24.000006,((8/3)-3)|8
上面這個解寫出來就是
8
--------- = 24
3-(8/3)
主程序為了簡化,省去了對輸入的檢查,樓主可以自己添加。