relation relative merge

This commit is contained in:
vrd
2022-12-28 14:19:44 +02:00
parent cc9b0ccc21
commit b3a2787fcd
6 changed files with 203 additions and 170 deletions
+95 -80
View File
@@ -38,33 +38,28 @@ Tree Tree::operator+ (const Tree& other)//
result.people.push(other.people[i]);
}
result.relatives.resize(result.numPeople);
result.relations.resize(result.numPeople);
result.relatives = relatives;
result.relations = relations;
for (unsigned i=0; i < other.numPeople; ++i) //Adds the relatives from the II tree
{
if (newId[i] >= numPeople) //If the member is found in the II tree but not in the I
{
result.relatives.push(other.relatives[i]);
result.relations.push(other.relations[i]);
}
else //If he's found in both
{
for (unsigned j = 0; j < other.people[i].numRel_; ++j) //Adds the number of relatives from the II to the number in the I
{
if(newId[other.relatives[i][j]] > numPeople)
if(newId[other.relations[i][j].id] > numPeople)
++result.people[newId[i]].numRel_;
}
result.relatives[newId[i]].resize(result.people[newId[i]].numRel_);
result.relations[newId[i]].resize(result.people[newId[i]].numRel_);
result.relatives[newId[i]] = relatives[newId[i]];
result.relations[newId[i]] = relations[newId[i]];
result.relatives[newId[i]] += other.relatives[i]; //The relatives from the II tree
result.relations[newId[i]] += other.relations[i];
result.relations[newId[i]] += other.relations[i]; //The relatives from the II tree
}
}
@@ -98,30 +93,28 @@ Tree& Tree::operator+=(const Tree& other)
people.push(other.people[i]);
}
relatives.resize(idCounter);
relations.resize(idCounter);
for (unsigned i = 0; i < other.numPeople; ++i) //Merges the relative data
{
if (newId[i] >= numPeople)
{
relatives.push(other.relatives[i]);
for (unsigned j = 0; j < other.people[i].numRel_; ++j)
relatives[newId[i]][j] = newId[ relatives[newId[i]][j] ];
relations.push(other.relations[i]);
for (unsigned j = 0; j < other.people[i].numRel_; ++j)
relations[newId[i]][j].id = newId[ relations[newId[i]][j].id ];
}
else //If the member is present in both trees
{
for (unsigned j = 0; j < other.people[i].numRel_; ++j) //Adds the number of relatives from the II to the number in the I
{
if (newId[other.relatives[i][j]] >= numPeople)
if (newId[other.relations[i][j].id] >= numPeople)
++people[newId[i]].numRel_;
}
relatives[newId[i]].resize(people[newId[i]].numRel_);
relations[newId[i]].resize(people[newId[i]].numRel_);
for (unsigned j = 0; j < other.people[i].numRel_; ++j)
{
relatives[newId[i]][j + people[newId[i]].numRel_ - other.people[i].numRel_] = newId[other.relatives[i][j]];
relations[newId[i]][j + people[newId[i]].numRel_ - other.people[i].numRel_] = other.relations[i][j];
relations[newId[i]][j + people[newId[i]].numRel_ - other.people[i].numRel_].id = newId[other.relations[i][j].id];
relations[newId[i]][j + people[newId[i]].numRel_ - other.people[i].numRel_].type = other.relations[i][j].type;
}
}
}
@@ -167,12 +160,12 @@ unsigned Tree::findId(const char* name, const short year, const unsigned char mo
return Nobody;
}
unsigned Tree::findOldestAncestor(const unsigned &id, const bool &isMale)const
unsigned Tree::findOldestAncestor(unsigned id, bool isMale)const
{
for (unsigned i = 0; i < people[id].numRel_; ++i)
{
if (relations[id][i] == Child && people[ relatives[id][i] ].isMale_ == isMale)
return findOldestAncestor(relatives[id][i], isMale);
if (relations[id][i].type == Child && people[ relations[id][i].id ].isMale_ == isMale)
return findOldestAncestor(relations[id][i].id, isMale);
}
return id;
}
@@ -207,22 +200,14 @@ void Tree::saveTree() const
people[i].save(peopleFile);
peopleFile.close();
std::ofstream relativeFile(treeName + ".relatives", std::ios::binary);
std::ofstream relationFile(treeName + ".relations", std::ios::binary);
/*relativeFile.write((char*)&numPeople, sizeof(numPeople));
relationFile.write((char*)&numPeople, sizeof(numPeople));*/
for (unsigned i = 0; i < numPeople; ++i)
{
//relativeFile.write((char*)&people[i].numRel_, sizeof(people[i].numRel_));
for (unsigned j = 0; j < people[i].numRel_; ++j)
relativeFile.write(reinterpret_cast<char*>(&relatives[i][j]), sizeof(relatives[i][j]));
//relationFile.write((char*)&people[i].numRel_, sizeof(people[i].numRel_));
for (unsigned j = 0; j < people[i].numRel_; ++j)
relationFile.write(reinterpret_cast<char*>(&relations[i][j]), sizeof(relations[i][j]));
}
relativeFile.close();
relationFile.close();
}
@@ -242,26 +227,17 @@ bool Tree::loadTree()
people.sNum(numPeople);
peopleFile.close();
std::ifstream relativeFile(treeName + ".relatives", std::ios::binary);
std::ifstream relationFile(treeName + ".relations", std::ios::binary);
relatives.resize(numPeople);
std::ifstream relationFile(treeName + ".relations", std::ios::binary);
relations.resize(numPeople);
for (unsigned i = 0; i < numPeople; ++i)
{
relatives[i].resize(people[i].numRel_);
for (unsigned j = 0; j < people[i].numRel_; ++j)
relativeFile.read(reinterpret_cast<char*>(&relatives[i][j]), sizeof(relatives[i][j]));
relatives[i].sNum(people[i].numRel_);
relations[i].resize(people[i].numRel_);
for (unsigned j = 0; j < people[i].numRel_; ++j)
relationFile.read(reinterpret_cast<char*>(&relations[i][j]), sizeof(relations[i][j]));
relations[i].sNum(people[i].numRel_);
}
relatives.sNum(numPeople);
relations.sNum(numPeople);
relativeFile.close();
relationFile.close();
return 1;
}
@@ -270,22 +246,22 @@ void Tree::addPerson(const char* name, bool isMale, unsigned father, unsigned mo
{
Person newPerson(name, birth, isMale, death);
people.push(newPerson);
Array<unsigned> newRelative;
relatives.push(newRelative);
Array<Relation> newRelation;
relations.push(newRelation);
Array<Relation> newRels;
relations.push(newRels);
++numPeople;
addRelation(father, Parent, numPeople - 1);
addRelation(mother, Parent, numPeople - 1);
}
bool Tree::addRelation(const char* firstName, const Relation type, const char* secondName)
bool Tree::addRelation(const char* firstName, const RelType type, const char* secondName)
{
return addRelation(findId(firstName), type, findId(secondName));
}
bool Tree::addRelation(const unsigned firstId, const Relation type, const unsigned secondId, bool opposite)//
bool Tree::addRelation(const unsigned firstId, const RelType type, const unsigned secondId, bool opposite)//
{
if (firstId == Nobody || firstId >= numPeople || secondId == Nobody || secondId >= numPeople || type == Invalid)
return 0;
@@ -293,16 +269,15 @@ bool Tree::addRelation(const unsigned firstId, const Relation type, const unsign
unsigned i = 0;
for (; i < people[firstId].numRel_; ++i) //If they are already relatives
{
if (relatives[firstId][i] == secondId)
if (relations[firstId][i].id == secondId)
{
relations[firstId][i] = type;
relations[firstId][i].type = type;
break;
}
}
if (i >= people[firstId].numRel_)
{
relatives[firstId].push(secondId);
relations[firstId].push(type);
relations[firstId].push({secondId, type});
++people[firstId].numRel_;
}
@@ -337,12 +312,11 @@ void Tree::removePerson(const unsigned id)
unsigned relId; //Íoìåð íà òåêóùèÿ ðîäíèíàòà
for (unsigned i = 0; i < people[id].numRel_; ++i) //Ïðåìàõâàò ñå âðúçêèòå íà ÷ëåíà çà ïðåìàõâàíå
{
relId = relatives[id][i];
relId = relations[id][i].id;
for (unsigned j = 0; j < people[relId].numRel_; ++j)
{
if (relatives[relId][j] == id)
if (relations[relId][j].id == id)
{
relatives[relId].remove(j);
relations[relId].remove(j);
break;
}
@@ -351,17 +325,16 @@ void Tree::removePerson(const unsigned id)
}
for (unsigned i = 0; i < people[numPeople - 2].numRel_; ++i) //Ïîñëåäíèÿò ÷ëåí âçåìà íîìåðà íà ïðåìàõíàòèÿ
{
relId = relatives[numPeople - 1][i];
relId = relations[numPeople - 1][i].id;
for (unsigned j = 0; j < people[relId].numRel_; ++j)
{
if (relatives[relId][j] == numPeople - 1)
if (relations[relId][j].id == numPeople - 1)
{
relatives[relId][j] = id;
relations[relId][j].id = id;
break;
}
}
}
relatives.remove(id);
relations.remove(id);
people.remove(id);
--numPeople;
@@ -376,9 +349,8 @@ void Tree::removeRelation(const unsigned firstId, const unsigned secondId)
{
for (unsigned i = 0; i < people[firstId].numRel_; ++i)
{
if (relatives[firstId][i] == secondId)
if (relations[firstId][i].id == secondId)
{
relatives[firstId].remove(i);
relations[firstId].remove(i);
--people[firstId].numRel_;
break;
@@ -386,9 +358,8 @@ void Tree::removeRelation(const unsigned firstId, const unsigned secondId)
}
for (unsigned i = 0; i < people[secondId].numRel_; ++i)
{
if (relatives[secondId][i] == firstId)
if (relations[secondId][i].id == firstId)
{
relatives[secondId].remove(i);
relations[secondId].remove(i);
--people[secondId].numRel_;
break;
@@ -396,8 +367,10 @@ void Tree::removeRelation(const unsigned firstId, const unsigned secondId)
}
}
void Tree::draw() const
void Tree::draw(person_id focused) const
{
erase(); //Clear the screen
wnoutrefresh(stdscr);
/* WINDOW* father = people[0].createPad(); */
/* WINDOW* mother = people[1].createPad(); */
@@ -411,16 +384,16 @@ void Tree::draw() const
/* 1, drawX, */
/* 1 +fh-1, drawX + fw-1); */
const U32 numPpl = people.gNum();
std::vector<bool> drawn(numPpl, false);
/* const U32 numPpl = people.gNum(); */
/* std::vector<bool> drawn(numPpl, false); */
U16 drawY = 0/* (LINES) / 2 */;
U16 drawX = 0/* (COLS) / 2 */;
drawLineRec(0, drawY, drawX);
drawLine(focused, drawY, drawX);
/* people[0].draw(drawY, drawY); */
/* for(U32 i=0; i<relations[0].gNum(); ++i) */
/* { */
/* if(relations[0][i] == Relation::Son) */
/* if(relations[0][i] == RelType::Son) */
/* { */
/* drawX = drawLineRec(i, drawY, drawX) + 2; */
/* } */
@@ -504,19 +477,19 @@ void Tree::printOldestAncestors(const unsigned id)const
void Tree::commonAncestorRec(const unsigned &id, const Array<char> &visited)const
void Tree::commonAncestorRec(person_id id, const Array<char> &visited)const
{
for (unsigned i = 0; i < people[id].numRel_; ++i)
{
if (relations[id][i] == Child)
if (relations[id][i].type == Child)
{
++visited[relatives[id][i]];
commonAncestorRec(relatives[id][i], visited);
++visited[relations[id][i].id];
commonAncestorRec(relations[id][i].id, visited);
}
}
}
static void linkToFirstBorn(I16 startY, I16 startX)
static U8 linkToFirstBorn(I16 startY, I16 startX)
{
if(startY >= -2 && startX >= 0)
{
@@ -529,9 +502,10 @@ static void linkToFirstBorn(I16 startY, I16 startX)
wnoutrefresh(win);
delwin(win);
}
return 3;
}
static void linkToChild(I16 startY, I16 startX, I16 endX)
static U8 linkToChild(I16 startY, I16 startX, I16 endX)
{
assert(endX >= startX);
@@ -550,34 +524,75 @@ static void linkToChild(I16 startY, I16 startX, I16 endX)
wnoutrefresh(win);
delwin(win);
}
return 3;
}
I16 Tree::drawLineRec(person_id id, I16 drawY, I16 drawX) const
I16 Tree::drawLine(person_id id, I16 drawY, I16 drawX) const
{
people[id].draw(drawY, drawX);
std::vector<person_id> sons;
std::vector<person_id> children;
for(U32 i=0; i<relations[id].gNum(); ++i)
{
if(relations[id][i] == Relation::Parent)
sons.push_back(relatives[id][i]);
if(relations[id][i].type == RelType::Parent)
children.push_back(relations[id][i].id);
}
if(!sons.empty())
if(!children.empty())
{
auto prevX = drawX;
drawY += BOX_HEIGHT;
linkToFirstBorn(drawY, drawX);
drawX = drawLineRec(sons[0], drawY + 3, drawX) + 1;
auto lnHt = linkToFirstBorn(drawY, drawX); /* Link height */
drawX = drawLine(children[0], drawY + lnHt, drawX);
for(size_t j = 1; j < sons.size(); ++j)
for(size_t j = 1; j < children.size(); ++j)
{
linkToChild(drawY + 1, prevX+1, drawX+1);
lnHt = linkToChild(drawY+1, prevX+1, drawX+1);
prevX = drawX;
drawX = drawLineRec(sons[j], drawY + 3, drawX) + 1;
drawX = drawLine(children[j], drawY + lnHt, drawX);
}
return drawX;
}
return drawX + people[id].boxWidth();
return drawX + people[id].boxWidth() + dist_between;
}
I16 Tree::drawLineWithWives(person_id id, I16 drawY, I16 drawX) const
{
/* const auto& rels = relations[id]; */
/* /\* const auto& rels = relations[id]; *\/ */
/* people[id].draw(drawY, drawX); */
/* /\* for(U32 i = 0; i < re *\/ */
/* std::vector<person_id> children; */
/* for(U32 i=0; i<relations[id].gNum(); ++i) */
/* { */
/* if(relations[id][i] == RelType::Parent) */
/* children.push_back(relatives[id][i]); */
/* } */
/* if(!children.empty()) */
/* { */
/* auto prevX = drawX; */
/* drawY += BOX_HEIGHT; */
/* auto lnHt = linkToFirstBorn(drawY, drawX); /\* Link height *\/ */
/* drawX = drawLine(children[0], drawY + lnHt, drawX); */
/* for(size_t j = 1; j < children.size(); ++j) */
/* { */
/* lnHt = linkToChild(drawY+1, prevX+1, drawX+1); */
/* prevX = drawX; */
/* drawX = drawLine(children[j], drawY + lnHt, drawX); */
/* } */
/* return drawX; */
/* } */
/* return drawX + people[id].boxWidth() + dist_between; */
}