存储许多for循环的结果

时间:2019-05-01 10:39:00

标签: c arrays list loops multidimensional-array

我在python中有一个代码,现在我正努力用c编写它(以优化速度),因为我从未使用过c!

以前,我以前将结果数据存储在字典或数组列表中,但我不知道什么是合适的结构以及如何在c中将其存储在这里。

我从名为(尝试)的文件中读取数据,然后使用代码中编写的函数对其进行处理。三个for loops用于生成所需的数据,但我不知道该如何存储!

包含循环的代码

for (i=0; i<m; i++){
   igraph_edge(&graph, i, &from, &to);
   igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
   igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);
   for (j=0; j < igraph_vector_size(&v2); j++) {
     for (k=0; k < igraph_vector_size(&v1); k++) {
       printf("%li %d %f %d %f\n", i, from, VECTOR(v1)[k] ,to, VECTOR(v2)[j]);     
     } 
   }
}     

 //EDIT: concerning the different data types, at the end all elements inside the loops could have have the same type so


int n1, n2;
for (i=0; i<m; i++){
    igraph_edge(&graph, i, &from, &to);
    igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
    igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);
    for (j=0; j < igraph_vector_size(&v2); j++) {
      for (k=0; k < igraph_vector_size(&v1); k++) {
        n1 =  floor(VECTOR(v1)[k]);
        n2 =  floor(VECTOR(v2)[j]);
        printf("%li %d %d %d %d\n", i, from, n1 ,to, n2);                        
      }
    }
 }  

结果在表格上

0 1 2.000000 2 1.000000
0 1 2.000000 2 3.000000
0 1 2.000000 2 4.000000
1 2 1.000000 3 2.000000
1 2 3.000000 3 2.000000
1 2 4.000000 3 2.000000
          .
          .
          .

我不想打印此数据,而是将其存储为

data = [ [ [1, 2.000000, 2 ,1.000000], [1, 2.000000, 2, 3.000000], [1, 2.000000, 2, 4.000000] ], [  [2, 1.000000, 3, 2.000000], [2, 3.000000, 3, 2.000000], ...  ], ... ]

然后,如果我需要访问数据

  1. 对于索引0,data[0]= [ [1, 2.000000, 2 1.000000], [1, 2.000000, 2, 3.000000], [1, 2.000000, 2, 4.000000] ]

  2. data[0][2]=[1 2.000000 2 4.000000]

  3. data[0][2][3]= [4.000000] data[0][2][3]= 4.000000

就我而言,这可能吗?我将非常感谢您的帮助。

P.S:我很乐意解释不清楚的地方。

添加

这是完整的代码(如果需要)

#include <igraph/igraph.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define sigma 1

void print_vector(igraph_vector_t *v, FILE *file) {
     long int i;
     for (i=0; i < igraph_vector_size(v); i++) {
        fprintf(file, "%li \n", (long int) VECTOR(*v)[i]);
     }
     fprintf(file,"\n");
 }


float rbf(int a, int b);

float rbf(int a, int b) {
  double inverse;
  double exp(double x;);
  double x;
  double result;

  inverse = ( 1/(sigma*sigma) );
  x = (- inverse * ( (a - b)*(a - b) ) );
  result = exp(x);
  return (result); 
} 

int main(void)
{

     igraph_t graph; 
     igraph_bool_t false;
     igraph_bool_t connected1, connected2, connected3, connected4, connected5, connected6;
     int ret;
     float rhs1;
     float rhs2;
     igraph_vector_t v1, v2;
     long int i, j, k, n, m ;
     igraph_integer_t from, to;
     igraph_adjlist_t adjlist;
     FILE *file;
     file = fopen("attempt", "r");
     if(!file){
        return 1;
     }

     igraph_read_graph_edgelist(&graph, file, 
                                0, false);

     fclose(file);

     igraph_vector_init(&v1, (igraph_vcount(&graph)) );
     igraph_vector_init(&v2, (igraph_vcount(&graph)) );
     igraph_adjlist_init(&graph, &adjlist, IGRAPH_ALL);

     n = igraph_vcount(&graph);
     m = igraph_ecount(&graph);
     for (i=0; i<m; i++){
        igraph_edge(&graph, i, &from, &to);
        igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
        igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);
        for (j=0; j < igraph_vector_size(&v2); j++) {
          for (k=0; k < igraph_vector_size(&v1); k++) {
            printf("%li %d %f %d %f\n", i, from, VECTOR(v1)[k] ,to, VECTOR(v2)[j]);                        
          }
        }
     }

     //igraph_destroy(&graph);
}

并且文件尝试包含此试用数据

1 2
2 3
2 4
3 4
4 5

1 个答案:

答案 0 :(得分:2)

  

想要存储它

每个元素都需要一个结构,例如

typedef Struct Data {
  int from;
  float vfrom;
  int to;
  float vto;
} Data;

然后一个Data**

请注意,这样做不允许有data[0][2][3]= [4.000000],否则需要拥有float ***,这是不实际的,它是data[0][2].vto == 4.000000

例如替换

 for (i=0; i<m; i++){
    igraph_edge(&graph, i, &from, &to);
    igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
    igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);
    for (j=0; j < igraph_vector_size(&v2); j++) {
      for (k=0; k < igraph_vector_size(&v1); k++) {
        printf("%li %d %f %d %f\n", i, from, VECTOR(v1)[k] ,to, VECTOR(v2)[j]);                        
      }
    }
 }

作者

 Data ** all = malloc(m * sizeof(Data*));

 for (i=0; i<m; i++){
    igraph_edge(&graph, i, &from, &to);
    igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
    igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);
    all[i] = malloc(igraph_vector_size(&v2)*graph_vector_size(&v1)*sizeof(Data));

    int idx = 0;

    for (j=0; j < igraph_vector_size(&v2); j++) {
      for (k=0; k < igraph_vector_size(&v1); k++) {
        all[i][idx].from = from;
        all[i][idx].vfrom = VECTOR(v1)[k];
        all[i][idx].to = to;
        all[i][idx].vto = VECTOR(v2)[j];
        idx += 1;
      }
    }
 }

请注意,如果所有子数组中的条目数未知且相同,则可能很难使用Data**,为此,您可能需要保存该数字:

typedef Struct Data {
  int from;
  float vfrom;
  int to;
  float vto;
} Data;

typedef Datas {
   int n;
   Data * datas;
} Datas;

允许这样做:

 Datas * all = malloc(m * sizeof(Datas));

 for (i=0; i<m; i++){
    igraph_edge(&graph, i, &from, &to);
    igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
    igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);

    int jsup = igraph_vector_size(&v2);
    int ksup = igraph_vector_size(&v1);
    Data * a = malloc(jsup * ksup * sizeof(Data));

    all[i].n = jsup * ksup;
    all[i].datas = a;

    for (j=0; j < jsup; j++) {
      for (k=0; k < ksup; k++) {
        a->from = from;
        a->vfrom = VECTOR(v1)[k];
        a->to = to;
        a->vto = VECTOR(v2)[j];
        a += 1;
      }
    }
 }

然后

printf("data : [");

for (i=0; i<m; i++) {
  Data * a = all[i].datas;

  printf(" [");

  for (int j = 0; j != all[i].n; ++j)
    printf(" [%d %f %d %f]", a[j].from, a[j].vfrom, a[j].to, a[j].vto);

  printf(" ]");
}

puts(" ]");

这里是完整程序:

#include <igraph/igraph.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define sigma 1

void print_vector(igraph_vector_t *v, FILE *file) {
     long int i;
     for (i=0; i < igraph_vector_size(v); i++) {
        fprintf(file, "%li \n", (long int) VECTOR(*v)[i]);
     }
     fprintf(file,"\n");
 }


float rbf(int a, int b);

float rbf(int a, int b) {
  double inverse;
  double exp(double x;);
  double x;
  double result;

  inverse = ( 1/(sigma*sigma) );
  x = (- inverse * ( (a - b)*(a - b) ) );
  result = exp(x);
  return (result); 
} 

typedef struct Data {
  int from;
  float vfrom;
  int to;
  float vto;
} Data;

typedef struct Datas {
   int n;
   Data * datas;
} Datas;


int main(void)
{

     igraph_t graph; 
     igraph_bool_t false;
     igraph_bool_t connected1, connected2, connected3, connected4, connected5, connected6;
     int ret;
     float rhs1;
     float rhs2;
     igraph_vector_t v1, v2;
     long int i, j, k, n, m ;
     igraph_integer_t from, to;
     igraph_adjlist_t adjlist;
     FILE *file;
     file = fopen("attempt", "r");
     if(!file){
        return 1;
     }

     igraph_read_graph_edgelist(&graph, file, 
                                0, false);

     fclose(file);

     igraph_vector_init(&v1, (igraph_vcount(&graph)) );
     igraph_vector_init(&v2, (igraph_vcount(&graph)) );
     igraph_adjlist_init(&graph, &adjlist, IGRAPH_ALL);

     n = igraph_vcount(&graph);
     m = igraph_ecount(&graph);
     Datas * all = malloc(m * sizeof(Datas));

     for (i=0; i<m; i++){
       igraph_edge(&graph, i, &from, &to);
       igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
       igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);

       int jsup = igraph_vector_size(&v2);
       int ksup = igraph_vector_size(&v1);
       Data * a = malloc(jsup * ksup * sizeof(Data));

       all[i].n = jsup * ksup;
       all[i].datas = a;

       for (j=0; j < jsup; j++) {
         for (k=0; k < ksup; k++) {
           a->from = from;
           a->vfrom = VECTOR(v1)[k];
           a->to = to;
           a->vto = VECTOR(v2)[j];
           printf("%d %f %d %f\n", a->from, a->vfrom, a->to, a->vto);
           a += 1;
         }
       }
     }

     printf("data : [");

     for (i=0; i<m; i++) {
       Data * a = all[i].datas;

       printf(" [");

       for (int j = 0; j != all[i].n; ++j)
         printf(" [%d %f %d %f]", a[j].from, a[j].vfrom, a[j].to, a[j].vto);

       printf(" ]");
     }

     puts(" ]");

     /* free resources */
     igraph_destroy(&graph);
     igraph_vector_destroy(&v1);
     igraph_vector_destroy(&v2);
     igraph_adjlist_destroy(&adjlist);

     for (i=0; i<m; i++)
       free(all[i].datas);
     free(all);         

     return 0;
}

文件尝试包含

1 2
2 3
2 4
3 4
4 5

执行:

pi@raspberrypi:/tmp $ ./a.out
1 2.000000 2 1.000000
1 2.000000 2 3.000000
1 2.000000 2 4.000000
2 1.000000 3 2.000000
2 3.000000 3 2.000000
2 4.000000 3 2.000000
2 1.000000 3 4.000000
2 3.000000 3 4.000000
2 4.000000 3 4.000000
2 1.000000 4 2.000000
2 3.000000 4 2.000000
2 4.000000 4 2.000000
2 1.000000 4 3.000000
2 3.000000 4 3.000000
2 4.000000 4 3.000000
2 1.000000 4 5.000000
2 3.000000 4 5.000000
2 4.000000 4 5.000000
3 2.000000 4 2.000000
3 4.000000 4 2.000000
3 2.000000 4 3.000000
3 4.000000 4 3.000000
3 2.000000 4 5.000000
3 4.000000 4 5.000000
4 2.000000 5 4.000000
4 3.000000 5 4.000000
4 5.000000 5 4.000000
data : [ [ [1 2.000000 2 1.000000] [1 2.000000 2 3.000000] [1 2.000000 2 4.000000] ] [ [2 1.000000 3 2.000000] [2 3.000000 3 2.000000] [2 4.000000 3 2.000000] [2 1.000000 3 4.000000] [2 3.000000 3 4.000000] [2 4.000000 3 4.000000] ] [ [2 1.000000 4 2.000000] [2 3.000000 4 2.000000] [2 4.000000 4 2.000000] [2 1.000000 4 3.000000] [2 3.000000 4 3.000000] [2 4.000000 4 3.000000] [2 1.000000 4 5.000000] [2 3.000000 4 5.000000] [2 4.000000 4 5.000000] ] [ [3 2.000000 4 2.000000] [3 4.000000 4 2.000000] [3 2.000000 4 3.000000] [3 4.000000 4 3.000000] [3 2.000000 4 5.000000] [3 4.000000 4 5.000000] ] [ [4 2.000000 5 4.000000] [4 3.000000 5 4.000000] [4 5.000000 5 4.000000] ] ]