简单题目,想看看大家不同的方法

yby4769250 2011-09-06 05:15:24
对一个数组,将数组中的偶数从大到小排序,奇数从小到大排序,排序后,奇数和偶数交叉存放,且数组第一位放奇数 ,若奇数和偶数不等长,则把剩下的直接放到数组中。

这是华为今天的机试题,挺简单的,主要想看看大家都有什么不同的想法,谁的方法最绝妙给谁最多分,呵呵
...全文
472 48 打赏 收藏 转发到动态 举报
写回复
用AI写文章
48 条回复
切换为时间正序
请发表友善的回复…
发表回复
newzai 2011-09-08
  • 打赏
  • 举报
回复
1. 统计偶数和奇数的个数。
2. 先把奇数放到 下标为 2*i的位置。偶数放在 2*i+1的位置。偶数多,则后面全部放偶数。奇数多则后面全部放奇数。
3. 对奇数和偶数分别进行冒泡排序。
life_at_606 2011-09-08
  • 打赏
  • 举报
回复
数组奇偶排放,分别排序,这个想法挺不错的。。
qingkongxiaoyang 2011-09-07
  • 打赏
  • 举报
回复
#include <iostream>
#include <string>
#pragma warning (disable:4786)
#include <map>

using namespace std;
#define LENGTH 100
void main()
{
int a[LENGTH] = {0};
int arraySize;
cout<<"请输入数组长度:"<<endl;
cin>>arraySize;
cout<<"请输入数组元素:"<<endl;
for(int j=0; j<arraySize; j++)
{
cin>>a[j];
}

map<int, int> singMap;
map<int, int> doubMap;
int result[LENGTH]={0};

for(int i=0; i<arraySize; i++)
{
if( a[i]%2 == 0 )
{
doubMap.insert(make_pair<int, int>(a[i], a[i]));
}
else
{
singMap.insert(make_pair<int, int>(a[i], a[i]));
}
}

map<int, int>::iterator iter;
map<int, int>::reverse_iterator riter;

i = 0;
for(iter = singMap.begin(),riter = doubMap.rbegin(); iter !=singMap.end() && riter!=doubMap.rend(); ++iter, ++riter)
{
result[i++]=(*iter).first;
result[i++]=(*riter).first;
}
while(iter!=singMap.end())
{
result[i++]=(*iter++).first;
}

while(riter!=doubMap.rend())
{
result[i++]=(*riter++).first;
}
cout<<"最终结果形式:"<<endl;
for(i=0; i<arraySize; i++)
{
cout<<result[i]<<endl;
}

}


这道题确实挺不错的。
我做了差不多一个小时才搞定。
使用map时,中间出现了点问题,一起调试不出来。
注意事项:
1、采用map,因为它本身提供了自动排序的功能。
2、使用rbgin的用法,可以解决由大到小排序的问题。
3、在做for做合并操作时,限定结束条件时,应该判定到底是什么关系?
开始时使用,
for(iter = singMap.begin(),riter = doubMap.rbegin(); iter !=singMap.end() riter!=doubMap.rend(); ++iter, ++riter)
导致程序一直有问题,试了好长时间也没解决。后来推荐是逗号的关系,此处为“与”的关系,即有一个到末尾即结束。
4、最后通过while循环来追加剩余的数据,这种方法很像数据结构中的链表合并操作。

以上,不知道算不算好的方法。
现在很喜欢使用vector,map之类的,遇到排序操作时,很容易会想到使用map。
we_sky2008 2011-09-07
  • 打赏
  • 举报
回复
可以先将原数组各元素交叉排放,然后再奇偶各自排序

#include<iostream>

using namespace std;

//奇偶交叉排放
void cross(int *src, int size)
{
int tmp;
int odd_flag = 1;
int i, j;

if (NULL == src || size <= 0)
return;

for (i = 0; i < size; ++i)
{
if (odd_flag != (src[i] & 1))
{
for (j = i + 1; j != size; ++j)
{
if (odd_flag == (src[j] & 1))
{
tmp = src[i];
src[i] = src[j];
src[j] = tmp;
}
}

if (j == size)
{
return;
}
}

odd_flag ^= 1;
}
}


//分别选择排序
void my_select_sort(int *src, int size)
{
int i, j;
int size_short = size - 1;
int tmp;
int odd_flag = 1;

if (NULL == src || size <= 0)
return;

for (i = 0; i < size_short; ++i)
{
for (j = i + 1; j < size; ++j)
{
if ((odd_flag == (src[j] & 1)) && (odd_flag == 1 ? src[j] < src[i] : src[j] > src[i]))
{
tmp = src[j];
src[j] = src[i];
src[i] = tmp;
}
}

odd_flag ^= 1;
}
}

void func(int *src, int size)
{
int i;

if (NULL == src || size <= 0)
return;

cross(src, size); //先奇偶交叉排放
my_select_sort(src, size); //再分别选择排序

for (i = 0; i < size; ++i)
{
cout<<src[i]<<' ';
}
cout<<endl;
}

int main()
{
int a[] = {1,2,3,4,5,6,7,8,9,10};

func(a, sizeof(a) / sizeof(a[0]));

system("pause");
return 0;
}

xiaolomg 2011-09-07
  • 打赏
  • 举报
回复
其实可以看到规律,不是那么难,而且要求必须在函数内完成所有代码
we_sky2008 2011-09-07
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 we_sky2008 的回复:]
可以先将原数组各元素交叉排放,然后再奇偶各自排序

C/C++ code


#include<iostream>

using namespace std;

//奇偶交叉排放
void cross(int *src, int size)
{
int tmp;
int odd_flag = 1;
int i, j;

if ……
[/Quote]

我在34楼的代码有点小错误,更正为:

#include<iostream>

using namespace std;

//奇偶交叉排放
void cross(int *src, int size)
{
int tmp;
int odd_flag = 1;
int i, j;

if (NULL == src || size <= 0)
return;

for (i = 0; i < size; ++i)
{
if (odd_flag != (src[i] & 1))
{
for (j = i + 1; j != size; ++j)
{
if (odd_flag == (src[j] & 1))
{
tmp = src[i];
src[i] = src[j];
src[j] = tmp;
}
}
}

odd_flag ^= 1;
}
}


//分别选择排序
void my_select_sort(int *src, int size)
{
int i, j;
int size_short = size - 1;
int tmp;
int odd_flag = 1;

if (NULL == src || size <= 0)
return;

for (i = 0; i < size_short; ++i)
{
for (j = i + 1; j < size; ++j)
{
if ((odd_flag == (src[j] & 1)) && (odd_flag == 1 ? src[j] < src[i] : src[j] > src[i]))
{
tmp = src[j];
src[j] = src[i];
src[i] = tmp;
}
}

odd_flag ^= 1;
}
}

void func(int *src, int size)
{
int i;

if (NULL == src || size <= 0)
return;

cross(src, size); //先奇偶交叉排放
my_select_sort(src, size); //再分别选择排序

for (i = 0; i < size; ++i)
{
cout<<src[i]<<' ';
}
cout<<endl;
}

int main()
{
int a[] = {1,2,3,4,5,6,7,8,9,10};

func(a, sizeof(a) / sizeof(a[0]));

system("pause");
return 0;
}


aszxqw 2011-09-07
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 jackyjkchen 的回复:]

路过围观,学生路过,还没到找工作的时候
[/Quote]
你是学生??!!
we_sky2008 2011-09-07
  • 打赏
  • 举报
回复
给出一种使用额外内存的方法:

#include<iostream>

using namespace std;

void aux(
int *src,
int size,
int *odd,
int *odd_num,
int *even,
int *even_num
)
{
int i, j, tmp;
int *cur, *num;

*odd_num = 0;
*even_num = 0;

for (i = 0; i < size; ++i)
{
cur = ((tmp = src[i]) & 1) ? odd + *odd_num : even + *even_num;
num = ((tmp = src[i]) & 1) ? odd_num : even_num;

//奇偶各自插入排序
while (cur > odd)
{
if (tmp < *(cur - 1))
{
*cur = *(cur - 1);
}
else
{
break;
}
--cur;
}

*cur = tmp;
++*num;
}

//拷贝到原数组
for (i = 0, j = *even_num; i != *odd_num && j != 0; )
{
*src++ = odd[i++];
*src++ = even[--j];
}
}

void func(int *src, int size)
{
int *odd = new int[size];
int *even = new int[size];
int odd_num, even_num;
int i;

aux(src, size, odd, &odd_num, even, &even_num);

for (i = 0; i < size; ++i)
{
cout<<src[i]<<' ';
}
cout<<endl;

delete[]odd;
delete[]even;
}

int main()
{
int a[] = {1,2,3,4,5,6,7,8,9,10};

func(a, sizeof(a) / sizeof(a[0]));

system("pause");
return 0;
}

__GUNS_N_ROSES__ 2011-09-07
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 qingkongxiaoyang 的回复:]

#include <iostream>
#include <string>
#pragma warning (disable:4786)
#include <map>

using namespace std;
#define LENGTH 100
void main()
{
int a[LENGTH] = {0};
int arraySize;
cout<<"请输……
[/Quote]

只是用到自动排序的功能为何不用multiset或者priority_queue? map用到这题来说用到大刀小用,而且map是效率相对低的容器。
huhaifengasd 2011-09-07
  • 打赏
  • 举报
回复
我的想法是先排序 在交换
ken_scott 2011-09-07
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 ken_scott 的回复:]
else if (array[j] > array[k]) {
[/Quote]
修改成

else if (1 == array[j] % 2 ? array[j] > array[k] : array[j] < array[k]) {
ken_scott 2011-09-07
  • 打赏
  • 举报
回复
晕错了 还有大小排序之分
ken_scott 2011-09-07
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 ken_scott 的回复:]
基本思想:冒泡排序
...
[/Quote]
昨天说的有些问题(虽然修改下方案还是可以做的), 最错的是叫成了冒泡排序, 代码就不写了
因为直接用选择排序就可以了(加点条件)

#include <iostream>

void select_sort(int array[], int size)
{
bool bDiffTreat = true; // need differentiate odd and even
for (int i = 0; i < size - 1; ++i) {
int j = i;
bool bFindFirst = (!bDiffTreat || 1 == (array[i] + i) % 2); // find first odd/even number
for (int k = i + 1; k < size; ++k) {
if (!bDiffTreat || 1 == (array[k] + i) % 2) {
if (!bFindFirst) {
j = k;
bFindFirst = true;
}
else if (array[j] > array[k]) {
j = k;
}
}
}

if (!bFindFirst) {
bDiffTreat = false;
--i;
}
else if (i != j) {
array[i] ^= array[j];
array[j] ^= array[i];
array[i] ^= array[j];
}
}
}

void print(int array[], int size)
{
for (int i = 0; i < size; ++i) {
std::cout << array[i] << ' ';
}
std::cout << std::endl;
}
int main()
{
{
int array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int size = sizeof(array) / sizeof(array[0]);
select_sort(array, size);
print(array, size);
}

{
int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int size = sizeof(array) / sizeof(array[0]);
select_sort(array, size);
print(array, size);
}

{
int array[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
int size = sizeof(array) / sizeof(array[0]);
select_sort(array, size);
print(array, size);
}

{
int array[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
int size = sizeof(array) / sizeof(array[0]);
select_sort(array, size);
print(array, size);
}

{
int array[] = {9, 7, 5, 3, 2, 1, 0};
int size = sizeof(array) / sizeof(array[0]);
select_sort(array, size);
print(array, size);
}

{
int array[] = {8, 6, 4, 3, 2, 1, 0};
int size = sizeof(array) / sizeof(array[0]);
select_sort(array, size);
print(array, size);
}

return 0;
}
夜夜风_ 2011-09-07
  • 打赏
  • 举报
回复
先排序 然后用迭代器 一个正向 一个反向 ,,至于排序那里还没想好。。。
yby4769250 2011-09-07
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 0153 的回复:]
来个委琐流,搞笑一下:

C/C++ code
#include <stdio.h>
void sortEO(int* piArr, int iNum)
{
int i,j,k,idx,iFlags = 0xB18D;
for (i = 0; i < iNum - 1; i++) {
k = i;
for (j = i + 1; j……
[/Quote]
这个看起来真的猥琐,理解起来也猥琐,呵呵
君恪 2011-09-07
  • 打赏
  • 举报
回复
个人思路:
1、遍历数组,将奇数和偶数放到不同的数组中。
2、分别将奇数和偶数排序
3、将奇偶数组交叉放回原数组。
这个应该是比较简单的方法了,用空间换时间,如果不对空间进行要求的话,应该是比较效率的做法了吧
yby4769250 2011-09-07
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 soulmate119 的回复:]
引用 16 楼 hacqing 的回复:
C/C++ code


bool sort( int *iArray, int iLen)
{
//对sort参数的有效性进行判断


//将iArray数组奇偶元素进行位置的调整


//进行奇元素排序


//进行偶元素排序
}
电子科大6号上午第一题 这样最直观了,上机试 这种最好想到!
[/Quote]

额呵呵,就是这样做的嘛
yby4769250 2011-09-07
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 we_sky2008 的回复:]
可以先将原数组各元素交叉排放,然后再奇偶各自排序

C/C++ code

#include<iostream>

using namespace std;

//奇偶交叉排放
void cross(int *src, int size)
{
int tmp;
int odd_flag = 1;
int i, j;

if (N……
[/Quote]

这个想法好
Ilijah 2011-09-07
  • 打赏
  • 举报
回复
{
检验有效性;
分别抽出奇数偶数数组;
分别排序;
分别写回
}

哎...
soulmate119 2011-09-07
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 hacqing 的回复:]
C/C++ code


bool sort( int *iArray, int iLen)
{
//对sort参数的有效性进行判断


//将iArray数组奇偶元素进行位置的调整


//进行奇元素排序


//进行偶元素排序
}
[/Quote]电子科大6号上午第一题 这样最直观了,上机试 这种最好想到!
加载更多回复(27)

64,646

社区成员

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

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