这个程序应该怎样写?。。。。。。。。。。

mikemeego002 2011-06-16 10:07:44
实现一个函数:凑14;输入很多个整数(1<=数值<=13),任意两个数相加等于14就可以从数组中删除这两个数,求剩余数(按由小到大排列);
比如: 输入数组[9,1,9,7,5,13], 输出数组[7,9]


...全文
261 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
ABU 2011-11-08
  • 打赏
  • 举报
回复
哈,其实这道题,可以通过时间换空间,避免排序之类的性能消耗,具体详细的解题思路、实现代码及其测试代码,详见:http://blog.csdn.net/caiguowu/article/details/6950062


// 凑MakeValue,默认凑14. 其中:OutPutArray:输出结果,这个数组存放的数据,相当于压缩数据,
// 例如OutPutArray[6] = 10,表示6的个数有10,优点是,如果数很多可以省内存。
bool MakeAndDelete(const int *InputArray, int count, int *OutPutArray, int MakeValue = 14)
{
ASSERT(NULL != InputArray && NULL != OutPutArray)
memset(OutPutArray,0,MakeValue*sizeof(int));// 输出清0

for (int i = 0; i < count; i++) // 哈,统计数目的同时,实际上就完了排序
{
if (InputArray[i]<1 || InputArray[i] >= MakeValue)// 防止输入值无效 {
return false;
}
OutPutArray[ InputArray[i] ] += 1;

for (int i = 1; i < MakeValue/2; i++) // 删除两数之和为14的
{
if (OutPutArray[i] > OutPutArray[MakeValue - i])
{
OutPutArray[i] = OutPutArray[i] - OutPutArray[MakeValue - i];
OutPutArray[MakeValue - i] = 0; // 注意前后不能换
}
else
{
OutPutArray[MakeValue - i] = OutPutArray[MakeValue - i] - OutPutArray[i];
OutPutArray[i] = 0; // 注意前后不能换
}
}

if(MakeValue%2 == 0)
{
OutPutArray[MakeValue/2] = OutPutArray[MakeValue/2]%2;
}
return true;
}


ABU 2011-11-08
  • 打赏
  • 举报
回复
哈,其实这道题,可以通过时间换空间,避免排序之类的性能消耗,具体详细的解题思路、实现代码及其测试代码,详见:http://blog.csdn.net/caiguowu/article/details/6950062

// 凑MakeValue,默认凑14. 其中:OutPutArray:输出结果,这个数组存放的数据,相当于压缩数据,
// 例如OutPutArray[6] = 10,表示6的个数有10,优点是,如果数很多可以省内存。
bool MakeAndDelete(const int *InputArray, int count, int *OutPutArray, int MakeValue = 14)
{
ASSERT(NULL != InputArray && NULL != OutPutArray)
memset(OutPutArray,0,MakeValue*sizeof(int));// 输出清0

for (int i = 0; i < count; i++) // 哈,统计数目的同时,实际上就完了排序
{
if (InputArray[i]<1 || InputArray[i] >= MakeValue)// 防止输入值无效 {
return false;
}
OutPutArray[ InputArray[i] ] += 1;

for (int i = 1; i < MakeValue/2; i++) // 删除两数之类为14
{
if (OutPutArray[i] > OutPutArray[MakeValue - i])
{
OutPutArray[i] = OutPutArray[i] - OutPutArray[MakeValue - i];
OutPutArray[MakeValue - i] = 0; // 注意前后不能换
}
else
{
OutPutArray[MakeValue - i] = OutPutArray[MakeValue - i] - OutPutArray[i];
OutPutArray[i] = 0; // 注意前后不能换
}
}

if(MakeValue%2 == 0)
{
OutPutArray[MakeValue/2] = OutPutArray[MakeValue/2]%2;
}
return true;
}
GARY 2011-06-16
  • 打赏
  • 举报
回复
修正之后的程序:

#include <iostream>
#include <set>
using namespace std;

int main()
{
bool b_erase = false, b_even = false;
multiset<int> coll, coll_copy;
copy(istream_iterator<int>(cin), istream_iterator<int>(), inserter(coll, coll.begin()));

multiset<int>::size_type count7 = coll.count(7);
if (count7 > 0)
{
if (count7 % 2 == 0)
{
b_even = true;
}
coll.erase(7);
}

copy(coll.begin(), coll.end(), inserter(coll_copy, coll_copy.begin()));

multiset<int>::iterator pos = coll.begin();
multiset<int>::iterator pos_copy;

for (; pos != coll.end();)
{
for (pos_copy = coll_copy.begin(); pos_copy != coll_copy.end(); ++pos_copy)
{
if (*pos + *pos_copy == 14)
{
b_erase = true;
coll.erase(pos++);
coll_copy.erase(pos_copy);
break;
}
}
if (!b_erase)
{
++pos;
}
else
{
b_erase = false;
}
}

if (!b_even)
{
coll.insert(7);
}

copy(coll.begin(), coll.end(), ostream_iterator<int>(cout, " "));
system("PAUSE");
}
GARY 2011-06-16
  • 打赏
  • 举报
回复
呃。。
有错误。

先特别处理了数字7,只要输入的元素中有7
不管是多少个,最后只留1个7即可

这弄错了,有奇数个7留1个,偶数个7都删掉。我改下程序。
GARY 2011-06-16
  • 打赏
  • 举报
回复
1
其中排序是利用了multiset容器的特性
将输入元素插入到multiset类型容器coll中,则元素自动排序。

2
先特别处理了数字7,只要输入的元素中有7
不管是多少个,最后只留1个7即可

3
删除元素是利用multiset容器的erase函数完成
不过要注意防止删除元素后迭代器失效的情况(程序中已经处理了)

4
“从标准输入读数据”,“向标准输出写数据”都是利用了stream_iterator流迭代器配接器

5
我脑子不好用,又是大菜鸟。为了快点答题,弄了个coll_copy。
其实用一个容器就可以完成了。楼主优化下。
就想叫yoko 2011-06-16
  • 打赏
  • 举报
回复
你这里不能简单删除的
因为如果数组里面有4 10 10
那么你删除4之后第二次的10就没法删除了
建议生成一个新数组做操作
或者用结构体数组 把要删除的数用一个bool变量标识

另外你的需求是删除后排序
也可以先排序 去掉重复元素 毕竟你这里是删除等于14的2个值而不是大于14的2个值[Quote=引用 7 楼 mikemeego002 的回复:]
int[] a=[9,1,9,7,5,13];
for(int i=0;i!=a.length;++i)
{
for(int j=i+1;j!=a.length;++j)
{
int m=a[i]+a[j];
if (m>=14)
{
//如何在这里删除a[i]和a[j]?
}
}
}
return a;

高手帮我改改
[/Quote]
GARY 2011-06-16
  • 打赏
  • 举报
回复
GARY 2011-06-16
  • 打赏
  • 举报
回复

http://hi.csdn.net/attachment/201106/16/3408116_1308196803TPCt.jpg

测试了一下,应该可以了。再整理一下。
GARY 2011-06-16
  • 打赏
  • 举报
回复

#include <iostream>
#include <set>
using namespace std;

int main()
{
multiset<int> coll, coll_copy;
copy(istream_iterator<int>(cin), istream_iterator<int>(), inserter(coll, coll.begin()));
if (coll.count(7) > 0)
{
coll.erase(7);
}
copy(coll.begin(), coll.end(), inserter(coll_copy, coll_copy.begin()));

multiset<int>::iterator pos = coll.begin();
multiset<int>::iterator pos_copy;

bool b_erase = false;
for (; pos != coll.end();)
{
for (pos_copy = coll_copy.begin(); pos_copy != coll_copy.end(); ++pos_copy)
{
if (*pos + *pos_copy == 14)
{
b_erase = true;
coll.erase(pos++);
coll_copy.erase(pos_copy);
break;
}
}
if (!b_erase)
{
++pos;
}
else
{
b_erase = false;
}
}

coll.insert(7);
copy(coll.begin(), coll.end(), ostream_iterator<int>(cout, " "));
system("PAUSE");
}
不会再变le 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 mikemeego002 的回复:]
int[] a=[9,1,9,7,5,13];
for(int i=0;i!=a.length;++i)
{
for(int j=i+1;j!=a.length;++j)
{
int m=a[i]+a[j];
if (m>=14)
{
//如何在这里删除a[i]和a[j]?
}
}
}
return a;

高手帮我改改
[/Quote]
你这样做是错误的,你删除后,数组长度会发生改变,继续执行,数组会越界或者读出来一个乱码
不会再变le 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 a419635259 的回复:]
我给你个算法吧,懒得写了,再写不出来你就得去看基础了


1.检查数组长度length
2.取第一个数和后面的数陆续相加,取第二个数和后面的数陆续相加。。。。。要是有任意一对结果等于15,则删除这两个数(不是简单的删除,后面的数要补上来)。只要执行了删除操作,就重新执行步骤1。若步骤2执行完毕后,没有找到相加等于15的数,就打印最后结果,程序结束
[/Quote]
那啥,15改成14
不会再变le 2011-06-16
  • 打赏
  • 举报
回复
我给你个算法吧,懒得写了,再写不出来你就得去看基础了


1.检查数组长度length
2.取第一个数和后面的数陆续相加,取第二个数和后面的数陆续相加。。。。。要是有任意一对结果等于15,则删除这两个数(不是简单的删除,后面的数要补上来)。只要执行了删除操作,就重新执行步骤1。若步骤2执行完毕后,没有找到相加等于15的数,就打印最后结果,程序结束
mikemeego002 2011-06-16
  • 打赏
  • 举报
回复
int[] a=[9,1,9,7,5,13];
for(int i=0;i!=a.length;++i)
{
for(int j=i+1;j!=a.length;++j)
{
int m=a[i]+a[j];
if (m>=14)
{
//如何在这里删除a[i]和a[j]?
}
}
}
return a;

高手帮我改改
mikemeego002 2011-06-16
  • 打赏
  • 举报
回复
有人写好,保证结贴
Defonds 2011-06-16
  • 打赏
  • 举报
回复
写一个算法就是了
c_losed 2011-06-16
  • 打赏
  • 举报
回复
for循环遍历+容器
grwstc 2011-06-16
  • 打赏
  • 举报
回复
不知你觉得难在哪?是取2个数相加,还是剩余数排序,还是从数组删除元素?
ryfdizuo 2011-06-16
  • 打赏
  • 举报
回复
遍历中,置为-1表示删除
liao05050075 2011-06-16
  • 打赏
  • 举报
回复
两个for循环就行了吧?
张小毛 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 zhao4zhong1 的回复:]

引用 27 楼 delelebug 的回复:
引用 22 楼 delelebug 的回复:

这题如果把 任意两个数相加等于14, 改成任意三个数相加等于14,就有难度了

怎么没人理呢

解不唯一
[/Quote]
赵兄,你的头像是你的照片吗,蛮帅
加载更多回复(12)

64,654

社区成员

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

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