C CSV GLOB排序优化

标签 c csv glib

我最近在 Sevone 接受采访时被问到了一个问题,但我从未得到关于我表现如何的答复。我只有 2 个小时来完成挑战,而且无法按性别排序。这是我的开始,下面是我的解决方案

// Sevone Programming Challenge!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

//! This is the sex of a human.
typedef enum { MALE, FEMALE } Gender;

//! This is a human person.
typedef struct Person {
    //! The given name.
    char* firstName;
    //! The family name.
    char* lastName;
    //! The age, in calendar years.
    int age;
    //! The sex (see above).
    Gender gender;
} Person;

/** This is the bonus function.
  **/
void bonusFunction();

/** This is the core of the program.
  **/
int main( int argc, char** argv ) {

    // INSTRUCTIONS:
    //    Please refer to: http://developer.gnome.org/glib/2.30/glib-Double-ended-Queues.html 
    // 1. Open "people.csv".
    // 2. Read in the list of people (format is "firstName lastName,age,{male|female}").
    // 3. Create a "Person" for each one read.
    // 4. Insert each "Person" into a GLib GQueue (this is a "double-ended queue", but think of it like a list).
    // 5. Sort the list (by using "g_queue_sort") by:
    //       1. Gender
    //       2. Last name
    // 6. Print out the list (by using "g_queue_foreach").  The format should be:
    //       (male/female) Last name, First name (age)
    // 7. Free up all memory (we're gonna valgrind this afterward).


// Ready for the bonus?
    bonusFunction();

    // KTHXBYE
    return( 0 );
}

/** This is the bonus function.
  **/
void bonusFunction() {
    //! This is the bonus array!
    int arrayOfInts[] = { 1, 1, 2, 3, 5, 8, 13, 21, 34 };


    // BONUS!
    // 1. Loop through the bonus array and print it without using square brackets ("[" and "]").


    // All done.
    return;
}

这是我的解决方案,请告诉我如何按性别排序或任何其他优化。

// Programming Challenge!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

//! This is the sex of a human.
typedef enum { MALE, FEMALE } Gender;

//! This is a human person.
typedef struct Person {
    //! The given name.
    char* firstName;
    //! The family name.
    char* lastName;
    //! The age, in calendar years.
    int age;
    //! The sex (see above).
    Gender gender;
} Person;

/** This is the bonus function.
  **/
void bonusFunction();

gint sort_lastName(gconstpointer a, gconstpointer b, gpointer data) {
    return strcmp( ((Person*)a)->lastName, ((Person*)b)->lastName );
}
void prt(gpointer per) {
 printf("%s, %s %d  \n ", ((Person*)per)->lastName, ((Person*)per)->firstName,((Person*)per)->age);
}

/** This is the core of the program.
  **/
int main( int argc, char** argv ) {
    puts("Starting SevOne Test\n");
    // INSTRUCTIONS:
    //    Please refer to: http://developer.gnome.org/glib/2.30/glib-Double-ended-Queues.html 
    // 1. Open "people.csv".
    // 2. Read in the list of people (format is "firstName lastName,age,{male|female}").
    // 3. Create a "Person" for each one read.
    // 4. Insert each "Person" into a GLib GQueue (this is a "double-ended queue", but think of it like a list).
    // 5. Sort the list (by using "g_queue_sort") by:
    //       1. Gender
    //       2. Last name
    // 6. Print out the list (by using "g_queue_foreach").  The format should be:
    //       (male/female) Last name, First name (age)
    // 7. Free up all memory (we're gonna valgrind this afterward).


    char buffer[100];
    int counter=0;
    char * token;
    GQueue* q = g_queue_new();

    FILE *fp;
    fp=fopen("people.csv", "r");

    if( fp == NULL )
    {
        puts("Failed to open file");
        return 0;
    }



    while(fgets(buffer, sizeof(buffer), fp) != NULL)
    {
        Person *ptr_one;
        ptr_one = (Person *) malloc (sizeof(Person));

        // Get first name
        token = strtok(buffer," ");
        ptr_one->firstName=(char *)malloc(sizeof(char)*sizeof(token));
        strcpy(ptr_one->firstName,token);

        // Get last name
        token = strtok(NULL,",");
        ptr_one->lastName=(char *)malloc(sizeof(char)*sizeof(token));
        strcpy(ptr_one->lastName,token);

        // Get age
        token = strtok(NULL, ",");
        ptr_one->age=(int *)malloc(sizeof(int));
        sscanf (token, "%d", &ptr_one->age);

        // Get gender
        token = strtok(NULL,",\n");


        g_queue_push_tail(q, ptr_one);

    }

    // Sort list by last name
    g_queue_sort(q, (GCompareDataFunc)sort_lastName, NULL);

    // print the list
    g_queue_foreach(q, (GFunc)prt, NULL);
    if( fclose(fp) != 0 )
    {
        puts("Failed to close file."); /* prints !!!Hello World!!! */
        return 0;
    }
    g_queue_free(q);




// Ready for the bonus?
    bonusFunction();

    // KTHXBYE
    return( 0 );
}

/** This is the bonus function.
  **/
void bonusFunction() {
    //! This is the bonus array!
    int arrayOfInts[] = { 1, 1, 2, 3, 5, 8, 13, 21, 34 };


    // BONUS!
    // 1. Loop through the bonus array and print it without using square brackets ("[" and "]").


    // All done.
    return;
}

以及下面的 CSV

Brad Fawcett,24,male
Steve Settlemyre,29,male
Dave Hegenbarth,44,male
Cathy Colapiertro,41,female
Steve Mahoney,23,male
Dave Mulford,26,male
Doug Manley,24,male
Steve Carrington,24,male
Lauren Jordan,31,female
Tanya Bakalov,26,female

最佳答案

首先你需要正确解析性别:

    // Get gendor
    token = strtok(NULL,",\n");
    if(strcasecmp(token, "female") == 0)
        ptr_one->gender = FEMALE;
    else
        ptr_one->gender = MALE;

然后使用适当的比较函数:

gint sort_gender(gconstpointer a, gconstpointer b, gpointer data) {
    return ((Person*)a)->gender - ((Person*)b)->gender;
}

还有奖励功能:

void bonusFunction() {
    //! This is the bonus array!
    int arrayOfInts[] = { 1, 1, 2, 3, 5, 8, 13, 21, 34 };

    // BONUS!
    // 1. Loop through the bonus array and print it without using square brackets ("[" and "]").
    int i;
    int *n = arrayOfInts;
    for(i = 0; i < sizeof(arrayOfInts)/sizeof(int); i++)
        printf("%d\n", *n++);

    return;
}

关于C CSV GLOB排序优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15376025/

相关文章:

c - 简单的 C 数据类型

c - GLib 哈希表 - 指针

c - 如何将指数格式转换为 c 中的十进制格式

C 中的编译器错误 - ')' 标记之前应为 '!'。

r - 如何在 R 中读取具有不同列数的 CSV 文件

php - 将 CSV 值插入数据库时​​,列计数与第 1 行错误的值计数不匹配

c - 使用 glib 进行垃圾回收时内存泄漏

c - 仅在安装了应用程序时才生成进程 (c)

c - 打印字符数组

sql - Redshift SQL - 反向 Listagg 函数