【问题标题】:Reverse output ordering in a C structC结构中的反向输出排序
【发布时间】:2015-08-07 14:15:25
【问题描述】:

我目前正在做一个项目,但遇到了一些障碍。我已经完成了所需的代码,但是有一个额外的部分要求我以与当前相反的顺序打印输出。

例如:

21, Fred Nurk
927, Arwen Evensong

应该返回:

Arwen Evensong (927)
Fred Nurk (21)

但目前正在返回:

Fred Nurk (21)
Arwen Evensong (927)

我想知道是否有一种简单的方法可以在不更改太多代码的情况下做到这一点?抱歉,如果代码有点凌乱且难以阅读,有一些限制使这个问题写起来很烦人:

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

#define MAX_LINE_LENGTH 80
#define MAX_NUM_STUDENTS 500
#define MAX_NAME_SIZE 50

typedef struct student_s Student;

struct student_s {
    int age;
    char name[MAX_NAME_SIZE];
    Student* next;
};

Student studentPool[MAX_NUM_STUDENTS];
int firstFree = 0;


Student* newStudent(const char* name, int age) {
    Student* student = NULL;
    if (firstFree < MAX_NUM_STUDENTS) {
        student = &studentPool[firstFree];
        firstFree += 1;
        strncpy(student->name, name, MAX_NAME_SIZE);
        student->name[MAX_NAME_SIZE - 1] = '\0';
        student->age = age;
        student->next = NULL;
    }
    return student;
}


Student* readOneStudent(FILE* file)
{
    char *buffer;
    buffer = (char *)malloc(MAX_LINE_LENGTH);
    Student* student = NULL;
    char* cp = fgets(buffer, MAX_LINE_LENGTH, file);
    if (cp != NULL) {
        char* commaPos = strchr(buffer, '\040');
        int age = atoi(buffer);
        if (commaPos != NULL && commaPos > buffer) {
            *commaPos = '\0';
            student = newStudent((commaPos+1),age);

        }
    }
    return student;
}

Student* readStudents(FILE *file)
{
    Student* first = NULL;
    Student* last = NULL;
    Student* student = readOneStudent(file);
    while (student != NULL) {
        if (first == NULL) {
            first = last = student;
        }
        else {
            last->next = student;
            last = student;

        }
        student= readOneStudent(file);
    }

    return first;
}


void printOneStudent(Student student)
{

strtok(student.name, "\n");
if (student.name != '\0'){
printf("%s (%d)\n", student.name, student.age);
}
else{
    printf("%s (%d)",student.name, student.age);
}
   }


void printStudents(const Student* student)
{
    while (student != NULL) {
        printOneStudent(*student);
        student = student->next;
    }
}


int main(void)
{
    FILE* inputFile = stdin;
    if (inputFile == NULL) {
        fprintf(stderr, "File not found\n");
    }
    else {
        Student* studentList = readStudents(inputFile);
        printStudents(studentList);
    }
}

【问题讨论】:

  • 让你的 printStudents 成为一个带有尾随输出的递归函数

标签: c struct output


【解决方案1】:

或者,您可以使用递归来反转单链表:

void printStudentsRev(const Student* student)
{
    if (student != NULL) {
        printStudentsRev(student->next);
        printOneStudent(*student);
    }
}

这不适用于很长的列表,因为堆栈区域有限

【讨论】:

    【解决方案2】:

    使用双向链表而不是单链表。添加到您的结构中。

    Student* previous
    

    在整个程序中相应地更新它。当你去打印时,迭代到最后并打印直到你在前面,类似于你的打印学生功能。

    void printStudents2(const Student* student){
    //iterate to end
        while (student->next != NULL) {
              student=student->next;
        }
        while(student != NULL){
              printOneStudent(*student);
              student = student->previous;
        }
    }
    
    Student* readStudents(FILE *file)
    {
        Student* first = NULL;
        Student* last = NULL;
        Student* student = readOneStudent(file);
        while (student != NULL) {
            if (first == NULL) {
                first = last = student;
                //add these too
                student ->next = NULL;
                student->previous = NULL;
            }
            else {
                //add this line here
                student->previous = last;
                last->next = student;
                last = student;
                //and this line here
                last->next = NULL;
    
            }
            student= readOneStudent(file);
        }
    
        return first;
    }
    

    编辑:它需要比递归解决方案多 10 行,但它适用于任何长度的列表。

    【讨论】:

      【解决方案3】:

      执行此操作的最简单方法是在此处向后构造列表是代码:

      Student* readStudents(FILE *file)
      {
          Student* first = NULL;
          Student* last = NULL;
          Student* student = readOneStudent(file);
          while (student != NULL) {
              if (first == NULL) {
                  first = last = student;
                  last->next = NULL;
              }
              else {
                  student->next = first;
                  first = student;
              }
              student = readOneStudent(file);
          }
      
          return first;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-21
        • 2011-12-28
        • 2020-12-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多