【问题标题】:Sparse Matrix with linked lists带有链表的稀疏矩阵
【发布时间】:2016-10-28 22:06:26
【问题描述】:

我正在尝试使用链表在 C 中创建一个稀疏矩阵。我的教授给了file.h 结构、函数列表以及它们应该做什么,并告诉我们“使用它”。 要恢复一切,我的代码不起作用,当我尝试插入一个元素(调用 ins_elem())并在调用 soma_elem_coluna()soma_elem_linha() 时返回奇怪的数字时它停止工作。

我已将整个代码放在下面,但问题确实存在于上面指定的函数中(以及soma_const(),因为我无法在不插入元素的情况下对其进行测试)。

我使用的逻辑是创建一个矩阵,如下图所示(使用数字而不是字符) [

别介意奇怪的打字,有些词是葡萄牙语。

(C = 列,L = 行)

这是我的file.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINES 4
#define COLUM 4

typedef struct Node{
    int Val, L, C;
    struct Node *down, *right;
}Node;

typedef struct{
    Node *L[LINES], *C[COLUM];
}matriz;

void cria_matriz(matriz* m);                       // creates matrix
void ins_elem(matriz* m, int e, int l, int c);     // insert element e into lxc 
void soma_const(matriz* m, int e, int l, int c);   // add value e to existing lxc
int soma_elem_linha(matriz *m, int l);             // sums all the values in row l
int soma_elem_coluna(matriz *m, int c);            // sums all the values in column c
void imp(matriz *m);                               // prints the matrix

我的file.c

#include "file.h"

void cria_matriz(matriz* m) 
{
    int i;
    for(i=0;i<LINES;i++) //initializes headrows
    {
        m->L[i]->down = NULL;
        m->L[i]->right = NULL;
        m->L[i]->C = -1;
        m->L[i]->L = -1;
    }
    for(i=0;i<COLUM;i++) //initializes headcolumns
    {
        m->C[i]->down = NULL;
        m->C[i]->right = NULL;
        m->C[i]->C = -1;
        m->C[i]->L = -1;
    }
}

void ins_elem(matriz *m, int e, int l, int c)
{
    Node* auxLine; // move through row
    Node* auxCol; // move through column
    auxLine = &m->L[l];
    auxCol = &m->C[c];
    while(auxLine->right != NULL && auxLine->right->C < c) //find correct pos in row
    {
        auxLine = auxLine->right;
    }
    while(auxCol->down != NULL && auxCol->down->L < c) //find correct pos in column (error happens here)
    {
        auxCol = auxCol->down;
    }
    Node* novo = malloc(sizeof(Node));
    novo->Val = e;
    novo->C = c;
    novo->L = l;
    novo->down = auxCol->down;
    auxCol->down = novo;
    novo->right = auxLine->right;
    auxLine->right = novo;
}

void soma_const(matriz *m, int e, int l, int c)
{
    Node* aux = &m->C[c];
    while(aux->down != NULL && aux->L < l)
        aux = aux->down;
    aux->Val+=e;
}

int soma_elem_coluna(matriz *m, int c)
{
    int sum = 0;
    Node* aux = &m->C[c];
    if(aux->down == NULL)
        return 0;
    while(aux->down != NULL)
    {
        aux = aux->down;
        sum += aux->Val;
    }
    return sum;
}

int soma_elem_linha(matriz *m, int l)
{
    int sum = 0;
    Node* aux = &m->L[l];
    if(aux->right == NULL)
        return 0;
    while(aux->right != NULL)
    {
        aux = aux->right;
        sum += aux->Val;
    }
    return sum;
}

void imp(matriz *m)
{
    Node* aux;
    int i, j;
    for(i=0;i<LINES;i++)
    {
        aux = &m->L[i];
        for(j=0;j<COLUM;j++)
        {
            if(aux->C == j)
            {
                printf("%d ",aux->Val);
                aux = aux->right;
            }
            else
            {
                printf("0 ");
            }
        }
        printf("\n");
    }
}

我的main.c:

#include "file.h"

int main()
{
    struct matriz* M = (matriz*)malloc(sizeof(matriz));
    int i,e,c,l,result;
    char str[20];
    for(i=0;i<5;i++) // this is temporary and another issue, how I make a while that 
    {                 // only stops when user (a bot actually) presses enter?
        scanf(" %s",str);

        if(!strcmp(str,"cria_matriz"))
        {
            cria_matriz(M);
        }
        else if(!strcmp(str,"ins_elem"))
        {
            scanf("%d %d %d",&e,&l,&c);
            ins_elem(M,e,l,c);
        }
        else if(!strcmp(str,"soma_const"))
        {
            scanf("%d %d %d",&e,&l,&c);
            soma_const(M,e,l,c);
        }
        else if(!strcmp(str,"soma_elem_linha"))
        {
            scanf("%d",&l);
            result = soma_elem_linha(M,l);
            printf("%d\n",result);
        }
        else if(!strcmp(str,"soma_elem_coluna"))
        {
            scanf("%d",&c);
            result = soma_elem_coluna(M,c);
            printf("%d\n",result);
        }
        else if(!strcmp(str,"imp"))
        {
            imp(M);
        }
    }
    return 0;
}

【问题讨论】:

  • 没有人吗?已经3个小时了,还是修不出来……
  • 目前还不清楚您的代码出了什么问题。您应该学习如何使用调试器。您的学习速度将提高 10 倍。

标签: c list matrix linked-list sparse-matrix


【解决方案1】:

您的文件编译时没有警告,因为代码中有很多指针和其他问题。我已经处理了您的代码以清理警告,但我无法测试逻辑 - 您必须这样做:

file.c

#include "file.h"

void cria_matriz(matriz *m) 
{
    for (int i = 0; i < LINES; i++) // initializes headrows
    {
        m->L[i] = malloc(sizeof(Node));
        m->L[i]->down = NULL;
        m->L[i]->right = NULL;
        m->L[i]->C = -1;
        m->L[i]->L = -1;
        m->L[i]->Val = 0;
    }

    for (int i = 0; i < COLUM; i++) // initializes headcolumns
    {
        m->C[i] = malloc(sizeof(Node));
        m->C[i]->down = NULL;
        m->C[i]->right = NULL;
        m->C[i]->C = -1;
        m->C[i]->L = -1;
        m->C[i]->Val = 0;
    }
}

void ins_elem(matriz *m, int e, int l, int c)
{
    Node *auxLine = m->L[l]; // move through row
    Node *auxCol = m->C[c]; // move through column

    while (auxLine->right != NULL && auxLine->right->C < c) // find correct pos in row
    {
        auxLine = auxLine->right;
    }

    while (auxCol->down != NULL && auxCol->down->L < c) // find correct pos in column (error happens here)
    {
        auxCol = auxCol->down;
    }

    Node *novo = malloc(sizeof(*novo));
    novo->Val = e;
    novo->C = c;
    novo->L = l;
    novo->down = auxCol->down;

    auxCol->down = novo;
    novo->right = auxLine->right;
    auxLine->right = novo;
}

void soma_const(matriz *m, int e, int l, int c)
{
    Node *aux = m->C[c];

    while (aux->down != NULL && aux->L < l)
    {
        aux = aux->down;
    }

    aux->Val += e;
}

int soma_elem_coluna(matriz *m, int c)
{
    Node *aux = m->C[c];

    if (aux->down == NULL) {
        return 0;
    }

    int sum = 0;

    while (aux->down != NULL)
    {
        aux = aux->down;
        sum += aux->Val;
    }

    return sum;
}

int soma_elem_linha(matriz *m, int l)
{
    Node *aux = m->L[l];

    if (aux->right == NULL) {
        return 0;
    }

    int sum = 0;

    while (aux->right != NULL)
    {
        aux = aux->right;
        sum += aux->Val;
    }

    return sum;
}

void imp(matriz *m)
{
    for (int i = 0; i < LINES; i++)
    {
        Node *aux = m->L[i];

        for (int j = 0; j < COLUM; j++)
        {
            if (aux->C == j)
            {
                printf("%d ", aux->Val);
                aux = aux->right;
            }
            else
            {
                printf("0 ");
            }
        }

        printf("\n");
    }
}

ma​​in.c

#include "file.h"

int main()
{
    matriz *M = malloc(sizeof(*M));
    int e, c, l;
    char str[32];

    for (int i = 0; i < 5; i++) // this is temporary and another issue, how I make a while that 
    {               // only stops when user (a bot actually) presses enter?
        (void) scanf(" %s", str);

        if (strcmp(str, "cria_matriz") == 0)
        {
            cria_matriz(M);
        }
        else if (strcmp(str, "ins_elem") == 0)
        {   
            scanf("%d %d %d", &e, &l, &c);
            ins_elem(M, e, l, c);
        }
        else if (strcmp(str, "soma_const") == 0)
        {
            (void) scanf("%d %d %d", &e, &l, &c);
            soma_const(M, e, l, c);
        }
        else if (strcmp(str, "soma_elem_linha") == 0)
        {
            (void) scanf("%d", &l);
            int result = soma_elem_linha(M, l);
            printf("%d\n", result);
        }
        else if (strcmp(str, "soma_elem_coluna") == 0)
        {
            scanf("%d", &c);
            int result = soma_elem_coluna(M, c);
            printf("%d\n", result);
        }
        else if (strcmp(str,"imp") == 0)
        {
            imp(M);
        }
    }

    free(M);

    return 0;
}

最大的问题是你一直在指向已经是指针的东西。此外,您初始化了尚未实际分配的数据。您没有初始化随后添加的某些数据。最后,strcmp() 不是布尔值,不要把它当做一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-19
    • 2012-09-23
    • 1970-01-01
    • 2012-01-10
    • 2017-05-11
    相关资源
    最近更新 更多