亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問板塊 發(fā)新帖
查看: 6168 | 回復(fù): 5
打印 上一主題 下一主題

我用C寫的一個(gè)算24點(diǎn)代碼。 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2006-03-24 11:16 |只看該作者 |倒序?yàn)g覽
主要是使用逆波蘭表達(dá)式的求值。歡迎測(cè)試和指正!


  1. /* cal24.c
  2. * given N integer numbers
  3. * find one expression which produces value T using all
  4. * the N numbers and {+,-,*,/} operators
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>

  9. #define N 4  /* number of cards    */
  10. #define T 24 /* target solution    */
  11. #define M 13 /* maximum card value */
  12. #define STACK_SIZE (N+N-1)
  13. #define EPS 1e-6
  14. #define ADD M+1
  15. #define SUB M+2
  16. #define MUL M+3
  17. #define DIV M+4

  18. /* evaluate an expression in reverse Polish notation (RPN) */
  19. double eval(int expr[])
  20. {
  21.     double oprnds[N],oprnd1,oprnd2;
  22.     int top = -1,i,op;
  23.     for(i = 0;i<STACK_SIZE;++i){
  24.         op = expr[i];
  25.         if(op<=M){
  26.             oprnds[++top] = (double)op;
  27.             continue;
  28.         }
  29.         oprnd1 = oprnds[top--];
  30.         oprnd2 = oprnds[top--];
  31.         switch(op){
  32.         case ADD: oprnd1 += oprnd2; break;
  33.         case SUB: oprnd1 -= oprnd2; break;
  34.         case MUL: oprnd1 *= oprnd2; break;
  35.         case DIV:
  36.             if(oprnd2<EPS && oprnd2>-EPS) return 0.0;
  37.             oprnd1 /= oprnd2;
  38.         }
  39.         oprnds[++top] = oprnd1;
  40.     }
  41.     return oprnds[top];
  42. }

  43. int succ(int expr[])
  44. {
  45.     double x = eval(expr);
  46.     if(x>T-EPS && x<T+EPS) return 1;
  47.     return 0;
  48. }

  49. /* just to make the expression more readable by human */
  50. void printsolution(int expr[])
  51. {
  52.     double oprnds[N],oprnd1,oprnd2,result;
  53.     int top = -1,i,op;
  54.     char c;
  55.     for(i = 0;i<STACK_SIZE;++i){
  56.         op = expr[i];
  57.         if(op<=M){
  58.             oprnds[++top] = (double)op;
  59.             continue;
  60.         }
  61.         oprnd1 = oprnds[top--];
  62.         oprnd2 = oprnds[top--];
  63.         switch(op){
  64.         case ADD:
  65.             c = '+';
  66.             result = oprnd1 + oprnd2;
  67.             break;
  68.         case SUB:
  69.             c = '-';
  70.             result = oprnd1 - oprnd2;
  71.             break;
  72.         case MUL:
  73.             c = '*';
  74.             result = oprnd1 * oprnd2;
  75.             break;
  76.         case DIV:
  77.             c = '/';
  78.             result = oprnd1 / oprnd2;
  79.         }
  80.         printf("%.2f %c %.2f => %.2f\n",oprnd1,c,oprnd2,result);
  81.         oprnds[++top] = result;
  82.     }
  83. }

  84. /* update ret[] with next possible permutation of N cards */
  85. int permute(int ret[])
  86. {
  87.     int orig[N],i,j = 1;
  88.     for(i = 0;i<N-1;++i)
  89.         if(ret[i]<ret[i+1]){
  90.             j = 0;
  91.             break;
  92.         }
  93.     if(j) return 0;
  94.     for(i = 0;i<N;++i) orig[i] = ret[i];
  95.     for(i = N-2;i>=0;--i)
  96.         if(orig[i]<orig[i+1]) break;
  97.     for(j = N-1;j>i;--j)
  98.         if(orig[j]>orig[i]) break;
  99.     ret[i] = orig[j];
  100.     orig[j] = orig[i];
  101.     for(j = i+1;j<N;++j)
  102.         ret[j] = orig[N-j+i];
  103.     return 1;
  104. }

  105. /* update ops[] with next possible operators */
  106. int operators(int ops[])
  107. {
  108.     int i,j;
  109.     for(i = N-1;i>=0;--i){
  110.         if(ops[i]<DIV){
  111.             ++ops[i];
  112.             for(j = i+1;j<N-1;++j) ops[j] = ADD;
  113.             return 1;
  114.         }
  115.     }
  116.     return 0;
  117. }

  118. /* update expr[] with next possible expression in RPN */
  119. int expressions(int expr[])
  120. {
  121.     if(expr[3]>M && expr[4]>M) return 0;
  122.     if(expr[2]>M && expr[4]>M) expr[2]^=expr[3]^=expr[2]^=expr[3];
  123.     else if(expr[2]>M) expr[4]^=expr[5]^=expr[4]^=expr[5];
  124.     else if(expr[3]>M) expr[2]^=expr[3]^=expr[2]^=expr[3];
  125.     else expr[3]^=expr[4]^=expr[3]^=expr[4];
  126.     return 1;
  127. }

  128. int main(int argc,char *argv[])
  129. {
  130.     int opd[N],pmt[N],ops[N-1],expr[STACK_SIZE],i,succeed = 1;
  131.     if(argc<N+1) exit(printf("Not enough arguments!\n"));
  132.     for(i = 0;i<N;++i) opd[i] = atoi(argv[i+1]);
  133.     for(i = 0;i<N;++i) pmt[i] = i;
  134.     for(i = 0;i<N-1;++i) ops[i] = ADD;
  135.     while(1){
  136.         for(i = 0;i<N;++i) expr[i] = opd[pmt[i]];
  137.         for(i = 0;i<N-1;++i) expr[N+i] = ops[i];
  138.         if(succ(expr)) break;
  139.         while(expressions(expr))
  140.             if(succ(expr)) break;
  141.         if(succ(expr)) break;
  142.         if(!operators(ops)){
  143.             if(!permute(pmt)){
  144.                 succeed = 0;
  145.                 break;
  146.             }
  147.             for(i = 0;i<N-1;++i) ops[i] = ADD;
  148.         }
  149.     }
  150.     if(!succeed) exit(printf("Find no solutions!\n"));
  151.     printsolution(expr);
  152. }

復(fù)制代碼

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2006-03-24 11:18 |只看該作者
幾個(gè)比較“經(jīng)典”的數(shù)字組合測(cè)試:

  1. [bohnanza:misc]$ ./cal24 3 3 8 8
  2. 8.00 / 3.00 => 2.67
  3. 3.00 - 2.67 => 0.33
  4. 8.00 / 0.33 => 24.00
  5. [bohnanza:misc]$ ./cal24 5 5 1 5
  6. 1.00 / 5.00 => 0.20
  7. 5.00 - 0.20 => 4.80
  8. 4.80 * 5.00 => 24.00
  9. [bohnanza:misc]$ ./cal24 4 4 10 10
  10. 10.00 * 10.00 => 100.00
  11. 100.00 - 4.00 => 96.00
  12. 96.00 / 4.00 => 24.00
  13. [bohnanza:misc]$ ./cal24 3 7 3 7
  14. 3.00 / 7.00 => 0.43
  15. 0.43 + 3.00 => 3.43
  16. 7.00 * 3.43 => 24.00
  17. [bohnanza:misc]$ ./cal24 1 2 3 4
  18. 2.00 + 1.00 => 3.00
  19. 3.00 + 3.00 => 6.00
  20. 4.00 * 6.00 => 24.00
  21. [bohnanza:misc]$ ./cal24 7 7 7 7
  22. Find no solutions!

復(fù)制代碼

原帖由 emacsnw 于 2006-3-23 19:16 發(fā)表
主要是使用逆波蘭表達(dá)式的求值。歡迎測(cè)試和指正!


  1. /* cal24.c
  2. * given N integer numbers
  3. * find one expression which produces value T using all
  4. * the N numbers and {+,-,*,/} operators
  5. ...
復(fù)制代碼

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2006-03-24 11:32 |只看該作者
  1. [bohnanza:misc]$ ./cal24 3 3 8 8
  2. 8.00 / 3.00 => 2.67
  3. 3.00 - 2.67 => 0.33
  4. 8.00 / 0.33 => 24.00
復(fù)制代碼


這個(gè)涉及到精度的這樣子表示好像不太妥當(dāng).
我覺得最后表達(dá)出來(lái)的時(shí)候?qū)懗梢贿B串的數(shù)字和運(yùn)算符組合可能好點(diǎn),比如上面的那個(gè):
8/ (3 - 8 /3)...

回頭我也研究一下24點(diǎn)的算法

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2006-03-24 12:24 |只看該作者
原帖由 converse 于 2006-3-23 19:32 發(fā)表
  1. [bohnanza:misc]$ ./cal24 3 3 8 8
  2. 8.00 / 3.00 => 2.67
  3. 3.00 - 2.67 => 0.33
  4. 8.00 / 0.33 => 24.00
復(fù)制代碼


這個(gè)涉及到精度的這樣子表示好像不太妥當(dāng).
我覺得最后表達(dá)出來(lái)的時(shí)候?qū)懗梢贿B串 ...


計(jì)算的時(shí)候是使用double精度的,這個(gè)只是打印的時(shí)候不想在數(shù)字后面打太多位的小數(shù)。
打印表達(dá)式確實(shí)你說(shuō)的那樣更好一些。但是我自己在玩這個(gè)游戲的時(shí)候卻是這樣的一個(gè)
過程,而且逆波蘭表達(dá)式轉(zhuǎn)換成這種打印形式方便一些,偷懶了。

論壇徽章:
1
榮譽(yù)會(huì)員
日期:2011-11-23 16:44:17
5 [報(bào)告]
發(fā)表于 2006-03-24 12:47 |只看該作者
很久很久以前,也寫過一個(gè)很垃圾的
http://72891.cn/viewthr ... &highlight=yuxh

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2006-03-24 15:41 |只看該作者
用分?jǐn)?shù)吧,反正全是有理數(shù)
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP