So I have a 2D array of strings, like this:
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"
};
These strings represent a map layout, where point "a" is connected to point "b" and "d" and there is an associated distance (or weight) between the points that are connected to point "a". Here is what the layout looks like when converted from all those strings:
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
And I have a struct, like this:
struct stopPoints {
int weights[10];
char connectingPoints[10];
};
I've successfully taken each string, and put each letter and number into its own struct. I did that by creating an array of structs like this: struct stopPoints store[26];
and then i proceeded to fill each struct iteratively by adding the appropriate element of each string. For example, for my first string "a = 2.b, 1.d"
, I put the letters "a" "b" and "d" into store[0].connectingPoints[0], store[0].connectingPoints[1], and store[0].connectingPoints[2],
respectively. So like this:
store[0].connectingPoints[0] = 'a';
store[0].connectingPoints[1] = 'b';
store[0].connectingPoints[2] = 'd';
I also put in the two numbers into the "weights" element of the struct, like this:
store[0].weights[0] = 2;
store[0].weights[1] = 1;
I've tested this out for all 12 strings and everything is in place.
Now, I want to create an adjacency matrix out of these strings that I have. Here is what the adjacency matrix should look like:
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
To explain a bit more, the first row [0] (represents point "a") contains 2 in the [0][1] index (representing the distance to point "b") and contains 1 in the [0][3] index (representing the distance to point "d").
As such, the second row [1] contains a 2 in the [1][0] and [1][2] index because point b is connected to point a and point c and index [1][5] contains a 1 because point b is also connected to point e. As you can see, each row and column actually represent the letters a-l in order (0=a, 1=b, 2=c, etc).
I've already initialized and populated a 12x12 array with all 0's. I just can't seem to properly populate my weight values to the corresponding index. Here is one of my many failed approaches:
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++;
}
}
}
Here is how you would hardcode the first two strings into the adjacency matrix:
//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];
I just don't know how I can do this iteratively. Any help would be much appreciated.
Converting from the char[][]
to adjmatrix
can be done with some string parsing as done in the code below.
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 ...)
}
}
}
getWeight()
int getWeight(char s[], int j) {
// returns the integer on left of '.' from the string
int w = 0,i = 0;
int m = 1;
for (i = j-1; s[i] >= '0' && s[i] <= '9'; --i) {
w += (s[i] - '0')*m;
m *= 10;
}
return w;
}
If you really need to use the struct then you can probably make it easier by making the number of weights
equal to the number of connectingPoints
for each store. i.e., if you are adding store[0].connectingPoints[0] = 'a';
let the weights be
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
Another e.g.: "c = 2.b, 1.f",
(Not sure what the order of connectingPoints
in your code is, but notice the one to one mapping of points and weights based on index)
store[2].connectingPoints[0] = 'b';
store[2].connectingPoints[1] = 'c';
store[2].connectingPoints[2] = 'f';
store[2].weights[0] = 2;
store[2].weights[1] = 0;
store[2].weights[2] = 1;
If you know that there are no self-loops, you can avoid storing them in connectedPoints
and further adding a respective entry to weights
.
In that case, you can build the adjmatrix
using a loop like this
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];
}
}