整型数组处理算法(八)插入(+、-、空格)完成的等式:1 2 3 4 5 6 7 8 9=N[华为面试题]

转载自

有一个未完成的等式:1 2 3 4 5 6 7 8 9=N

当给出整数N的具体值后,请你在2,3,4,5,6,7,8,9这8个数字的每一个前面,或插入运算符号“+”,或插入一个运算符号“-”,或不插入任何运算符号,使等式成立,并统计出能使等式成立的算式总数,若无解,则输出0。
例如:取N为108时,共能写出15个不同的等式,以下就是其中的二个算式:
1+23+4+56+7+8+9=108
123-45+6+7+8+9=108
输入一个数N

输出一个数,表示能使等式成立的算式总数。


方法一:

[cpp]  view plain copy
  1. #include "stdafx.h"  
  2. #include <iostream>  
  3. #include <string>  
  4. #include <fstream>  
  5. #include <sstream>  
  6. #include "stdio.h"  
  7.     using namespace std;  
  8. #define N 9   
  9. //把数字转换为字符串  
  10. string convertstrtoint(int j){  
  11.     stringstream tempstream;  
  12.     tempstream<<j;  
  13.     string i;  
  14.     tempstream>>i;  
  15.     tempstream.clear();  
  16.     tempstream.str("");  
  17.     return i;  
  18. }  
  19. void init(int*a,int num){  
  20.     int temp=10;  
  21.    
  22.     a[0]=1;  
  23.     for(int i=1;i<num;i++)  
  24.     {  
  25.         a[i]=temp;  
  26.         temp=temp*10;  
  27.     }  
  28. }  
  29. int garr[]={1,2,3,4,5,6,7,8,9};  
  30. int mulnumi[10];  
  31. //将数组中的数,组合成整数  
  32. int GetNumFromArr(int* b,int num)  
  33. {  
  34.     int tempsum=0;  
  35.     int tempnum=0;  
  36.    
  37.     for(int i=num-1;i>=0;i--)  
  38.     {  
  39.         tempnum=b[i]*mulnumi[num-i-1];  
  40.         tempsum+=tempnum;  
  41.     }  
  42.     return tempsum;  
  43. }  
  44.    
  45. void GetExpressResult(int* arr,int num,int expectval,int curval,int* pnum,string rstr)  
  46. {  
  47.    
  48.     int temp=0;  
  49.     for(int i=0;i<num;i++){  
  50.         temp=GetNumFromArr(arr,i+1);  
  51.         if(i+1==num)  
  52.         {  
  53.    
  54.             if(curval==temp)  
  55.             {  
  56.                 cout<<rstr<<"+"+convertstrtoint(temp)<<endl;  
  57.                 (*pnum)++;      
  58.                 return;  
  59.             }  
  60.             if(curval==-temp){  
  61.                 cout<<rstr<<"-"+convertstrtoint(temp)<<endl;  
  62.                 (*pnum)++;      
  63.                 return;  
  64.             }  
  65.             else  
  66.             {   
  67.                 //cout<<rstr<<endl;  
  68.                 return ;  
  69.             }  
  70.         }  
  71.         else if(i+1<num)  
  72.         {  
  73.             GetExpressResult(arr+1+i,num-1-i,expectval,curval-temp,pnum,rstr+"+"+convertstrtoint(temp));  
  74.             if(num<N)  
  75.                 GetExpressResult(arr+1+i,num-1-i,expectval,curval+temp,pnum,rstr+"-"+convertstrtoint(temp));  
  76.    
  77.         }  
  78.     }  
  79. }  
  80.    
  81. int _tmain(int argc, _TCHAR* argv[])  
  82. {  
  83.     init(mulnumi,10);  
  84.     int res=0;//存放有多少个表达式  
  85.     int *p=garr+N;  
  86.     GetExpressResult(garr,N,5,5,&res,string(""));  
  87.     cout<<"total:"<<res<<endl;  
  88.     getchar();  
  89.     return 0;  
  90. }  


方法二:

[cpp]  view plain copy
  1. #include <iostream>  
  2. #include <cmath>  
  3. using namespace std;  
  4.    
  5. int func (const char* str, int num);  
  6. bool calc (const char* result, int num);  
  7. void display(const char* result);  
  8.    
  9. int main()  
  10. {  
  11.     const char str[] = "123456789";  
  12.     int num;  
  13.     cout << "input num: ";  
  14.     cin >> num;  
  15.     cout << "result: " << func(str, num) << endl;  
  16.     return 0;  
  17. }  
  18.    
  19. int func(const char* str, int num)  
  20. {  
  21.     //初始化输出数组  
  22.     int len = strlen(str);  
  23.     char* result = new char[len*2];  
  24.     for (int i = 0; i < len; i++)  
  25.     {  
  26.         result[i*2] = str[i];  
  27.     }  
  28.     result[len*2-1] = '\0';  
  29.        
  30.     //模拟3进制的运算  
  31.     char key[3] = {' ''+''-'};  
  32.     int n = pow(3.0, len - 1);  
  33.     int ret = 0;  
  34.     for (int i = 0; i < n; i++)  
  35.     {  
  36.         //把i转换成3进制,计算每一位,转换成字符,填入字符串相应位置  
  37.         int pos = len * 2 - 3; //个位数填入位置  
  38.         int temp = i, mod;  
  39.         do  
  40.         {  
  41.             mod = temp % 3;  
  42.             temp /= 3;  
  43.             result[pos] = key[mod];  
  44.             pos -= 2;  
  45.         }while (temp > 0);  
  46.         //高位补0  
  47.         while (pos > 0)  
  48.         {  
  49.             result[pos] = key[0];  
  50.             pos -= 2;  
  51.         }  
  52.         if (calc(result, num)) //计算结果并输出  
  53.             ret++;  
  54.     }  
  55.    
  56.     delete[] result;  
  57.     return ret;  
  58. }  
  59.    
  60. bool calc(const char* result, int num)  
  61. {  
  62.     int sum = 0, sign = 1, i = 0;  
  63.     int temp = 0;  
  64.     while (result[i] != '\0')  
  65.     {  
  66.         if (result[i] == ' ')  
  67.         {  
  68.             temp *= 10;  
  69.         }  
  70.         else if(result[i] == '+' || result[i] == '-')  
  71.         {  
  72.             sign = (result[i] == '+') ? 1 : -1;  
  73.             sum += temp;  
  74.             temp = 0;  
  75.         }  
  76.         else  
  77.         {  
  78.             temp += sign * (result[i] - '0');  
  79.         }  
  80.         i++;  
  81.     }  
  82.     sum += temp;  
  83.     if (sum == num)  
  84.     {  
  85.         display(result);   //输出结果  
  86.         return true;  
  87.     }  
  88.     else  
  89.         return false;  
  90. }  
  91.    
  92. void display(const char* result)  
  93. {  
  94.     for (int i = 0; i < strlen(result); i++)  
  95.         if (result[i] != ' ')  
  96.             cout << result[i];  
  97.     cout << endl;  
  98. }  

方法三:

[cpp]  view plain copy
  1. #include <stdio.h>  
  2.    
  3. /*返回两个数合并的情况*/  
  4. int HeBin(int arry[],int i,int j)  
  5. {  
  6.     int num=0;  
  7.     for(;i<=j;i++)  
  8.     {  
  9.         num = num*10 + arry[i];  
  10.     }  
  11.     return num;  
  12. }  
  13. //a为装载1~9的数组,n为当前数组所用到的数字顺序 ,g为输入的值  
  14. int Digui(int a[],int n,int g)  
  15. {  
  16.     static int sum1=0;  
  17.     int i=n;  
  18.     if(n > 0)  
  19.     {  
  20.         for(i = n;i >=0;i--)  
  21.         {  
  22.             if(i != 0)  
  23.             {  
  24.                 Digui(a,i-1,g-HeBin(a,i,n));        //数字合并加减的情况  
  25.                 Digui(a,i-1,g+HeBin(a,i,n));  
  26.             }else  
  27.             {  
  28.                 if(g - HeBin(a,0,n) == 0)  
  29.                 {  
  30.                 //    printf("%d - %d (0 , %d)\n",g,HeBin(a,0,n),n);  
  31.                     sum1++;        //符合条件的情况时,sum1加一  
  32.                 }  
  33.                 return sum1;  
  34.             }  
  35.         }  
  36.         Digui(a,n-1,g-a[i]);    //单个数字的加减的情况  
  37.         Digui(a,n-1,g+a[i]);  
  38.    
  39.     }else if(n == 0)  
  40.     {  
  41.         if(0 == g - a[n])  
  42.             sum1++;    //符号情况时加一  
  43.     }  
  44.     return sum1;  
  45. }  
  46.    
  47. int main()  
  48. {  
  49.     int a[] = {1,2,3,4,5,6,7,8,9};  
  50.     int goal;  
  51.     while(1 != (scanf("%d",&goal)));  
  52.     goal = Digui(a,8,goal);  
  53.     printf("%d\n",goal);  
  54.     return 0;  
  55. }  

方法四:

[cpp]  view plain copy
  1. /*--------------------------------------- 
  2. 函数型计算器(VC++6.0,Win32 Console)程序由 yu_hua 于2007-07-27设计完成 
  3. 功能: 
  4. 目前提供了10多个常用数学函数: 
  5.     ⑴正弦sin 
  6.     ⑵余弦cos 
  7.     ⑶正切tan 
  8.     ⑷开平方sqrt 
  9.     ⑸反正弦arcsin 
  10.     ⑹反余弦arccos 
  11.     ⑺反正切arctan 
  12.     ⑻常用对数lg 
  13.     ⑼自然对数ln 
  14.     ⑽e指数exp 
  15.     ⑾乘幂函数∧ 
  16. 用法: 
  17. 如果要求2的32次幂,可以打入2^32<回车> 
  18. 如果要求30度角的正切可键入tan(Pi/6)<回车> 
  19. 注意不能打入:tan(30)<Enter> 
  20. 如果要求1.23弧度的正弦,有几种方法都有效: 
  21. sin(1.23)<Enter> 
  22. sin 1.23 <Enter> 
  23. sin1.23  <Enter> 
  24. 如果验证正余弦的平方和公式,可打入sin(1.23)^2+cos(1.23)^2 <Enter>或sin1.23^2+cos1.23^2 <Enter> 
  25. 此外两函数表达式连在一起,自动理解为相乘如:sin1.23cos0.77+cos1.23sin0.77就等价于sin(1.23)*cos(0.77)+cos(1.23)*sin(0.77) 
  26. 当然你还可以依据三角变换,再用sin(1.23+0.77)也即sin2验证一下。 
  27. 本计算器充分考虑了运算符的优先级因此诸如:2+3*4^2 实际上相当于:2+(3*(4*4)) 
  28. 另外函数名前面如果是数字,那么自动认为二者相乘. 
  29. 同理,如果某数的右侧是左括号,则自动认为该数与括弧项之间隐含一乘号。 
  30. 如:3sin1.2^2+5cos2.1^2 相当于3*sin2(1.2)+5*cos2(2.1) 
  31. 又如:4(3-2(sqrt5-1)+ln2)+lg5 相当于4*(3-2*(√5 -1)+loge(2))+log10(5) 
  32. 此外,本计算器提供了圆周率 Pi键入字母时不区分大小写,以方便使用。 
  33. ----------------------------------------*/  
  34. #include <iostream>  
  35. #include <iomanip>  
  36. #include <cstdlib>  
  37. #include <cstring>  
  38. #include <cctype>  
  39. #include <cmath>  
  40. #include <stdio.h>  
  41. #include <string.h>  
  42. #include <windows.h>  
  43. using namespace std;  
  44. const char Tab=0x9;  
  45. const int  DIGIT=1;  
  46. const int MAXLEN=16384;  
  47. char s[MAXLEN],*endss;  
  48. int pcs=15;  
  49. double fun(double x,char op[],int *iop) {  
  50.     while (op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号,如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter>  
  51.         switch (op[*iop-1]) {  
  52.         case  7: x=sin(x);  (*iop)--;break;  
  53.         case  8: x=cos(x);  (*iop)--;break;  
  54.         case  9: x=tan(x);  (*iop)--;break;  
  55.         case 10: x=sqrt(x); (*iop)--;break;  
  56.         case 11: x=asin(x); (*iop)--;break;  
  57.         case 12: x=acos(x); (*iop)--;break;  
  58.         case 13: x=atan(x); (*iop)--;break;  
  59.         case 14: x=log10(x);(*iop)--;break;  
  60.         case 15: x=log(x);  (*iop)--;break;  
  61.         case 16: x=exp(x);  (*iop)--;break;  
  62.         }  
  63.     return x;  
  64. }  
  65. double calc(char *expr,char **addr) {  
  66.     static int deep; //递归深度  
  67.     static char *fname[]={ "sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp",NULL};  
  68.     double ST[10]={0.0}; //数字栈  
  69.     char op[10]={'+'}; //运算符栈  
  70.     char c,*rexp,*pp,*pf;  
  71.     int ist=1,iop=1,last,i;  
  72.     if (!deep) {  
  73.         pp=pf=expr;  
  74.         do {  
  75.             c = *pp++;  
  76.             if (c!=' '&& c!=Tab)  
  77.                 *pf++ = c;  
  78.         } while (c!='\0');  
  79.     }  
  80.     pp=expr;  
  81.     if ((c=*pp)=='-'||c=='+') {  
  82.         op[0] = c;  
  83.         pp++;  
  84.     }  
  85.     last = !DIGIT;  
  86.     while ((c=*pp)!='\0') {  
  87.         if (c=='(') {//左圆括弧  
  88.             deep++;  
  89.             ST[ist++]=calc(++pp,addr);  
  90.             deep--;  
  91.             ST[ist-1]=fun(ST[ist-1],op,&iop);  
  92.             pp = *addr;  
  93.             last = DIGIT;  
  94.             if (*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是:当右圆括弧的右恻为左圆括弧或函数名字时,默认其为乘法  
  95.                 op[iop++]='*';  
  96.                 last = !DIGIT;  
  97.                 c = op[--iop];  
  98.                 goto operate ;  
  99.             }  
  100.         }  
  101.         else if (c==')') {//右圆括弧  
  102.             pp++;  
  103.             break;  
  104.         } else if (isalpha(c)) {  
  105.             if (!strnicmp(pp,"Pi",2)) {  
  106.                 if (last==DIGIT) {  
  107.                     cout<< "π左侧遇)" <<endl;exit(1);  
  108.                 }  
  109.                 ST[ist++]=3.14159265358979323846264338328;  
  110.                 ST[ist-1]=fun(ST[ist-1],op,&iop);  
  111.                 pp += 2;  
  112.                 last = DIGIT;  
  113.                 if (!strnicmp(pp,"Pi",2)) {  
  114.                     cout<< "两个π相连" <<endl;exit(2);  
  115.                 }  
  116.                 if (*pp=='(') {  
  117.                     cout<< "π右侧遇(" <<endl;exit(3);  
  118.                 }  
  119.             } else {  
  120.                 for (i=0; (pf=fname[i])!=NULL; i++)  
  121.                     if (!strnicmp(pp,pf,strlen(pf))) break;  
  122.                 if (pf!=NULL) {  
  123.                     op[iop++] = 07+i;  
  124.                     pp += strlen(pf);  
  125.                 } else {  
  126.                     cout<< "陌生函数名" <<endl;exit(4);  
  127.                 }  
  128.             }  
  129.         } else if (c=='+'||c=='-'||c=='*'||c=='/'||c=='^') {  
  130.             char cc;  
  131.             if (last != DIGIT) {  
  132.                 cout<< "运算符粘连" <<endl;exit(5);  
  133.             }  
  134.             pp++;  
  135.             if (c=='+'||c=='-') {  
  136.                 do {  
  137.                     cc = op[--iop];  
  138.                     --ist;  
  139.                     switch (cc) {  
  140.                     case '+':  ST[ist-1] += ST[ist];break;  
  141.                     case '-':  ST[ist-1] -= ST[ist];break;  
  142.                     case '*':  ST[ist-1] *= ST[ist];break;  
  143.                     case '/':  ST[ist-1] /= ST[ist];break;  
  144.                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;  
  145.                     }  
  146.                 } while (iop);  
  147.                 op[iop++] = c;  
  148.             } else if (c=='*'||c=='/') {  
  149. operate:        cc = op[iop-1];  
  150.                 if (cc=='+'||cc=='-') {  
  151.                     op[iop++] = c;  
  152.                 } else {  
  153.                     --ist;  
  154.                     op[iop-1] = c;  
  155.                     switch (cc) {  
  156.                     case '*':  ST[ist-1] *= ST[ist];break;  
  157.                     case '/':  ST[ist-1] /= ST[ist];break;  
  158.                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;  
  159.                     }  
  160.                 }  
  161.             } else {  
  162.                 cc = op[iop-1];  
  163.                 if (cc=='^') {  
  164.                     cout<< "乘幂符连用" <<endl;exit(6);  
  165.                 }  
  166.                 op[iop++] = c;  
  167.             }  
  168.             last = !DIGIT;  
  169.         } else {  
  170.             if (last == DIGIT) {  
  171.                 cout<< "两数字粘连" <<endl;exit(7);  
  172.             }  
  173.             ST[ist++]=strtod(pp,&rexp);  
  174.             ST[ist-1]=fun(ST[ist-1],op,&iop);  
  175.             if (pp == rexp) {  
  176.                 cout<< "非法字符" <<endl;exit(8);  
  177.             }  
  178.             pp = rexp;  
  179.             last = DIGIT;  
  180.             if (*pp == '('||isalpha(*pp)) {  
  181.                 op[iop++]='*';  
  182.                 last = !DIGIT;  
  183.                 c = op[--iop];  
  184.                 goto operate ;  
  185.             }  
  186.         }  
  187.     }  
  188.     *addr=pp;  
  189.     if (iop>=ist) {  
  190.         cout<< "表达式有误" <<endl;exit(9);  
  191.     }  
  192.     while (iop) {  
  193.         --ist;  
  194.         switch (op[--iop]) {  
  195.         case '+':  ST[ist-1] += ST[ist];break;  
  196.         case '-':  ST[ist-1] -= ST[ist];break;  
  197.         case '*':  ST[ist-1] *= ST[ist];break;  
  198.         case '/':  ST[ist-1] /= ST[ist];break;  
  199.         case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;  
  200.         }  
  201.     }  
  202.     return ST[0];  
  203. }  
  204. int main(int argc,char **argv) {  
  205.     //1 2 3 4 5 6 7 8 9 =110 中间可以挿+ - 或者不挿 如果1 2 不挿的话 就是12  
  206.     char op[4]=" +-";  
  207.     int g1;  
  208.     int g2;  
  209.     int g3;  
  210.     int g4;  
  211.     int g5;  
  212.     int g6;  
  213.     int g7;  
  214.     int g8;  
  215.    
  216.     for (g1=0;g1<3;g1++)  
  217.     for (g2=0;g2<3;g2++)  
  218.     for (g3=0;g3<3;g3++)  
  219.     for (g4=0;g4<3;g4++)  
  220.     for (g5=0;g5<3;g5++)  
  221.     for (g6=0;g6<3;g6++)  
  222.     for (g7=0;g7<3;g7++)  
  223.     for (g8=0;g8<3;g8++) {  
  224.         strcpy(s,"1 2 3 4 5 6 7 8 9");  
  225.         s[ 1]=op[g1];  
  226.         s[ 3]=op[g2];  
  227.         s[ 5]=op[g3];  
  228.         s[ 7]=op[g4];  
  229.         s[ 9]=op[g5];  
  230.         s[11]=op[g6];  
  231.         s[13]=op[g7];  
  232.         s[15]=op[g8];  
  233.         if (110.0==calc(s,&endss)) printf("%s=110\n",s);  
  234.     }  
  235.     /* 
  236.     if (argc<=1) { 
  237.         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页 
  238.         cout << "计算函数表达式的值。"<<endl<<"支持(),+,-,*,/,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl; 
  239.         while (1) { 
  240.             cout << "请输入表达式:"; 
  241.             gets(s); 
  242.             if (s[0]==0) break;// 
  243.             cout << s <<"="; 
  244.             cout << setprecision(15) << calc(s,&endss) << endl; 
  245.         } 
  246.     } else { 
  247.         strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0; 
  248.         if (argc>=3) { 
  249.             pcs=atoi(argv[2]); 
  250.             if (pcs<0||15<pcs) pcs=15; 
  251.             printf("%.*lf\n",pcs,calc(s,&endss)); 
  252.         } else { 
  253.             printf("%.15lg\n",calc(s,&endss)); 
  254.         } 
  255.     } 
  256.     */  
  257.     return 0;  
  258. }  
  259. //123+4+5+67-89=110  
  260. //123+4-5-6-7-8+9=110  
  261. //123-4+5-6-7+8-9=110  
  262. //123-4-5+6+7-8-9=110  
  263. //12+34+56+7-8+9=110  
  264. //12+3+45+67-8-9=110  
  265. //12-3+4-5+6+7+89=110  
  266. //1+234-56-78+9=110  
  267. //1+2+34+5+67-8+9=110  
  268. //1-2+3+45-6+78-9=110  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值