导航:首页 > 源码编译 > 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的源码过程相关的资料

热点内容
java常用的服务器 浏览:277
集结APP在哪里下载 浏览:798
欧洲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