如何迭代地获取特定的结构元素并将它们存储到C中的2D数组中?

如何迭代地获取特定的结构元素并将它们存储到C中的2D数组中?,c,string,struct,dijkstra,adjacency-matrix,C,String,Struct,Dijkstra,Adjacency Matrix,我有一个2D字符串数组,如下所示: char str[12][100] = { "a = 2.b, 1.d", "b = 2.a, 1.e, 2.c", "c = 2.b, 1.f", "d = 1.a, 1.g", "e = 1.h, 1.b", "f = 1.i, 1.c", "g = 1.j, 1.d", "h = 1.k, 1.e", "i = 1.l, 1.f", "j = 1.g, 2.k", "

我有一个2D字符串数组,如下所示:

char str[12][100] = {
    "a = 2.b, 1.d",
    "b = 2.a, 1.e, 2.c",
    "c = 2.b, 1.f",
    "d = 1.a, 1.g",
    "e = 1.h, 1.b",
    "f = 1.i, 1.c",
    "g = 1.j, 1.d",
    "h = 1.k, 1.e",
    "i = 1.l, 1.f",
    "j = 1.g, 2.k",
    "k = 2.j, 1.h, 2.l",
    "l = 2.k, 1.i"
};
struct stopPoints {
    int  weights[10];
    char connectingPoints[10];
};
store[0].connectingPoints[0] = 'a';
store[0].connectingPoints[1] = 'b';
store[0].connectingPoints[2] = 'd';
typedef struct Connection {
    char  conn_target; 
    int   conn_weight;
} Connection;

typedef struct StopPoints {
    Connection sp_connections[MAX_CONN];
} StopPoints;
这些字符串表示地图布局,其中点“a”连接到点“b”和“d”,并且连接到点“a”的点之间存在关联的距离(或权重)。以下是从所有这些字符串转换时的布局:

    a--(2)--b--(2)--c
    |       |       |
   (1)     (1)     (1)
    |       |       |
    d       e       f
    |       |       |
   (1)     (1)     (1)
    |       |       |
    g       h       i
    |       |       |
   (1)     (1)     (1)
    |       |       |
    j--(2)--k--(2)--l
我有一个结构,像这样:

char str[12][100] = {
    "a = 2.b, 1.d",
    "b = 2.a, 1.e, 2.c",
    "c = 2.b, 1.f",
    "d = 1.a, 1.g",
    "e = 1.h, 1.b",
    "f = 1.i, 1.c",
    "g = 1.j, 1.d",
    "h = 1.k, 1.e",
    "i = 1.l, 1.f",
    "j = 1.g, 2.k",
    "k = 2.j, 1.h, 2.l",
    "l = 2.k, 1.i"
};
struct stopPoints {
    int  weights[10];
    char connectingPoints[10];
};
store[0].connectingPoints[0] = 'a';
store[0].connectingPoints[1] = 'b';
store[0].connectingPoints[2] = 'd';
typedef struct Connection {
    char  conn_target; 
    int   conn_weight;
} Connection;

typedef struct StopPoints {
    Connection sp_connections[MAX_CONN];
} StopPoints;
我已经成功地获取了每个字符串,并将每个字母和数字放入它自己的结构中。我这样做是通过创建一个结构数组:
struct stopPoints store[26]“a=2.b,1.d”
,我将字母“a”“b”和“d”分别放入
存储区[0]、连接点[0]、存储区[0]、连接点[1]和存储区[0]。连接点[2]、
。所以像这样:

char str[12][100] = {
    "a = 2.b, 1.d",
    "b = 2.a, 1.e, 2.c",
    "c = 2.b, 1.f",
    "d = 1.a, 1.g",
    "e = 1.h, 1.b",
    "f = 1.i, 1.c",
    "g = 1.j, 1.d",
    "h = 1.k, 1.e",
    "i = 1.l, 1.f",
    "j = 1.g, 2.k",
    "k = 2.j, 1.h, 2.l",
    "l = 2.k, 1.i"
};
struct stopPoints {
    int  weights[10];
    char connectingPoints[10];
};
store[0].connectingPoints[0] = 'a';
store[0].connectingPoints[1] = 'b';
store[0].connectingPoints[2] = 'd';
typedef struct Connection {
    char  conn_target; 
    int   conn_weight;
} Connection;

typedef struct StopPoints {
    Connection sp_connections[MAX_CONN];
} StopPoints;
我还将这两个数字放入结构的“weights”元素中,如下所示:

store[0].weights[0] = 2;
store[0].weights[1] = 1;
我已经对所有12个字符串进行了测试,一切都准备就绪

现在,我想用这些字符串创建一个邻接矩阵。以下是邻接矩阵的外观:

0 2 0 1 0 0 0 0 0 0 0 0                                        
2 0 2 0 1 0 0 0 0 0 0 0                                        
0 2 0 0 0 1 0 0 0 0 0 0                                        
1 0 0 0 0 0 1 0 0 0 0 0                                        
0 1 0 0 0 0 0 1 0 0 0 0                                        
0 0 1 0 0 0 0 0 1 0 0 0                                        
0 0 0 1 0 0 0 0 0 1 0 0                                        
0 0 0 0 1 0 0 0 0 0 1 0                                        
0 0 0 0 0 1 0 0 0 0 0 1                                        
0 0 0 0 0 0 1 0 0 0 2 0                                        
0 0 0 0 0 0 0 1 0 2 0 2                                        
0 0 0 0 0 0 0 0 1 0 2 0
为了进一步解释,第一行[0](表示点“a”)在[0][1]索引中包含2(表示到点“b”的距离),在[0][3]索引中包含1(表示到点“d”的距离)

因此,第二行[1]在[1][0]和[1][2]索引中包含a 2,因为点b连接到点a,点c和索引[1][5]包含a 1,因为点b也连接到点e。如您所见,每一行和每一列实际上按顺序(0=a、1=b、2=c等)表示字母a-l

我已经用所有0初始化并填充了一个12x12阵列。我似乎无法正确地将权重值填充到相应的索引中。以下是我的许多失败方法之一:

int row2, col2, ugh=1;        
for (row2 = 0; row2 < 12; row2++){
    for (col2 = 0; col2 < 12; col2++){
        while(store[row2].connectingPoints[ugh] != NULL){
            adjmatrix[row2][col2] = store[row2].weights[col2];
            ugh++;
        }
}

我只是不知道如何迭代地完成这个任务。任何帮助都将不胜感激。

char[][]
转换到
adjmatrix
可以通过一些字符串解析来完成,如下代码所示

int adjmatrix[26][26] = {0}; //assuming 26 possible points (from question "struct stopPoints store[26]")

int i,j,k = 0;
int n = 12;

for (i = 0; i < n; ++i) {
    int l = strlen(str[i]);
    for (j = 0; j < l; ++j) {
        if (str[i][j] == '.') {
            adjmatrix[str[i][0] - 'a'][str[i][j+1] - 'a'] = getWeight(str[i], j);
            // (char) - 'a', gives an integer value for the small case alphabets (a->1, b->2, c->3 ...)
        }
    }
}
如果您确实需要使用该结构,那么您可以通过使每个商店的
权重数
等于
连接点数
来简化该结构。i、 例如,如果您正在添加
存储[0]。连接点[0]=“a”设置权重

store[0].weights[0] = 0;  // weight of point a to point a
store[0].weights[1] = 2;  // weight of point a to point b
store[0].weights[2] = 1;  // weight of point a to point d
另一个例子是:
“c=2.b,1.f”,
(不确定代码中连接点的顺序是什么,但请注意基于索引的点和权重的一对一映射)

如果您知道没有自循环,可以避免将它们存储在
连接点
中,并进一步向
权重
添加相应的条目

在这种情况下,您可以使用如下循环构建
adjmatrix

struct stopPoints store[26];

for (i = 0; i < n; ++i) {
    int l = strlen(store[i].connectingPoints);
    for (j = 0; j < l; ++j) {
        adjmatrix[str[i][0] - 'a'][store[i].connectingPoints[j] - 'a'] = store[i].weights[j];
    }
}
struct stopPoints存储[26];
对于(i=0;i
字符到整数的转换

您可以找到ASCII表的副本。你应该把这个页面标记为书签,因为如果你花很多时间编程,你会相当多地引用它(一年两次,比如说,30多年)

关于ASCII码(它是Latin1、Unicode等的子集),需要知道的重要一点是,数字、大写字母和小写字母按升序排列在三个连续的组中

也就是说,“0”的代码比“1”的代码少一个,以此类推,直到“9”。“A”…“Z”和“A”…“Z”也是如此

因此,您可以通过简单的减法将字符值转换为索引值:

int ch0 = 'a' - 'a';  // == 0
int ch1 = 'b' - 'a';  // == 1
int ch4 = 'e' - 'a';  // == 4
如果您有一个(小写,ASCII)字符值,并从中减去'a',您将得到一个范围为0..25的整数值

这意味着您可以使用该公式计算邻接矩阵的两个索引值:

        //a=2b, 1d;
        adjmatrix[0][0] = 0; //point a
        adjmatrix[0][1] = store[0].weights[0];
        adjmatrix[0][3] = store[0].weights[1];

        //b=2a, 2c, 1e;
        adjmatrix[1][0] = store[1].weights[0];
        adjmatrix[1][1] = 0; //point b
        adjmatrix[1][2] = store[1].weights[1];
        adjmatrix[1][4] = store[1].weights[2];
#define MAX_CONN 10
#define NUM_STORES 12
#define STORE_INDEX(ch) ((ch) - 'a')
#define FIRST_STORE 'a'
#define END_STORES (FIRST_STORE + NUM_STORES)
#define MAX_WEIGHT 100

// NOTE: I'm ignoring return type, and adjmatrix's 
// lifetime, in favor of just putting this code all 
// in one place. You'll have to figure out the rest.

void build_adj() {

    struct stopPoints store[NUM_STORES]; // Values?
    int adjmatrix[NUM_STORES][NUM_STORES] = {0};

    for (st = FIRST_STORE; st < END_STORES; ++st) {
        int row = STORE_INDEX(st);

        // Set default weights: MAX_WEIGHT or 0 (for self)

        for (i = 0; i < NUM_STORES; ++i) {
                adjmatrix[row][i] = MAX_WEIGHT;
        }

        adjmatrix[row][row] = 0;

        // Install parsed weights for this row

        for (iconn = 0; iconn < MAX_CONN; ++iconn) {

            // NB: setting connectingPoints[x] to '\0' invalidates connection.
            char st2 = store[row].connectingPoints[iconn];

            if (st2 != '\0') {
                adjmatrix[row][STORE_INDEX(st2)] = store[row].weights[iconn];

                // FIXME: Maybe set reflexive weight? a->b, b->a?
           }                                        
        }
    }
}
然后你有:

StopPoints store[MAX_STORES];

// most code stays the same

    st2 = store[row].sp_connections[iconn].conn_target;

// ...

    adjmatrix[row][STORE_INDEX(st2)] = store[row].sp_connections[iconn].conn_weight;
其优点是概念性的:连接目标和权重捆绑在同一个结构中。它使这更容易思考,也更容易转换为使用指针;-)


另一方面,由于结构填充,它将占用更多内存。但是我认为你现在不关心这个。

Detail:
char str[12][100]
不是一个字符串的2D数组。它可以称为字符串的一维数组或字符的二维数组谢谢你的澄清,这总是让我困惑。谢谢你的输入!所以我确实需要使用structs,所以我不能更改它。不幸的是,它在我的项目的不同部分发挥作用。我试着像你展示的那样构建adjmatrix,但它仍然不能产生正确的输出。我想这是因为我的权重和坐标点的数量不一样。我在改变这一点上遇到了一些困难,但有办法解决吗?我想保持我的权重从索引0开始,实际上,我可以改变它。我现在有了它,我的重量和连接点都排成一行。因此,我的存储[0]。权重[0]现在对于所有这些值都是0。但是它仍然产生了错误的输出…@missmouse314对答案进行了一些编辑。我想现在更清楚了。仅为自循环边添加权重[i]=0。例如,如果
store='c'
c.connectingPoint='c'
。如果您认为数据中没有自循环,那么首先可以避免将它们添加到
连接点中。对不起,这就是我的意思。对于自循环边,我将其权重设置为0。但它仍然无法使用您使用结构提供的代码生成正确的输出。我理解逻辑,但在应该是1或2的地方,我仍然得到了0