N个整数,求其中任意N-1个数的乘积中的最大的一个。

qsc555 2006-12-03 03:10:42
N个整数,求其中任意N-1个数的乘积中的最大的一个。
例如 3,2,1,则最大的是3*2=6
提示:整数包括0和负数
要求给出个比较有效率的算法

我的函数实现:
long GetMaxValueInCumulation(long plIntegerNumbers[],long lIntegerNumbersCount)
{
long lMinIntegerNumber = 1<<sizeof(long);

//不合法输入返回最大的整数
if(!plIntegerNumbers || lIntegerNumbersCount <= 0)
return (lMinIntegerNumber);

long lReturnValue = 1;
long lMaxNegativeValue = 0;
long lNegativeValueCount = 0;
long lIndex = 0;

//中间处理变量
long lCumulationDataIndex = 0;
long plCumulationData = new long[lIntegerNumbersCount];
if(!plCumulationData)
return (lMinIntegerNumber);
memset(plCumulationData,0,lIntegerNumbersCount];

//去掉最小值及0值及处理负数的情况
for(lIndex = 0; lIndex < lIntegerNumbersCount;lIndex++)
{
if( plIntegerNumber[lIndex] > 0 && plIntegerNumbers[lIndex] < lMinIntegerNumber )
lMinIntegerNumber = plIntegerNumbers[lIndex];
if( plIntegerNumbers[lIndex] < 0 )
lNegativeValueCount++;
if(plIntegerNumbers[lIndex] < 0 && lMaxNegativeValue < plIntegerNumbers[lIndex] )
lMaxNegativeValue = plIntegerNumbers[lIndex];
if(plIntegerNumber[lIndex])
plCumulationData[lCumulationDataIndex++] = plIntegerNumber[lIndex];
}

//计算结果
if(lNegativeValueCount < 1)
{
for(lIndex = lCumulationDataIndex - 1;lIndex >= 0;lIndex--)
lReturnValue *= plCumulationData[lIndex];
}
else
{
if(lNegativeValueCount % 2 )
{
for(lIndex = lCumulationDataIndex - 1;lIndex >= 0;lIndex--)
{
if(lMaxNegativeValue == plCumulationData[lIndex] )
continue;
lReturnValue *= plCumulationData[lIndex];
}
}
else
for(lIndex = lCumulationDataIndex - 1;lIndex >= 0;lIndex--)
lReturnValue *= plCumulationData[lIndex];
}

delete []plCumulationData;

return (lReturnValue);
}

学习学习别人更好的办法:)
...全文
2633 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
qsc555 2006-12-25
  • 打赏
  • 举报
回复
哈哈,本人表达能力不什么好,就此结束吧,似乎没有讨论的必要了;
healer_kx 2006-12-23
  • 打赏
  • 举报
回复
看不懂回帖。。。虽然看着很整齐,都不知道谁说了啥。。。
qsc555 2006-12-23
  • 打赏
  • 举报
回复
哈哈,谢谢各位参与,本人是很不负责,发了帖子就不管了,今天才肯认真读帖,我觉得
gxqcn(★) HugeCalc ← http://maths.diy.myrice.com/ 最后考虑的比较周全了,但本人不是很熟悉STL的东西,所以开始不愿意认真阅读,现在总结下,如果大家认为没有必要讨论了,我就结帖了:)

/***********************************************************
gxqcn(★) HugeCalc ← http://maths.diy.myrice.com/ :
该问题等价于:从 N 个整数中剔除一个,使余下的数乘积最大。

令这N个数依次为 a1,a2,...,an,P=a1*a2*...*an,
(1) 如果 P<0,则剔除其中最大的负整数即可;
(2) 如果 P=0,
2.1 若这 N 个数中有且仅有一个为“0”。若其它数之积为正,则剔除“0”;否则剔除任意一个非零数;
2.2 若这 N 个数中至少有两个为“0”,则随便剔除一个均可;
(3) 如果 P>0,则剔除其中最小的正整数即可。
//注明:(3)改为:如果 P>0,如果有正数, 则剔除其中最小的正整数即可;否则,剔除最小的负数;
******************************************************************************/

谢谢xxyyboy(壮志凌云) 提醒,我后来也发现自己误解为:
/******************************************************
题目最好改为
M个整数,求其中任意N-1(M>=N)个数的乘积中的最大的一个。
*******************************************************/
我把题目理解为上述情况了。


healer_kx(甘草 春去春回,花落谁家?心寄笔端,谁解我意?),我觉得你的代码不错,但正如
/*********************************************************************************
回复人:gxqcn(★) HugeCalc ← http://maths.diy.myrice.com/ (☆) ( 二级(初级)) 信誉:100 2006-12-7 7:55:33

楼上的还是漏了一种情况:全部为负数,且为偶数个(此时应剔除最小的负数)。
**********************************************************************************/
所说的,这段代码
{
//去掉那个最小的正整数
}
还要判断是否有正数的情况。


YourKing(01240) ( 二级(初级)) 信誉:100 , 我很想知道什么实现,如果阁下能给出
汇编的代码,非常感谢,学习学习:)

我觉得大家都是在考虑算法,但是算法的复杂度和效率能给出吗?本人也想看看别人是什么考虑的,
谢谢各位了.
gxqcn 2006-12-07
  • 打赏
  • 举报
回复
楼上的还是漏了一种情况:全部为负数,且为偶数个(此时应剔除最小的负数)。
houdy 2006-12-07
  • 打赏
  • 举报
回复
我来总结一下:
1.定义以下几个变量:
int iMinPositiveNumber -- the min positive number
int iMaxNegativeNumber -- the max positive number
int iNegativeNumberCount -- the count of negative number
bool bZeroExist -- the zero number
2.使用以下的逻辑推理:
if (0 == iNegativeNumberCount%2) {
if (bZeroExist) {
remove zero
}else {
if (0 == iMinPositiveNumber) {
remove the iMaxNegativeNumber;
}else {
remove the iMinPositiveNumber;
}
}
}else {
remove the iMaxNegativeNumber;
}
dmt9697 2006-12-06
  • 打赏
  • 举报
回复
1.负数个数为奇数,去掉最大的负数(不管有没有0没有关系)
2.负数为偶数:(1).有0去0
(2).没有0去掉最小的正数

变量:fushujiouFlag,zeroFlag,Maxfushu,Minzhengshu
冒泡排序一下,给他们赋值一下就好了
gxqcn 2006-12-06
  • 打赏
  • 举报
回复
#include<iostream>
#include <algorithm>

using namespace std;

const bool _comp( const int * const &pL, const int * const &pR )
{
return ( *pL < *pR );
}

int main(int argc, char* argv[])
{
#define LEN 8
int i;
const int ZERO = 0;
const int a[LEN] = { -2, -1, 0, 0, 1, 2, 3, -9 };
const int * ap[LEN];
const int ** pSkip;

for ( i=0; LEN!=i; ++i )
{
ap[i] = &a[i];
}

/* 仅对 a[] 的地址排序,对 a[] 本身不作任何变动 */
sort( ap, ap+LEN, _comp );

pair<const int **, const int **>
pZero = equal_range( ap, ap+LEN, &ZERO, _comp );

switch( pZero.second - pZero.first /* 含“0”的数目 */)
{
case 0:
if (( pZero.first - ap ) & 0x01)
{ /* 有奇数个负数,无零,则剔除一个绝对值最小的负数 */
pSkip = pZero.first - 1 ;
}
else
{ /* 有偶数个负数,无零,则剔除一个绝对值最小的正数 */
if ( ap + LEN != pZero.second )
{
pSkip = pZero.second + 1;
}
else /* 但很不幸,无正数可删,则改删绝对值最大的负数 (※)*/
{
pSkip = ap;
}
}
break;

case 1:
if (( pZero.first - ap ) & 0x01)
{ /* 有奇数个负数,一个零,则可剔除任意一个非零数 */
pSkip = ap;
}
else
{ /* 有偶数个负数,一个零,则剔除掉这个零 */
pSkip = pZero.first;
}
break;

default:/* 有多个零,则可剔除任意某个数 */
pSkip = ap;
}

/* 输出 */
cout << "del: " << **pSkip << endl;
for ( i=0; LEN!=i; ++i )
{
if ( *pSkip != a + i )
{
cout << a[i] << " ";
}
}
cout << endl;

return 0;
}

/* (※)注:与先前的论述相比,多了一种情况:当仅有偶数个负数时,剔除最小的负数 */
itoaer 2006-12-06
  • 打赏
  • 举报
回复
这个还是今年google的一个笔试题目
KenYuan2016 2006-12-06
  • 打赏
  • 举报
回复
题目最好改为
M个整数,求其中任意N-1(M>=N)个数的乘积中的最大的一个。
KenYuan2016 2006-12-06
  • 打赏
  • 举报
回复
1.去掉 0 ,1
2。绝对值排序
3。奇数个负数,下一步处理,偶数个负数,直接给出结果。
4。取出绝对值最小的最后一个负数与剩下的数中绝对值最大的正数交换,相乘结果1
5。取出绝对值最小的最后一个正数与剩下的数中绝对值最大的负数交换,相乘结果2
6。比较1,2 给出最终结果。
xjx19 2006-12-05
  • 打赏
  • 举报
回复
先排序,直接求最大的n-1个数的积,可以不?
gxqcn 2006-12-05
  • 打赏
  • 举报
回复
在看帖不回帖被鄙视的年代里,流行着回帖不看帖。。。
YourKing 2006-12-05
  • 打赏
  • 举报
回复
为什么一个是无解,一个是N-1解?你这N-1个解都为0吧?那如果有两个零,我还不是可以得出那么多乘积为0的?
===============================
如果有2个0,则用来比较的N个值都是0,所以我说无解

个人觉得有讨论是好事
否则,大家都不要发言了,让版主或星星,嗯,还有那些一答就中的高手来答题好了
gxqcn 2006-12-05
  • 打赏
  • 举报
回复
不知道这里的回帖者是没有看帖的习惯呢?还是出现了阅读理解的障碍?包括对代码的。
老早 healer_kx(甘草) 就给出了非常好(高效)的代码,其算法与本人之前的描述正好完全吻合,
如果各位能仔细阅读理解的话,就无须讨论到现在还不清楚。
goodbee 2006-12-05
  • 打赏
  • 举报
回复
1.如果N个数中有>=2个0,无解
2.如果有1个0,计算其他N-1个数的符号位积,如果为正则这N-1个数的乘积为解
如果为负,则有N-1个解
为什么一个是无解,一个是N-1解?你这N-1个解都为0吧?那如果有两个零,我还不是可以得出那么多乘积为0的?
healer_kx 2006-12-05
  • 打赏
  • 举报
回复
。。。 。。。
YourKing 2006-12-05
  • 打赏
  • 举报
回复
不需要计算数乘积,只要符号位的
一趟循环记录就可以得到所需要的信息
YourKing 2006-12-05
  • 打赏
  • 举报
回复
将这N个数存储在整型数组A[N]中
1.如果N个数中有>=2个0,无解
2.如果有1个0,计算其他N-1个数的符号位积,如果为正则这N-1个数的乘积为解
如果为负,则有N-1个解
3.如果没有0,计算其他N个数的符号位积,如果为正,找出这N个数中最小正数, 如果为负,找出N个数中最大负数,余下N-1个数的积为解

请指教
listart 2006-12-05
  • 打赏
  • 举报
回复
遍历数组,记录下最小的正数,最大的负数和零的位置,同时记录下负数的个数
遍历时如果存在零,那么去此零的结果就是解
如果不存在零,那么按负数个数的奇偶分2种情况:
1、偶数个就去掉最小的正数
2、奇数个就去掉最大的负数
ppcat_001 2006-12-04
  • 打赏
  • 举报
回复
判断一下是不是有2个0,或者一个0,一个1,那样就不用算了
加载更多回复(10)

65,208

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧