问题描述
1177: 按要求排序(指针专题)
时间限制: 1 Sec 内存限制: 128 MB
提交: 4896 解决: 2286
输入n和n个整数,然后按要求排序,若输入1,请输出升序排序序列;若输入2,请输出降序排序序列,若输入3,请输出按绝对值升序排序序列。要求程序结构如下,请完善程序。
void sort(int a[], int n, int (*cmp)());
int CmpAsc(int x, int y); /按升序要求判断两元素是否逆序/
int CmpDec(int x, int y); /按降序要求判断两元素是否逆序/
int CmpAbsAsc(int x, int y); /按绝对值升序要求判断两元素是否逆序/
int main(void)
{
int a[10],i,n;
int slt;
/读入n和n个整数,存入数组a/
/*读入用户的选择,存入slt; */
switch(slt)
{
case 1: sort(a, n, CmpAsc); break;
case 2: sort(a, n, CmpDec); break;
case 3: sort(a, n, CmpAbsAsc);break;
}
/输出排序后的数组/
}
void sort(int a[], int n, int (*cmp)())
{
/对数组a排序,排序原则由cmp指定,若cmp为真,表示两元素逆序/
}
int CmpAsc(int x, int y)
{
//如果x>y返回1,否则返回0;
}
int CmpDec(int x, int y)
{
//如果x<y返回1,否则返回0;
}
int CmpAbsAsc(int x, int y)
{
//如果abs(x)>abs(y)返回1,否则返回0
}
输入
输入第一行是一个正整数n;
输入第二行是n个整数;
输入第三行是一个1~3的整数slt,表示用户的排序要求。
输出
输出n个整数。若用户的排序选择是1,则输出升序排序后的n个整数;若用户的排序选择是2,则输出降序排序后的n个整数;若用户的排序选择是3,则输出按绝对值升序排序后的n个整数;输出占一行,数据之间用空格隔开。
样例输入 Copy
5
2 -3 1 5 4
2
样例输出 Copy
5 4 2 1 -3
提示
请采用稳定的排序算法
代码&注释
#include <iostream>
#include <cmath> // 使用 abs 函数 或者 fabs函数(浮点数绝对值)
void sort(int a[], int n, int (*cmp)(int x, int y));
int CmpAsc(int x, int y); /*按升序要求判断两元素是否逆序*/
int CmpDec(int x, int y); /*按降序要求判断两元素是否逆序*/
int CmpAbsAsc(int x, int y); /*按绝对值升序要求判断两元素是否逆序*/
int main(void)
{
using namespace std;
int * a, n;
int slt;
/*读入n和n个整数,存入数组a*/
cin >> n;
a = new int [n];
for ( int i = 0; i < n; i++ ) {
cin >> a[i];
}
/*读入用户的选择,存入slt; */
cin >> slt;
// 若输入1,请输出升序排序序列;
// 若输入2,请输出降序排序序列,
// 若输入3,请输出按绝对值升序排序序列。要求程序结构如下,请完善程序。
switch(slt)
{
case 1: sort(a, n, CmpAsc); break;
case 2: sort(a, n, CmpDec); break;
case 3: sort(a, n, CmpAbsAsc);break;
}
/*输出排序后的数组*/
for ( int i = 0; i < n - 1; i++ ) {
cout << a[i] << " ";
}
cout << a[n - 1];
// 释放内存
delete [] a;
return 0;
}
void sort(int a[], int n, int (*cmp)(int x, int y))
{
/*对数组a排序,排序原则由cmp指定,若cmp为真,表示两元素逆序*/
for (int i = 0; i < n - 1; i++) { // 简单选择排序
int k = i;
for (int j = i + 1; j < n; j++) {
if (cmp(a[k], a[j])) {
k = j;
}
}
int temp;
temp = a[i]; a[i] = a[k]; a[k] = temp;
}
}
int CmpAsc(int x, int y)
{
//如果x>y返回1,否则返回0;
if ( x > y ) return 1;
return 0;
}
int CmpDec(int x, int y)
{
//如果x<y返回1,否则返回0;
if ( x < y ) return 1;
return 0;
}
int CmpAbsAsc(int x, int y)
{
//如果abs(x)>abs(y)返回1,否则返回0
if ( abs(x) > abs(y) ) return 1; //abs头文件不是math.h而是stdlib.h 。 在C++中,只需要包括cmath即可。
else if ( x + y == 0 && x > y) return 1; // 绝对值相同
return 0;
}
补充 abs 函数知识
C语言中,
求整数的绝对值abs()和labs()应该包含stdlib.h
求浮点数的绝对值fabs()应该包含math.h
在C++中,
只需要包括cmath即可。
C标准:
只在 stdlib.h 中有定义abs():
int abs (int n);
C++标准:
在stdlib.h中
int abs ( int n);
long int abs (long int n);
在math.h中
double abs (double x);
float abs (float x);
long double abs (long double x);
参考网站:
=> C++参考网站
总结
忘了考虑绝对值相等的情况。
本例中 int (* cmp)(int x, int y) 作为一个参数很特别。它有点像一个抽象函数?
这里它有一个整数返回值,通过这个值判断是否逆序(和期望的排序是否相同)。
备注
这里的 sort 是个人定义的。
void sort(int a[], int n, int (*cmp)(int x, int y))
{
/*对数组a排序,排序原则由cmp指定,若cmp为真,表示两元素逆序*/
for (int i = 0; i < n - 1; i++) { // 简单选择排序
int k = i;
for (int j = i + 1; j < n; j++) {
if (cmp(a[k], a[j])) {
k = j;
}
}
int temp;
temp = a[i]; a[i] = a[k]; a[k] = temp;
}
}
对比下列函数
void sort(int a[], int n, int (*cmp)(int x, int y));
int (*cmp)(int x, int y);
// 上面的 cmp 函数和下面三个函数的传入参数,返回值类型 一模一样,
// 不同的地方除了名字(>.<)外,就是 多了一颗 *
int CmpAsc(int x, int y); /*按升序要求判断两元素是否逆序*/
int CmpDec(int x, int y); /*按降序要求判断两元素是否逆序*/
int CmpAbsAsc(int x, int y); /*按绝对值升序要求判断两元素是否逆序*/
而上面三个函数也有相同点,比如参数列标,返回值(类型)
不同点就是具体实现不一样,或者说比较的原则不一样:
int CmpAsc(int x, int y)
{
//如果x>y返回1,否则返回0;
if ( x > y ) return 1;
return 0;
}
int CmpDec(int x, int y)
{
//如果x<y返回1,否则返回0;
if ( x < y ) return 1;
return 0;
}
int CmpAbsAsc(int x, int y)
{
//如果abs(x)>abs(y)返回1,否则返回0
if ( abs(x) > abs(y) ) return 1; //abs头文件不是math.h而是stdlib.h 。 在C++中,只需要包括cmath即可。
else if ( x + y == 0 && x > y) return 1; // 绝对值相同
return 0;
}