首页 > 解决方案 > 如何按升序从未排序的列表写入文件?

问题描述

我的数据结构类有问题。我的任务是生成 30 个随机数,然后按生成顺序将它们打印到列表中。之后,我必须从列表中删除可被 3 整除的数字和包含数字“3”的数字。最后,我需要按升序将该列表打印到文件中,但我们不允许在打印到文件之前对列表进行排序。

我的代码工作正常,但我找不到按升序将数字打印到文件的解决方案。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<stdbool.h>
#define BUFFER_LENGTH 256

typedef struct lista* Poz;
typedef struct lista {
    int br;
    Poz next;
}lista;

bool containsDigit(int, int);
int PrintList(Poz);
int PrintRandom(int, int);
Poz StvoriCvor();
int PrintToFile(Poz);

bool containsDigit(int number, int digit) {
    while (number != 0) {
        int curr_digit = number % 10;
        if (curr_digit == digit)
            return true;
        number /= 10;
    }
    return false ;
}

int PrintToFile(Poz P) {
    int digit = 3;
    if (P == NULL) return -1;
    Poz temp;
    temp = StvoriCvor();
    if (temp == NULL) return -1;
    char* fileName = NULL;
    FILE* fp;

    fileName = (char*)malloc(sizeof(char) * BUFFER_LENGTH);
    if (fileName == NULL) return -1;

    printf("Unesite ime datoteke:\n");
    scanf("%s", fileName);

    fp = fopen(fileName, "w+");
    if (fp == NULL) return -1;
    while (P != NULL) {
        if (P->br % 3 == 0 || containsDigit(P->br, digit) == true) {
            P = P->next;
        }
        else {
            fprintf(fp, "%d\n", (int)P->br);
            P = P->next;
        }
        
    }
    fclose(fp);
    return 0;
}

int PrintRandom(int min, int max) {
    int num = (rand() % (max - min + 1) + min);
    return num;
}

int PrintList(Poz P) {
    P = P->next;
    if (P == NULL) {
        printf("Lista je prazna.\n");
    }
    else {
        printf("Sljedeci brojevi su u listi.\n");
        while (P != NULL) {
            printf("%d ", P->br);
            P = P->next;
        }
    }
    return 0;
}

Poz StvoriCvor() {
    Poz Q = NULL;
    Q = (Poz)malloc(sizeof(lista));
    if (Q == NULL) {
        printf("Greska u funkciji StvoriCvor.\n");
    }
    Q->next = NULL;
    return Q;
}

int main() {
    Poz Sort = NULL;
    lista head;
    head.next = NULL;
    Poz Q = NULL;
    Poz temp = NULL;
    int min = 0, max = 100, count = 30;
    srand(time(0));
    int pr = 100, x = 0;
    char* choice;
    choice = (char*)malloc(sizeof(char));
    if (choice == NULL) {
        printf("Greska.\n");
    }

    for (int i = 0; i < count; i++) {
        Q = StvoriCvor();
        if (Q == NULL) {
            printf("Greska u funkciji StvoriCvor.\n");
        }
        else {
            Q->br = PrintRandom(min, max);
            Q->next = head.next;
            head.next = Q;
        }
    }
    PrintList(&head);
    PrintToFile(head.next);

    return 0;
}

标签: clistsorting

解决方案


列表实际上并不是一个尝试按顺序迭代的好数据结构。如果要进行中序遍历,则需要不同的数据结构,因此似乎要做的就是使用一个。使用辅助数据结构(或者,在这种情况下,使用辅助数据结构作为主要数据结构!)通常是一个好主意。也许这违反了“不排序列表”指令的精神,但这样的指令有点奇怪,因为对列表进行排序是一件愚蠢的事情。SO 不是编码服务,但这种玩具写起来很有趣,值得每隔一段时间做一次(或者这样做可能是纯粹的拖延!),所以没有广泛的测试或任何真正的审查,这是一个开始:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

struct list_element {
    int val;
    struct list_element *next;
};

struct tree_element {
    int val;
    struct tree_element *child[2];
};

static void *
xmalloc(size_t s)
{
    void *rv = malloc(s);
    if( rv == NULL ){
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    return rv;
}

static struct list_element *
push_list(struct list_element *h, int v)
{
    struct list_element *new = xmalloc(sizeof *new);
    new->val = v;
    new->next = h;
    return new;
}

static void
insert_tree(struct tree_element **t, int v)
{
    char buf[128];
    if( (v % 3 == 0) || snprintf(buf, sizeof buf, "%d", v) > 127 ||
            strchr(buf, '3') != NULL ){
        return;
    }
    if( *t == NULL ){
        struct tree_element *new = *t = xmalloc(sizeof **t);
        new->val = v;
        new->child[0] = NULL;
        new->child[1] = NULL;
    } else {
        struct tree_element *n = *t;
        insert_tree(n->child + ( n->val > v ? 0 : 1 ), v);
    }
}

static void
print_tree_node(const struct tree_element *t, FILE *out)
{
    fprintf(out, "%d ", t->val);
}

static void
in_order(struct tree_element *r, void (*f)(const struct tree_element *, FILE *),
    FILE *out)
{
    if( r ){
        in_order(r->child[0], f, out);
        f(r, out);
        in_order(r->child[1], f, out);
    }
}

int
main(int argc, char **argv)
{
    struct list_element *head = NULL;
    struct tree_element *root = NULL;
    int count = argc > 1 ? strtoul(argv[1], NULL, 10) : 10;
    int mod = argc > 2 ? strtoul(argv[2], NULL, 10) : INT_MAX;
    srand(time(NULL));
    for( int i = 0; i < count; i += 1 ){
        int r = rand() % mod;
        head = push_list(head, r);
        insert_tree(&root, r);
    }

    puts("Original list:");
    for( ; head; head = head->next ){
        printf("%d ", head->val);
    }
    putchar('\n');
    puts("Filtered and sorted:");
    in_order(root, print_tree_node, stdout);
    putchar('\n');

    return 0;
}

推荐阅读