首页 > 代码库 > N个数的数组求N-1个数组合乘积最大的一组

N个数的数组求N-1个数组合乘积最大的一组

  1 /*  2 编程之美题,给定N个数的数组,只能使用乘法,不使用除法,找出N-1个数的乘积最大的一组,有两种方法,方法一:采用两个数组分别保存从左向右  3 和从又向左的两个乘积值,然后在扫描一次,求出最大乘积,空间换时间的方法。  4 方法二:通过分析这些数的性质,看有多少正数,多少负数,多少0  5 (1)如果有2个或2个以上的0,则返回0  6 (2)如果有一个0,则看去除0后的乘积为正数还是负数,如果是负数,最大值为0,返回0(即当有一个0时,看负数奇偶情况,如果负数个数是奇数,则返回0)  7 ,如果是正数,则返回这个正数(即其它所有的乘积)  8 (3)如果总乘积为负数,则根据负负为正,去除绝对值最小的负数  9 (4)如果总乘积为正数,则如果存在正数,则除去绝对值最小的正数,否则除去绝对值最大的负数。 10 因为题目不让用除法,所以不能直接乘出总乘积,然后用除法,所以要一次扫描,记录正数个数,负数个数,绝对值最小正数,绝对值最小的负数,绝对值最大的负数。 11 */ 12  13 #include <iostream> 14 using namespace std; 15  16 double maxmultiply(const double *A,int n) 17 { 18     if(A==NULL) 19         return 0; 20     double * left=new double[n]; 21     double * right=new double[n]; 22     left[0]=A[0]; 23     right[n-1]=A[n-1]; 24     for(int i=1;i<n;i++) 25         left[i]=left[i-1]*A[i]; 26     for(int i=n-2;i>=0;i--) 27         right[i]=right[i+1]*A[i]; 28     double result=A[0]; 29     result=max(left[n-2],right[1]);   //先判断两个边界的时候,后面就不用比较了。 30     for(int i=1;i<=n-2;i++) 31     { 32         result=max(result,left[i-1]*right[i+1]); 33     } 34     return result; 35 } 36  37 /* 38 方法二,记录正负数个数 39 */ 40 double maxmultiply2(const double *A ,int n) 41 { 42     if(A==NULL) 43         return 0; 44     int pos=0; 45     int neg=0; 46     int zero=0; 47     double fabminp=A[0];             //绝对值最小的正数 48     double fabminn=A[0];             //绝对值最小的负数 49     double fabmaxn=A[0];             //绝对值最大的负数 50     double result=1; 51     for(int i=0;i<n;i++) 52     { 53         if(A[i]==0) 54             zero++; 55         if(A[i]>0) 56         { 57             pos++; 58             if(A[i]<fabminp) 59                 fabminp=A[i]; 60         } 61         if(A[i]<0) 62         { 63             neg++; 64             if(A[i]*(-1)<fabminn) 65             { 66                 fabminn=A[i]; 67             } 68             if(A[i]*(-1)>fabmaxn) 69             { 70                 fabmaxn=A[i]; 71             } 72         } 73     } 74     if(zero>=1) 75     { 76         if(zero>=2)                              //有两个以上0,返回0. 77             return 0; 78         else if((neg&1)==0)                        //有一个0,并且负数个数是偶数,说明乘积为正数,返回该正数,必须加括号才行 79         { 80             for(int i=0;i<n;i++) 81             { 82                 if(A[i]!=0) 83                     result*=A[i]; 84             } 85             return result; 86         } 87         else   return 0;                         //有一个0,并且其余乘积为负数,最大为0. 88     } 89     else if((neg&1)==0)                           //负数个数是偶数(包括0),则总乘积为正,必须加括号才行 90     { 91         if(pos>0)                                       //如果有正数,则去除最小正数,例如2,3,4,-1,-2,去除2,如果3,-1,-2,则除去3 92         { 93             for(int i=0;i<n;i++) 94             { 95                 if(A[i]!=fabminp) 96                     result*=A[i]; 97             } 98             return result; 99         }100         else                                  //没有正数情况,是偶数个负数,例如-2,-3,-4,-5,去除绝对值最大的负数                                  101         {102             for(int i=0;i<n;i++)103             {104                 if(A[i]!=fabmaxn)105                     result*=A[i];106             }107             return result;108         }109     }110     else                                       //负数个数是奇数个,总乘积为负数例如2,3,-1,-2,-3,此时去除绝对值最小的负数,-1                      111     {112         for(int i=0;i<n;i++)113         {114             if(A[i]!=fabminn)115                 result*=A[i];116         }117         return result;118     }119 }120 121 122 int main()123 {124     double A[]={2,9,-1,3,7,0,8,9,-3};125     int n=9;126     cout<<maxmultiply2(A,n)<<endl;127     system("pause");128 }