精华内容
下载资源
问答
  • 比如,有A、B、C三个员工竞选某要职,HR组织吃瓜群众位对其三位进行评分,出于不清楚的原因,HR在拿到群众们的评分结果后,会先对某侯选人的得分结果记录集进行排序,再按比例去掉记录两头(最高、最低)的N%评分...

    sql的优势之一是使用单一的命令能够访问到一个记录集,其重要的特点就是非过程化。

            在很多企业流行着360评分体系。比如,有A、B、C三个员工竞选某要职,HR组织吃瓜群众位对其三位进行评分,出于不清楚的原因,HR在拿到群众们的评分结果后,会先对某侯选人的得分结果记录集进行排序,再按比例去掉记录两头(最高、最低)的N%评分记录,最后再进行后续计算。

            本文是直接解决以上的“去掉记录两头的N%评分记录”的问题的。最少有以下几种方案:

          (本文代码基于SQL Server2005,关于@tb_eval表变量的定义见本文最后的附录)

    -- 去掉最高20%、最低20%评分

    select *
    from
    @tb_eval a01
    where a01.id not in (select top 20 percent id from @tb_eval a02 where a01.empid=a02.empid order by a02.score desc)
    and a01.id not in (select top 20 percent id from @tb_eval a02 where a01.empid=a02.empid order by a02.score asc)
    order by empid, score desc

     

    -- 去掉最高20%、最低20%评分

    select * 
    from 
    (
    	select row_number() over (partition by empid order by score desc) rowno, *
    	from @tb_eval
    ) a01
    where rowno > (select cast(round(count(*)*0.2,0) as int) padcnt from @tb_eval a02 where a01.empid=a02.empid)
    and rowno <= (select (count(*) - cast(round(count(*)*0.2,0) as int)) padcnt from @tb_eval a02 where a01.empid=a02.empid)

     

    -- 去掉最高20%、最低20%评分

    select a01.*
    from 
    (
    	select row_number() over (partition by empid order by score desc) rowno, *
    	from @tb_eval
    ) a01
    left join 
    (
    	select empid, cast(round(count(*)*0.2,0) as int) topcnt, cast(round(count(*)*0.2,0) as int) lastcnt, count(*) as totalcnt 
    	from @tb_eval 
    	group by empid
    ) a02
    on a01.empid=a02.empid
    where a01.rowno>a02.topcnt and a01.rowno <= (a02.totalcnt - a02. lastcnt)

      

    本问题其实像是大学时代的课后练习作业,写作本文的原因主要是想说明sql的非过程化,你不应该使用游标去完成本任务。

     附录:

    1、完整的代码

    -- 人员表(本例不使用)
    declare @tb_emp table table
    (
        id    int,				-- 人员ID
        name    varchar(64)		-- 人员名称
    );
    
    insert into @tb_emp (id, name) values(1, 'emp01');
    insert into @tb_emp (id, name) values(2, 'emp02');
    insert into @tb_emp (id, name) values(3, 'emp03');
    insert into @tb_emp (id, name) values(4, 'emp04');
    insert into @tb_emp (id, name) values(5, 'emp05');
    insert into @tb_emp (id, name) values(6, 'emp06');
    insert into @tb_emp (id, name) values(7, 'emp07');
    insert into @tb_emp (id, name) values(8, 'emp08');
    insert into @tb_emp (id, name) values(9, 'emp09');
    insert into @tb_emp (id, name) values(10, 'emp10');
    insert into @tb_emp (id, name) values(11, 'emp11');
    insert into @tb_emp (id, name) values(12, 'emp12');
    insert into @tb_emp (id, name) values(13, 'emp13');
    insert into @tb_emp (id, name) values(14, 'emp14');
    insert into @tb_emp (id, name) values(15, 'emp15');
    insert into @tb_emp (id, name) values(16, 'emp16');
    insert into @tb_emp (id, name) values(17, 'emp17');
    insert into @tb_emp (id, name) values(18, 'emp18');
    insert into @tb_emp (id, name) values(19, 'emp19');
    insert into @tb_emp (id, name) values(20, 'emp20');
    insert into @tb_emp (id, name) values(21, 'emp21');
    insert into @tb_emp (id, name) values(22, 'emp22');
    insert into @tb_emp (id, name) values(23, 'emp23');
    insert into @tb_emp (id, name) values(24, 'emp24');
    insert into @tb_emp (id, name) values(25, 'emp25');
    
    
    -- 评分表
    declare @tb_eval table
    (
    	    id	int not null identity(1,1) primary key,		-- 评分表自动编号
    	    empid int,						-- 被评分人员ID
    	    score decimal(10, 2),				-- 评分
                examinerid int					-- 评分人员ID
    );
    
    -- 给empid为1, 3, 5的评分
    insert into @tb_eval (empid, score, examinerid) values (1,9, 4);
    insert into @tb_eval (empid, score, examinerid) values (1,76, 19);
    insert into @tb_eval (empid, score, examinerid) values (1,37, 10);
    insert into @tb_eval (empid, score, examinerid) values (1,90, 13);
    insert into @tb_eval (empid, score, examinerid) values (1,29, 7);
    insert into @tb_eval (empid, score, examinerid) values (1,6, 2);
    insert into @tb_eval (empid, score, examinerid) values (1,69, 17);
    insert into @tb_eval (empid, score, examinerid) values (1,76, 5);
    insert into @tb_eval (empid, score, examinerid) values (1,60, 15);
    insert into @tb_eval (empid, score, examinerid) values (3,13, 20);
    insert into @tb_eval (empid, score, examinerid) values (3,49, 6);
    insert into @tb_eval (empid, score, examinerid) values (3,72, 25);
    insert into @tb_eval (empid, score, examinerid) values (3,84, 2);
    insert into @tb_eval (empid, score, examinerid) values (3,4, 22);
    insert into @tb_eval (empid, score, examinerid) values (3,17, 11);
    insert into @tb_eval (empid, score, examinerid) values (3,74, 18);
    insert into @tb_eval (empid, score, examinerid) values (3,66, 21);
    insert into @tb_eval (empid, score, examinerid) values (3,62, 8);
    insert into @tb_eval (empid, score, examinerid) values (3,4, 4);
    insert into @tb_eval (empid, score, examinerid) values (3,66, 13);
    insert into @tb_eval (empid, score, examinerid) values (3,41, 3);
    insert into @tb_eval (empid, score, examinerid) values (3,94, 16);
    insert into @tb_eval (empid, score, examinerid) values (5,87, 24);
    insert into @tb_eval (empid, score, examinerid) values (5,71, 14);
    insert into @tb_eval (empid, score, examinerid) values (5,39, 22);
    insert into @tb_eval (empid, score, examinerid) values (5,55, 12);
    insert into @tb_eval (empid, score, examinerid) values (5,13, 19);
    insert into @tb_eval (empid, score, examinerid) values (5,73, 16);
    insert into @tb_eval (empid, score, examinerid) values (5,45, 10);
    insert into @tb_eval (empid, score, examinerid) values (5,9, 15);
    insert into @tb_eval (empid, score, examinerid) values (5,4, 8);
    insert into @tb_eval (empid, score, examinerid) values (5,31, 11);
    
    -- 全部评分按empid分组后,每组从高到低评分
    select row_number() over (partition by empid order by score desc) rowno, * 
    from @tb_eval
    
    -- 去掉最高20%、最低20%评分
    select *
    from 
    @tb_eval a01 
    where a01.id not in (select top 20 percent id from @tb_eval a02 where a01.empid=a02.empid order by a02.score desc) 
    and a01.id not in (select top 20 percent id from @tb_eval a02 where a01.empid=a02.empid order by a02.score asc) 
    order by empid, score desc 
    
    -- 去掉最高20%、最低20%评分
    select a01.*
    from 
    (
    	select row_number() over (partition by empid order by score desc) rowno, * 
    	from @tb_eval 
    ) a01 
    left join 
    (
    	select empid, cast(round(count(*)*0.2,0) as int) topcnt, cast(round(count(*)*0.2,0) as int) endcnt, count(*) as totalcnt 
    	from @tb_eval 
    	group by empid 
    ) a02 
    on a01.empid=a02.empid 
    where a01.rowno>a02.topcnt and a01.rowno <= (a02.totalcnt - a02.endcnt) 
    
    -- 去掉最高20%、最低20%评分
    select * 
    from 
    ( 
    	select row_number() over (partition by empid order by score desc) rowno, * 
    	from @tb_eval 
    ) a01 
    where rowno > (select cast(round(count(*)*0.2,0) as int) padcnt from @tb_eval a02 where a01.empid=a02.empid) 
    and rowno <= (select (count(*) - cast(round(count(*)*0.2,0) as int)) padcnt from @tb_eval a02 where a01.empid=a02.empid) 
    


    2、未进行去头、去尾的结果: 

    rowno

    id

    empid

    score

    examinerid

    1

    4

    1

    90

    13

    2

    2

    1

    76

    19

    3

    8

    1

    76

    5

    4

    7

    1

    69

    17

    5

    9

    1

    60

    15

    6

    3

    1

    37

    10

    7

    5

    1

    29

    7

    8

    1

    1

    9

    4

    9

    6

    1

    6

    2

    1

    22

    3

    94

    16

    2

    13

    3

    84

    2

    3

    16

    3

    74

    18

    4

    12

    3

    72

    25

    5

    17

    3

    66

    21

    6

    20

    3

    66

    13

    7

    18

    3

    62

    8

    8

    11

    3

    49

    6

    9

    21

    3

    41

    3

    10

    15

    3

    17

    11

    11

    10

    3

    13

    20

    12

    14

    3

    4

    22

    13

    19

    3

    4

    4

    1

    23

    5

    87

    24

    2

    28

    5

    73

    16

    3

    24

    5

    71

    14

    4

    26

    5

    55

    12

    5

    29

    5

    45

    10

    6

    25

    5

    39

    22

    7

    32

    5

    31

    11

    8

    27

    5

    13

    19

    9

    30

    5

    9

    15

    10

    31

    5

    4

    8


    3、去头、去尾后的结果:

    rowno

    id

    empid

    score

    examinerid

    3

    8

    1

    76

    5

    4

    7

    1

    69

    17

    5

    9

    1

    60

    15

    6

    3

    1

    37

    10

    7

    5

    1

    29

    7

    4

    12

    3

    72

    25

    5

    17

    3

    66

    21

    6

    20

    3

    66

    13

    7

    18

    3

    62

    8

    8

    11

    3

    49

    6

    9

    21

    3

    41

    3

    10

    15

    3

    17

    11

    3

    24

    5

    71

    14

    4

    26

    5

    55

    12

    5

    29

    5

    45

    10

    6

    25

    5

    39

    22

    7

    32

    5

    31

    11

    8

    27

    5

    13

    19




    展开全文
  • ] ,int count,CompareFunctionPointer cfp)函数,调用函数(使用switch…case,通过控制台输入的数字与枚举值匹配实现调用不同的函数)来分别实现按姓名、员工编号、评分排序,其中每种排序的升、降方式都要实现。...
    <pre name="code" class="cpp"><p><span style="font-family:Microsoft YaHei;font-size:18px;">①   创建一个Teacher数组,利用上面的sortTeachers(Teacher  teacher[ ] ,int count,CompareFunctionPointer  cfp)函数,调用函数(使用switch…case,通过控制台输入的数字与枚举值匹配实现调用不同的函数)来分别实现按姓名、员工编号、评分排序,其中每种排序的升、降方式都要实现。比如:分别实现对年龄按照升序、降序排列。</span></p><p><span style="font-family:Microsoft YaHei;font-size:18px;">②   输出教师数组中全部的男老师。</span></p><p><span style="font-family:Microsoft YaHei;font-size:18px;">③   输出教师数组中的所有女老师。 </span></p>
    
    
    
    /<span style="font-size:24px;">/  Teacher.h</span>
    //  Exame
    //
    //  Created by lanou3g on 15-3-25.
    //  Copyright (c) 2015年 lanou3g. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    // 第二种定义
    // 性别
    // typedef enum sex
    // {
    //    Man,
    //    Woman
    // } Sex;
    
    // typedef struct teacher
    // {
    //    char name[20];
    //     Sex sex;
    //    int age;
    //    int num;
    //    float score;
    //    
    // } Teacher;
    
    typedef struct teacher
    {
        char name[20];
        char sex;
        int age;
        int num;
        float score;
        
    } Teacher;
    
    
    enum FunctionName
    {
        CompareNameByAscending = 1,
        CompareNameByDescending,
        CompareNumberByAscending,
        CompareNumberByDescending,
        CompareScoreByAscending,
        CompareScoreByDescending,
        PrintFemaleTeacher,
        PrintMaleTeacher
        
        
    };
    void printTeacher(Teacher *teacher);
    
    typedef BOOL (*CompareFunctionPointer)(Teacher teacher1,Teacher teacher2);
    
    void sortTeachers(Teacher teacher[],int count,CompareFunctionPointer cfp);//<span style="font-size:24px;"><strong>函数指针的利用</strong></span>
    
    void printTeachers(Teacher *teachers,int count);
    
    BOOL compareNumberAscending(Teacher teacher1,Teacher teacher2);
    BOOL compareNumberDescending(Teacher teacher1,Teacher teacher2);
    
    BOOL compareNameAscending(Teacher teacher1,Teacher teacher2);
    BOOL compareNameDescending(Teacher teacher1,Teacher teacher2);
    
    BOOL compareScoreDescending(Teacher teacher1,Teacher teacher2);
    BOOL compareScoreAscending(Teacher teacher1,Teacher teacher2);
    
    
    void printMaleTeacher(Teacher *teacher,int count);
    void printFemaleTeacher(Teacher *teacher,int count);
    
    
    
    
    
    
    
    <pre name="code" class="cpp">//
    // <strong><span style="font-size:18px;"> Teacher.m</span></strong>
    //  Exame
    //
    //  Created by lanou3g on 15-3-25.
    //  Copyright (c) 2015年 lanou3g. All rights reserved.
    //
    
    #import "Teacher.h"
    
    void printTeacher(Teacher *teacher)
    {
        printf("姓名:%s,性别:%c,年龄:%d,编号:%d,评分:%f\n",teacher->name,teacher->sex,teacher->age,teacher->num,teacher->score);
    }
    
    typedef BOOL (*CompareFunctionPointer)(Teacher teacher1,Teacher teacher2);//<span style="font-size:24px;">定义函数指针</span>
    
    void sortTeachers(Teacher teacher[],int count,CompareFunctionPointer cfp)//<span style="font-size:24px;">函数回调</span>
    {
        for (int i = 0; i < count - 1; i ++) {
            for (int j = 0; j < count - i - 1; j ++) {
                if (cfp(teacher[j],teacher[j+1])) {
                    Teacher tea = teacher[j];
                    teacher[j] = teacher[j+1];
                    teacher[j+1] = tea;
                }
            }
        }
    }
    
    void printTeachers(Teacher *teachers,int count)
    {
        for (int i = 0; i < count; i ++) {
            printTeacher(&teachers[i]);
        }
    }
    
    BOOL compareNumberAscending(Teacher teacher1,Teacher teacher2)
    {
        return teacher1.num > teacher2.num;
    }
    BOOL compareNumberDescending(Teacher teacher1,Teacher teacher2)
    {
        return teacher1.num < teacher2.num;
    }
    BOOL compareNameAscending(Teacher teacher1,Teacher teacher2)
    {
        //return strcmp(teacher1.name,teacher2.name);
        if (strcmp(teacher1.name,teacher2.name) > 0) {
            return YES;
        }
        else
            return NO;
    }
    BOOL compareNameDescending(Teacher teacher1,Teacher teacher2)
    {
        //return strcmp(teacher2.name, teacher1.name);
        if (strcmp(teacher1.name,teacher2.name) < 0) {
            return YES;
        }
        else
            return NO;
    
    }
    
    BOOL compareScoreDescending(Teacher teacher1,Teacher teacher2)
    {
        return teacher1.score < teacher2.score;
    }
    BOOL compareScoreAscending(Teacher teacher1,Teacher teacher2)
    {
        return teacher1.score > teacher2.score;
    }
    
    
    void printMaleTeacher(Teacher *teacher,int count)
    {
        for (int i = 0; i < count; i ++) {
            if (teacher[i].sex == 'm') {
                printTeacher(&teacher[i]);
            }
        }
    }
    void printFemaleTeacher(Teacher *teacher,int count)
    {
        for (int i = 0; i < count; i ++) {
            if (teacher[i].sex == 'f') {
                printTeacher(&teacher[i]);
            }
        }
    }
    
    <strong><span style="font-size:24px;">主函数的实现</span></strong>
    <pre name="code" class="cpp">//
    //  main.m
    //  Exame
    //
    //  Created by lanou3g on 15-3-25.
    //  Copyright (c) 2015年 lanou3g. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import "Teacher.h"
    
    int main(int argc, const char * argv[])
    {
        printf("输入1:实现按照姓名进行升序排列\n输入2:实现按照姓名进行降序排列\n输入3:实现按照员工编号进行升序排列\n输入4:实现按照员工编号进行降序排列\n输入5:实现按照评分进行升序排列\n输入6:实现按照评分进行降序排列\n输入7:实现输出所有的女老师\n输入8:实现输出所有的男老师\n");
        printf("=====================\n");
        printf("请输入实现功能对应的数字:\n");
    
     
        Teacher teacher[4] = {{"zhangsan",'m',23,34,5.5},{"lishi",'f',45,56,3.5},{"wangwu",'m',22,12,1.3},{"songliu",'f',45,12,3.2}};
        
        int n = 0;
        while (scanf("%d",&n)!=EOF) {
           
            if (n >= 1 && n <= 8) {
                switch (n) {
                    case CompareNameByAscending:
                        sortTeachers(teacher,4,compareNameAscending);
                        printTeachers(teacher,4);
                        break;
                    case CompareNameByDescending:
                        sortTeachers(teacher,4,compareNameDescending);
                        printTeachers(teacher,4);
                        break;
                    case CompareNumberByAscending:
                        sortTeachers(teacher,4,compareNumberAscending);
                        printTeachers(teacher,4);
                        break;
                    case CompareNumberByDescending:
                        sortTeachers(teacher,4, compareNumberDescending);
                        printTeachers(teacher,4);
                        break;
                    case CompareScoreByAscending:
                        sortTeachers(teacher,4, compareScoreAscending);
                        printTeachers(teacher,4);
                         break;
                    case CompareScoreByDescending:
                        sortTeachers(teacher,4, compareScoreDescending);
                        printTeachers(teacher,4);
                         break;
                    case PrintFemaleTeacher:
                        printFemaleTeacher(teacher,4);
                        break;
                    case PrintMaleTeacher :
                        printMaleTeacher(teacher,4);
                        break;
                   
    
                    default:
                        break;
                }
            }
            
            else
                printf("请重新输入:\n");
        }
            
    
        return 0;
    }
    

    
    
    
    
    展开全文
  • 任务要求:部门每个人绩效考核评分后,表格根据分数,对所有员工进行自动排名并排序,不是显示名次,而是自动按名次重新排列员工顺序。说的多,不如看看动图化的要求吧,就像这样:看明白了么?其实一开始觉得这个...
    这是一个很有趣的案例。任务要求:部门每个人绩效考核评分后,表格根据分数,对所有员工进行自动排名并排序,不是显示名次,而是自动按名次重新排列员工顺序。说的多,不如看看动图化的要求吧,就像这样:a38b7e36080d36d72c04dfcc8ea2dbae.gif看明白了么?其实一开始觉得这个任务是个悖论,一方面我算出来结果,然后根据结果又原位排列顺序,是不合逻辑的。不过我们可以换个思路,我们可以改为2张表,表1用来计算结果,表2接收表1的结果并自动排列,这样就打破了悖论。这段话没看懂也不要紧,文章看完再回来看这一段。第一步:完成表格版式,及表1数据录入7a0948cad368c54584dedcdc4ae52d02.png为演示方便,将表1设为静态表,实际工作中加公式就可以改造为动态的。表1的排名其实可以不设置,这里加上是为了看的清楚。将员工姓名复制粘贴到表2,并用VLOOKUP从表1取得分。b2b1bdd499c48997fbf280436c460ff9.gif第二步:手动排序,并录制宏这步很关键。自动排列,首先想到这是代码干的,所以要用到宏或VBA。我们先告诉EXCEL要干什么,即录个片段,让EXCEL自动执行就好。点击录制宏,名字随意。然后选择“得分”和“员工姓名”列,记住这里一定不要反哦,因为我们是要按分数排序。然后点击“数据”选项卡——“降序”,再点击停止录制宏,可以查看代码。

    3c2a7f2925ef5661b0cdce8d3ec460f6.gif

    c0ca82b57beca6234bdd2958c5fcb73c.png至此,静态的排序操作已经完成了,我们加个排名吧。

    fdce7f904f5a6745703a659118ce9e68.png

    第三步:让表格动起来这步思想是,每次我操作后,让EXCEL自动做一次自动排序工作,即调用一次“宏2”。点击“开发工具”选项卡——“Visual Basic”,就打开了VBE环境。双击左侧的Sheet1,然后右侧界面第一个下拉框选择“Worksheet”,第二个下拉框选择“SelectionChange”。然后在第一个SUB过程中写上“宏2”,关掉就好。其实前面步骤可以给“宏2”起个好点的名字,比如“自动排名排序”,这里引用的时候就很清楚。

    f5cf0121ee3e00bb199130411388a406.gif

    下面就是验证操作结果的时候了!再看一遍动图:a38b7e36080d36d72c04dfcc8ea2dbae.gif完成任务!注意保存文件!因为是有代码的,所以需要保存为启用宏的工作簿xlsm格式。你以为这就结束了??等等,发现排名有点问题。好几个并列分,排名怎么不一样?这里我们写个公式就好,E3=COUNTIF($G$3:$G$20,">"&G3)+1,在右侧得分已经排好序的情况下进行计算。公式具体什么意思呢?简单说,就是计算这个区域数字比G3大的次数,因为牛人7已经最高分了,所以COUNTIF的结果就是0,然后加个1,就是排名;同样啊,牛人9也是并列最高分,所以COUNTIF的结果也是0,然后加个1,就实现了并列第一的目的。再到牛人3,有2个分比他高,所以排名就是2+1=3。

    eb334ab51d45e6a9c291cec3ea77aa3c.png

    保存文件,打完收工。

    e7b58d49658c386d21a86b5f593bc348.png

    学有用的知识,做有用的表15036abbdecebf13adffb9d5371ff6ac.png

    展开全文
  • 定义一个Teacher结构体包括:姓名,性别,年龄,员工编号,评分 2.定义一个对结构体数组排序的函数,包括一个返回值为BOOl类型的回调函数,实现按照不同的条件对结构体成员排序 3.定义一个打印所有老师信息的函数 ...

    需求分析

    1.定义一个Teacher结构体包括:姓名,性别,年龄,员工编号,评分
    2.定义一个对结构体数组排序的函数,包括一个返回值为BOOl类型的回调函数,实现按照不同的条件对结构体成员排序
    3.定义一个打印所有老师信息的函数
    4.实现多个返回值为BOOL类型的函数,用来判断排序中的if交换变量条件
    5.定义一个判断并打印所有男老师和女老师的函数
    6.定义一个枚举类型,和控制台输入功能的数字相对应
    7.使用while循环实现重新输入功能,若输入功能以外的数字,则提示重新输入界面截图


    函数声明

    Teacher.h

    //定义一个Teacher结构体
    typedef struct teacher {
        char name[20];
        char gender;
        int age;
        int number;
        float score;
    }Teacher;
    //声明一个枚举和用户从控制台输入的功能数字对应
    enum FunctionName {
        CompareNameByAscending = 1,
        CompareNameByDescending,
        CompareNumberByAscending,
        CompareNumberByDescending,
        CompareScoreByAscending,
        CompareScoreByDescending,
        PrintMaleTeacher,
        PrintFemaleTeacher
    };
    //打印一个Teacher的函数
    void printTeacher(Teacher *teacher);
    //声明一个函数指针类型,判断条件真假
    typedef BOOL(*CompareFunctionPointer)(Teacher teacher1, Teacher teacher2);
    //Teacher结构体数组排序函数
    void sortTeachers(Teacher teacher[], int count, CompareFunctionPointer cfp);
    //打印Teach结构体数组中所有老师信息
    void printTeachers(Teacher *teachers, int count);
    //按照名字升序排序
    BOOL compareNameByAscending(Teacher teacher1, Teacher teacher2);
    //按照名字降序排序
    BOOL compareNameByDescending(Teacher teacher1, Teacher teacher2);
    //按编号升序排序
    BOOL compareNumberByAscending(Teacher teacher1, Teacher teacher2);
    //按编号降序排序
    BOOL compareNumberByDescending(Teacher teacher1, Teacher teacher2);
    //按评分升序排序
    BOOL compareScoreByAscending(Teacher teacher1, Teacher teacher2);
    //按评分降序排序
    BOOL compareScoreByDescending(Teacher teacher1, Teacher teacher2);
    //输出全部男老师
    void printMaleTeacher(Teacher *teachers, int count);
    //输出全部女老师
    void printFemaleTeacher(Teacher *teachers, int count);
    //打印操作说明
    void printInstructions();
    //重命名输出男女老师函数指针
    typedef void (*PrintByGender)(Teacher *teachers, int count);

    函数实现


    Teacher.m

    //打印Teacher的函数
    void printTeacher(Teacher *teacher) {
        printf("Name:%-20sGender:%-20cAge:%-20dNumber:%-20dScore:%-20f\n", teacher->name, teacher->gender, teacher->age, teacher->number, teacher->score);
    }
    //Teacher结构体数组排序函数
    void sortTeachers(Teacher teacher[], int count, CompareFunctionPointer cfp) {
        for (int i = 0; i < count - 1; i++) {
            for (int j = 0; j < count - 1 - i; j++) {
                if (cfp(teacher[j], teacher[j + 1])) {
                    Teacher temp = teacher[j];
                    teacher[j] = teacher[j + 1];
                    teacher[j + 1] = temp;
                }
            }
        }
    }
    //打印Teach结构体数组中所有老师信息
    void printTeachers(Teacher *teachers, int count) {
        for (int i = 0; i < count; i++) {
            printf("Name:%-20sGender:%-20cAge:%-20dNumber:%-20dScore:%-20f\n", teachers[i].name, teachers[i].gender, teachers[i].age, teachers[i].number, teachers[i].score);
        }
    }
    //按照名字升序排序
    BOOL compareNameByAscending(Teacher teacher1, Teacher teacher2) {
        if (strcmp(teacher1.name, teacher2.name) > 0) {
            return YES;
        }
        return NO;
    }
    //按照名字降序排序
    BOOL compareNameByDescending(Teacher teacher1, Teacher teacher2) {
        if (strcmp(teacher1.name, teacher2.name) < 0) {
            return YES;
        }
        return NO;
    }
    //按编号升序排序
    BOOL compareNumberByAscending(Teacher teacher1, Teacher teacher2) {
        if (teacher1.number > teacher2.number) {
            return YES;
        }
        return NO;
    }
    //按编号降序排序
    BOOL compareNumberByDescending(Teacher teacher1, Teacher teacher2) {
        if (teacher1.number < teacher2.number) {
            return YES;
        }
        return NO;
    }
    //按评分升序排序
    BOOL compareScoreByAscending(Teacher teacher1, Teacher teacher2) {
        if (teacher1.score > teacher2.score) {
            return YES;
        }
        return NO;
    }
    //按评分降序排序
    BOOL compareScoreByDescending(Teacher teacher1, Teacher teacher2) {
        if (teacher1.score < teacher2.score) {
            return YES;
        }
        return NO;
    }
    //输出全部男老师
    void printMaleTeacher(Teacher *teachers, int count) {
        for (int i = 0; i < count; i++) {
            if (teachers[i].gender == 'm') {
                printf("Name:%-20sGender:%-20cAge:%-20dNumber:%-20dScore:%-20f\n", teachers[i].name, teachers[i].gender, teachers[i].age, teachers[i].number, teachers[i].score);
            }
        }
    }
    //输出全部女老师
    void printFemaleTeacher(Teacher *teachers, int count) {
        for (int i = 0; i < count; i++) {
            if (teachers[i].gender == 'f') {
                printf("Name:%-20sGender:%-20cAge:%-20dNumber:%-20dScore:%-20f\n", teachers[i].name, teachers[i].gender, teachers[i].age, teachers[i].number, teachers[i].score);
            }
        }
    }
    //声明一个枚举和用户从控制台输入的功能数字对应
    typedef enum FunctionName List;
    //打印操作说明
    void printInstructions() {
        printf("输入1:实现按照姓名进行升序排序\n");
        printf("输入2:实现按照姓名进行降序排序\n");
        printf("输入3:实现按照员工编号进行升序排序\n");
        printf("输入4:实现按照员工编号进行降序排序\n");
        printf("输入5:实现按照评分进行升序排序\n");
        printf("输入6:实现按照评分进行降序排序\n");
        printf("输入7:实现输出所有的男老师\n");
        printf("输入8:实现输出所有的女老师\n");
        printf("=================================\n");
        printf("请输入实现功能对应的数字:");
    }

    函数调用


    main.m

    //创建Teacher类型的结构体数组
    Teacher teachers[] = {
        {"CLS", 'f', 35, 120, 100.0},
        {"XQC", 'f', 32, 100, 98.5},
        {"CGX", 'm', 36, 110, 99.5},
        {"XDL", 'f', 30, 90, 59.5},
        {"ZSY", 'm', 24, 190, 60.0}
    };
    int main(int argc, const char * argv[]) {
        //定义变量
        CompareFunctionPointer function = NULL;
        int n = 0;
        BOOL isAgain = YES;
        int count = sizeof(teachers) / sizeof(teachers[0]);
        //输出用户操作说明
        printInstructions();
        while (isAgain) {
            function = NULL;
            scanf("%d", &n);
            switch (n) {
                case CompareNameByAscending:
                    function = compareNameByAscending;
                    break;
                case CompareNameByDescending:
                    function = compareNameByDescending;
                    break;
                case CompareNumberByAscending:
                    function = compareNumberByAscending;
                    break;
                case CompareNumberByDescending:
                    function = compareNumberByDescending;
                    break;
                case CompareScoreByAscending:
                    function = compareScoreByAscending;
                    break;
                case CompareScoreByDescending:
                    function = compareScoreByDescending;
                    break;
                case PrintFemaleTeacher:
                    printFemaleTeacher(teachers, count);
                    break;
                case PrintMaleTeacher:
                    printMaleTeacher(teachers, count);
                    break;
                default: {
                    printf("对不起您输入的数字没有对应的函数,请重新输入:");
                    break;
                }
            }
            if (function != NULL) {
                sortTeachers(teachers, count, function);
                printTeachers(teachers, count);
            }
        }
        return 0;
    }
    

    案例分析

    博主手把手教你玩转回调函数


    • 拿到一个案例,博主首先想到的是通过需求分析来设计一个程序的整体架构,尽可能将程序拆分为几个独立的模块,并提高程序的内聚性,减少程序的耦合性。接下来博主将通过对本案例尽可能详细的分析来说明这一点。
    • 首先我们先放下回调函数不管,按照由整体到局部来对这一案例进行分析,题目要求是创建一个结构体数组并且按照一定的顺序输出,那我们就可以先声明一个结构体,并且写一个函数,用来输出结构体数组的每一个成员的变量。这里楼主使用了typedef对结构体重命名,不懂的童鞋自行脑补,内事问度娘。
    • 第一步我们做完了,题目的要求是输出排序后的信息,我们可以写一个函数对数组进行排序。我们就先做一个按照评分对老湿们进行排序吧,之前都是老湿们给我们排序,现在换做我们给老湿们排序了,想想都暗爽那!闲话少叙,使用冒泡排序,对结构体数组按照比较部分交换整体的思想进行交换。
         for (int i = 0; i < count - 1; i++) {
            for (int j = 0; j < count - 1 - i; j++) {
                if ((teacher[j].score - teacher[j + 1].score) > 0) {
                    Teacher temp = teacher[j];
                    teacher[j] = teacher[j + 1];
                    teacher[j + 1] = temp;
                }
            }
        }
    • 看到这里有人要说了,既然这都已经可以实现了,为什么还要使用函数回调来做?这个问题问得好!如果只按照一种规则对结构体数组排序,确实这样就已经实现了,但题目是要求按照几种方式对老湿门进行排序,这时使用函数回调就能体现其优越性了。通过分析题目,改变排序规则改变的就是冒泡排序中的if判断条件,那么如果我们能将判断条件作为一个参数传入函数的话,就可以通过在主调函数中改变排序的条件。
      (teacher[j].score - teacher[j + 1].score) > 0
    • 按照这个思路继续想,怎样能将一个判断条件作为函数的参数传入到该函数中那?博主告诉你,回调函数就可以实现这个神奇的功能。有的看客们又要问,为什么回调函数可以作为函数参数那?这个问题问得妙,首先函数是存储在内存中一块叫做代码区的空间的,函数就存储在这块区域,并且每个函数都有一个地址,也就是指针,如果能得到这个地址的话,就可以通过调用定义指针变量指向该地址并调用该函数。
      函数名代表函数首地址,这例子代表定义一个返回值是int型并且有2个int型参数的函数指针p指向fun函数。
      int (*p)(int a, int b) = fun;
    • 首先需要定义一个返回值是BOOL类型并且有两个Teacher结构体变量的函数
      BOOL isTrue(Teacher teacher1, Teacher teacher2);
      为了让函数指针作为参数,需要定义一个相同类型的函数指针类型
      typedef BOOL(*CompareFunctionPointer)(Teacher teacher1, Teacher teacher2);
      看到了吧,有了两个结构体参数teacher1和teacher2就可以尽情的对老湿们进行各种方式的排序了。
    • 接下来定义几个CompareFunctionPointer类型的函数用来实现不同的排序,博主写了按照6中方式排序,看客们可以再自行编写对年龄的排序函数。
      void sortTeachers(Teacher teacher[], int count, CompareFunctionPointer cfp);
      根据博主的提示,相信大家都能完成这样一个排序的函数,其中的cfp就是我们讲到的函数指针,在函数实现部分也会很简单,还记得上面提到的冒泡排序嘛,只要在if的括号中调用函数cfp(teacher[j], teacher[j + 1])
    • 好了,万事俱备,接下来就要见证奇迹了,回到主调函数main.m中,先传入一个按照名字升序排序的函数并打印。注意函数指针参数,博主传入的是一个函数名字,而且没有括号和参数哦,原因上面已经说过了,函数名就是函数的地址,也叫做函数指针。输出结果就是按照名字升序排序的老湿信息。
    int count = sizeof(teachers) / sizeof(teachers[0]);
    printInstructions();
    sortTeachers(teachers, count, compareNameByAscending);
    printTeachers(teachers, count);

    按姓名升序

    • 亲们看到这里不知道你们理解了没有,小编答应说要尽量详尽的带着大家学习函数回调,那就再带着大家来总结一下吧。
      1.函数回调适用范围:这个东西是一个比普通函数更有逼格的函数,但亲们也要分析具体案例决定使用与否。一般情况下回调函数可以用来替换在函数中的表达式中,达到动态改变条件的作用。
      2.函数回调的使用步骤:首先找到要替换的表达式,写出替换的函数并实现,并定义一个相同类型的函数指针类型,在原函数中加入函数指针类型参数,用回调函数替换原函数表达式部分。

    博主讲到这里函数回调部分的内容就差不多结束了,本题目中要求输入功能对应数字并打印,那能不能通过输入一个字符串来调用对应的函数那?博主先卖个关子,看客们可以自行实现输入一个运算单词,例如:sum,max,minGB实现和函数的匹配,博主将在下一篇博客中和亲们分享:返回值是函数指针的函数。亲们记得关注哦。

    展开全文
  • 在Excel表格中数据的排序是一个经常使用的功能。如果需要对实时更新的数据排序,你是否还在更新...现要求根据每个员工各个任务的总评分进行实时的升序排序(新增任务评分之后自动更新),用于统计工作难度和下次分配任...
  • 任务要求:部门每个人绩效考核评分后,表格根据分数,对所有员工进行自动排名并排序,不是显示名次,而是自动按名次重新排列员工顺序。说的多,不如看看动图化的要求吧,就像这样:看明白了么?其实一开始觉得这个...
  • 在Teacher.h中,定义一个Teacher结构体,成员变量包括:姓名、性别、年龄、员工编号、评分。2分 声明一个打印Teacher的函数,void printTeacher(Teacher * teacher)。1分 实现部分 4分 定义一个函数指针类型,...
  • 支持主观题人工评分、客观题自动评分 支持报名考试、指定人员考试等考试方式 支持试题导入导出 支持试卷导出到Word 支持以整张试卷方式编辑试题 支持无限层次的机构分组 支持总公司-分公司-中心支公司等数据...
  • 活动现场管理系统 v1.0 是一套活动现场电子网络管理系统,可在线进行 web 应用,无需客户端,可联网操作、可单机操作、可在投影大屏上适时显示,包含了一般活动出席人员签到、竞赛活动选手评分、电子摇号、选举唱票...
  • EnableQ提供的问卷设计功能包含最为全面的20多种调查问卷问题题型,不仅包含基础的单选、多选、填空、多行填空问题题型,更囊括矩阵单选、评分、比重、排序、文件上传等高阶问题类型。多个不同或相同的问题题型可在...
  • EnableQ v8.20免费版

    2018-10-23 14:34:12
    EnableQ提供的问卷设计功能包含最为全面的20多种调查问卷问题题型,不仅包含基础的单选、多选、填空、多行填空问题题型,更囊括矩阵单选、评分、比重、排序、文件上传等高阶问题类型。多个不同或相同的问题题型可在...
  • EnableQ提供的问卷设计功能包含最为全面的20多种调查问卷问题题型,不仅包含基础的单选、多选、填空、多行填空问题题型,更囊括矩阵单选、评分、比重、排序、文件上传等高阶问题类型。多个不同或相同的问题题型可在...
  • 比如入门级的电商网站商品管理案例,基于版本号进行乐观锁并发控制的实验,mget+bulk批量处理的实验,scoll滚动搜索大量数据的实验,scoll+bulk+alias零停机重建索引的实验,基于Java开发的员工管理案例,等等。...
  • Excel百宝箱8.0

    2011-06-07 21:32:17
    【根据工资计算钞票】:根据员工的工资计算需要多少张100元、50元......1元的钞票,可以批量计算。发现金工资的财务工作者必备 【隔行插入行】:对工作表隔行插入行,或者隔列插入列,其中行数可以自定义 【折分工作...
  • 【根据工资计算钞票】根据员工的工资计算需要多少张100元、50元......1元的钞票,可以批量计算。发现金工资的财务工作者必备 【隔行插入行】对工作表隔行插入行,或者隔列插入列,其中行数可以自定义 【折分工作簿】...
  • 16.3.3 对公司不满的员工 16.3.4 硬件被盗 16.3.5 我们自身 16.4 代码的安全性 16.4.1 过滤用户输入 16.4.2 转义输出 16.4.3 代码组织 16.4.4 代码自身的问题 16.4.5 文件系统因素 16.4.6 代码稳定性和缺陷 16.4.7 ...
  • 【按颜色排序】:让Excel 2003也可以按背景色排序数据,2007或者2010用户不需要使用 【返回首页】:配合建立工作表目录工具使用,可以在任何工作表中瞬间返回第一个工作表 【工作簿标签】:将当前开启的工作簿创建...
  • C#开发典型模块大全

    2014-03-12 18:11:22
    11.2.7 对ListView控件中的项进行排序 267 11.3 设计过程 267 11.3.1 主窗体预览 267 11.3.2 批量复制、剪切文件 268 11.3.3 批量复制、剪切文件夹 270 11.3.4 批量重命名文件 271 11.3.5 批量删除文件...
  • 【取RMB张数】 根据员工的工资计算需要多少张100元、50元......1元的钞票,可以批量累计计算。发现金工资的财务工作者的必备工具之一。 【数字转英文】 将选中区域(默认)或已使用区域存储格的金额数字转换成英文...
  • EXCEL集成工具箱V6.0

    2010-09-11 01:44:37
    【取RMB张数】 根据员工的工资计算需要多少张100元、50元......1元的钞票,可以批量累计计算。发现金工资的财务工作者的必备工具之一。 【数字转英文】 将选中区域(默认)或已使用区域存储格的金额数字转换成英文...
  • 【取RMB张数】 根据员工的工资计算需要多少张100元、50元......1元的钞票,可以批量累计计算。发现金工资的财务工作者的必备工具之一。 【数字转英文】 将选中区域(默认)或已使用区域存储格的金额数字转换成英文...
  • 【取RMB张数】 根据员工的工资计算需要多少张100元、50元......1元的钞票,可以批量累计计算。发现金工资的财务工作者的必备工具之一。 【数字转英文】 将选中区域(默认)或已使用区域存储格的金额数字转换成英文...
  • 【取RMB张数】 根据员工的工资计算需要多少张100元、50元......1元的钞票,可以批量累计计算。发现金工资的财务工作者的必备工具之一。 【数字转英文】 将选中区域(默认)或已使用区域存储格的金额数字转换成英文...

空空如也

空空如也

1 2
收藏数 23
精华内容 9
关键字:

员工评分排序