I need (for g++) a (computation time) optimized algorithm tree structure to duplicate/multiplicate a tree.
My tree will be a k-ary tree, but not necessarily filled.
The main operation is to multiplicate (up to k times) the existing tree and add the trees as subtrees to a new node. Then the leaf node level will be erased to hold the fixed-level rule.
Does anybody know of a data structure offering this?
An example for the multiplication: Suppose we have a binary tree
A
|
/ \
/ \
B C
| / \
| / \
D E F
and we want to add a new node / multiply like
R
/ \
/ \
.. ..
So the result will look like
R
/ \
/ \
/ \
/ \
/ \
A A
| |
/ \ / \
/ \ / \
B C B C
| / \ | / \
| / \ | / \
D E F D E F
I tried to organize this on a std::vector in a heap-like structure, but multiplying the tree is still kind of slow, because I have to copy each tree level by itself rather than just copying the whole tree at once.
When you add R, it is trivial to give it 2 pointers to A, rather than copying the entire subtree starting at A.
R
/ \
| |
\ /
A
|
/ \
/ \
B C
| / \
| / \
D E F
This is both very fast and very easy to code.
Now, the hitch in this comes in if you later want to update one side of the tree, but not the other. For example, perhaps you want to change the "right" F to a G. At that point you can use a copy-on-write strategy on only certain of the nodes, in this case leading to
R
/ \
/ \
A A <-- copied, left side points to B
| / \
/ \ * \
/ \ \
B C C <-- copied, left side points to E
| / \ / \
| / \ * \
D E F G
Basically, you only need to copy the path from the point of the change (F/G) up to either the root (easiest to implement) or up to the highest node that is shared (A in this example).
Maybe take a look on Androids code for the T9-dictionary. AFAIR it looks flat, but basically what they do is build a tree of letters, so that traversing the tree from top to bottom makes words. And I think they used relative offsets to jump from on node to the next (like a linked list).
So you should be able to copy the whole tree in one run.
I don't remember the exact layout thou, and i think it didn't do ugly padding as I do here, but to continue w/ your example it would look something(!) like this:
# your tree
__________
/// _ \ _
/// /// \ \ /// \
A007021B007000D000000C007014E000000F000000
\\\_/ \\\_____/
# copying it, "under" R:
__________ __________
_ /// _ \ _ /// _ \ _
/// \ /// /// \ \ /// \ /// /// \ \ /// \
R007049A007021B007000D000000C007014E000000F000000A007021B007000D000000C007014E000000F000000
\\\ \\\_/ \\\_____/ / \\\_/ \\\_____/
\\\______________________________________/
Related
I have a lot of repetitive code that needs me to use different sets of data frequently in some function or some operation. i.e as shown below (the numbers and letters are just place holders, all i need to do is string two sets of data together using x macros)
a = 1
a = 2
a = 3
a = 4
.
.
.
then
b = 1
b = 2
b = 3
.
.
.
and
c = 1
c = 2
c = 3
.
.
.
I was trying to create an X-macro that combines the following two X-macros into one
//X-macro 1
#define SET_1 \
X(a) \
X(b) \
X(c) \
//X-macro 2
#define SET_2 \
X(1) \
X(2) \
X(3) \
X(4)
Any help?
How about this approach:
#define X_abc(X,X2) \
X(a,X2) \
X(b,X2) \
X(c,X2)
#define X_1234(x,X2) \
X2(x,1) \
X2(x,2) \
X2(x,3) \
X2(x,4)
#define SET(x,y) x = y;
#define DEFINE(x,y) int x = y;
X_abc(X_1234,DEFINE)
Our input expressions are similar to this (even more complex):
( ( ?var1 <= (?var2 + 125) && ?var1 > (?var2 + 10) ) || !(?var1 == ?var3) )
Note: variables are always started by either '?' or '_'
Our desired output:
||
/ \
/ \
/ \
/ \
/ \
&& !
/ \ |
/ \ |
/ \ ==
/ \ / \
/ \ ?var1 ?var3
<= >
/ \ / \
/ \ / \
/ \ / \
?var1 + ?var1 +
/ \ / \
/ \ / \
/ \ / \
?var2 125 ?var2 10
Your helps are really appreciated.
This may not be elegant. Chiefly because I am relatively new to C++, but this little program I am putting together is stumbling here.
I don't get it. Have I misunderstood arrays? The edited code is:
int diceArray [6][3][1] = {};
...
}else if (y >= xSuccess || x >= xSuccess){
// from here...
diceArray[2][1][0] = diceArray[2][1][0] + 1;
diceArray[2][1][1] = diceArray[2][1][1] + 1;
// ...to here, diceArray[2][2][0] increases by 1. I am not referencing that part of the array at all. Or am I?
}
By using comments I tracked the culprit down to the second expression. If I comment out the first one diceArray[2][2][0] does not change.
Why is diceArray[2][1][1] = diceArray[2][1][1] + 1 causing diceArray[2][2][0] to increment?
I tried..
c = diceArray[2][1][1] + 1;
diceArray[2][1][1] = c;
..as a workaround but it was just the same. It increased diceArray[2][2][0] by one.
You are indexing out of bounds. If I declare such an array
int data [3];
Then the valid indices are
data[0]
data[1]
data[2]
The analog to this is that you declare
int diceArray [6][3][1]
^
But then try to assign to
diceArray[2][1][0]
^
diceArray[2][1][1] // This is out of range
^
Since you are assigning out of range, due to pointer arithmetic you are actually assigning to the next dimension due to striding, etc.
The variable is declared as:
int diceArray [6][3][1] = {};
This is how it looks like in memory:
+---+ -.
| | <- diceArray[0][0] \
+---+ \
| | <- diceArray[0][1] > diceArray[0]
+---+ /
| | <- diceArray[0][2] /
+---+ -'
| | <- diceArray[1][0] \
+---+ \
| | <- diceArray[1][1] > diceArray[1]
+---+ /
| | <- diceArray[1][2] /
+---+ -'
. . .
. . .
. . .
+---+ -.
| | <- diceArray[5][0] \
+---+ \
| | <- diceArray[5][1] > diceArray[5]
+---+ /
| | <- diceArray[5][2] /
+---+ -'
The innermost component of diceArray is an array of size 1.
C/C++ arrays are always indexed starting from 0 and that means the only valid index in and array of size 1 is 0.
During the compilation, a reference to diceArray[x][y][z] is converted using pointer arithmetic to offset x*3*1+y*1+z (int values) using the memory address of diceArray as base.
The code:
diceArray[2][1][1] = diceArray[2][1][1] + 1;
operates on offset 8 (=2*3*1+1*1+1) inside diceArray. The same offset is computed using diceArray[2][2][0], which is a legal access inside the array.
The modern compilers are usually able to detect this kind of errors and warn you on the compilation.
I've been trying to port this immediate mode(glBegin/glEnd) code to direct mode(VAs) for rendering a plane. Please let me know if the direct mode code will exactly work as the immediate mode code.
Note: consider a 50X50 mesh
Immediate mode code:
int once=0, a=0,b=0;
for(int j=0; j<50-1; j++)
{
once=0;
for(int i=0; i<50; i++)
{
a=i+j*(50);
b=i+(j+1)*50;
if(once)
{
glBegin(GL_TRIANGLE_STRIP);
once=1;
}
else
{
glTexCoord2f(Texture[a].x, Texture[a].y);
glVertex2f(Mesh[a].x, Mesh[a].y);
glTexCoord2f(Texture[a].x, Texture[a].y);
glVertex2f(Mesh[b].x, Mesh[b].y);
}
}
if(once)
{
glEnd();
}
}
Direct mode code:
unsigned int indexArray[50*50];
int idx=0;
for(int j=0; j<50-1; j++)
{
for(int i=0; i<50; i++)
{
a=i+j*(50);
b=i+(j+1)*50;
indexArray[idx]=a;
indexArray[idx+1]=b;
idx+=2;
}
}
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(2dPoint), Texture);
glVertexPointer(3, GL_FLOAT, sizeof(2dPoint), Mesh);
glDrawElements(GL_TRIANGLE_STRIP, (50-1)*(50-1)*2, GL_UNSIGNED_INT, indexArray);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
Note: 2dPoint is a structure for 2 floating point values holding x and y
Update
After correcting the glVertexPointer() for 2-d co-ordinates. I observed the triangulation happening the following way:
With glBegin()-glEnd():
/\ /\ /\ /\ /
/ \ / \ / \ / \ /
\ / \ / \ / \ / \ /
\ / \ / \ / \/ \ /
\/ \ \ / /\ \ /
/\ / \ \/ / \ \/
/ \ / \ /\ / \ /\
/ \ / \ / \ / \ / \
\ / \ / \ / \ / \
\ / \ / \/ \/ \
\ / \ \ /\ /\ \
\ / \ / \ / \ / \ \
\/ \ / \ / \ / \ \
/\ \ / \ / \ / \ \
/ \ \ / / \ / \ \
/ \ / / \ \/ \ \
/ \ / \ / \ /\ \ \
\ / \ / \ / \ \ \
\/ \ / \ / \ \ \
/\ / \ / \ \ \
With glDrawElements():
/\ /\ /\ /\ /
/ \ / \ / \ / \ /
\ / \ / \ / \ / \ /
\ / \ / \ / \/ \ /
--\/--------\--------\--/-------/\-------\--/
/\ / \ \/ / \ \/
/ \ / \ /\ / \ /\
/ \ / \ / \ / \ / \
------\-/-------\---/----\--/--------\--/----\
\ / \ / \/ \/ \
\ / \ \ /\ /\ \
\ / \ / \ / \ / \ \
\/ \ / \ / \ / \ \
/\ \ / \ / \ / \ \
/ \ \ / / \ / \ \
-/----\----- \-------/-\--------\/----------\-------\
/ \ / \ / \ /\ \ \
\ / \ / \ / \ \ \
\/ \ / \ / \ \ \
/\ / \ / \ \ \
Sorry for the alignment issues in the illustration. but as you can see, with the index array and glDrawElements(), the number of triangles increased. how can i modify the index array to match the winding similar to the results of glBegin()/glEnd()?
Since you only have 2d coordinates, the glVertexPointer call is wrong.
glVertexPointer(3, GL_FLOAT, sizeof(2dPoint), Mesh);
This line tell OpenGL to always read 3 floats per vertex, so if you only have 2 of them you have to change it to:
glVertexPointer(2, GL_FLOAT, sizeof(2dPoint), Mesh);
^
I have a tree model representing a k-ary tree (i.e. nodes have a list of children). The model implements the QAbstractItemModel and its QSize span(QModelIndex) method.
Given the following k-ary tree:
and
/ \
/ \
/ \
or or
/\ /\ \
/ \ / \ \
I1 I2 I3 I4 I5
My intention is to visualize the tree in a QTableView from left to right as follows:
___________
| | | Item 1
| |v|_______
| | | Item 2
| |_|_______
|^| | Item 3
| | |_______
| |v| Item 4
| | |_______
| | | Item 5
|_|_|_______
Such that each node spans over all its child nodes.
I've implemented the QAbstractItemModel::span method, but it is not taken into account by the QTableView class.
When (i.e. reacting to which signal) and how should I rebuild/redraw the QTableView?
Notes:
The model will be a read/write model. The user will have the option to rearrange the expression tree with drag&drop.
Qt Version 4.8, upgrading to 5 is not an option.
Thanks in advance.