Hello everyone,

I have a std::map that includes individual ID and a struct that contains father and mother information, read from a file "ped.txt". This file has the format: ID - FATHER - MOTHER. Some fathers or mothers don't have IDs as individuals. The code bellow is an example to populate the map.

ORIGINAL FILE:
1 0 0
2 0 0
3 14 20
14 999 6
20 10 1000
30 999 7
8 0 1000
77 3 8
500 77 0

Now, I'm trying to re-code all IDs in sequence (including father and mother), so that individuals that don't have father and mother (E.G.: 1 0 0 ) will receive the initials codes (they are founders of others), after that I need to ensure that all individuals will have ID greater than father and mother. As the example above, I need to generate codes from 1 to 14 ("0" will be kept).

For that individual with father, I was planning look for the new father ID (Need to be re-coded first) and after set the individual ID as one greater number.

I don't know if I can use map for that. Are there some properties from map that make this easier?

Thanks a lot!

PS: Thanks Mike for your help in this code.

#include <iostream>
#include <fstream>
#include <vector>
#include <map>

struct STreeGen                      /* Family structure declaration   */
{
  int ID;
  STreeGen *father;         /* Pointer to father structure   */
  STreeGen *mother;         /* Pointer to mother structure   */
} ;


int main()
{
	int indivV = 0;
	int fatherV =0;
	int motherV = 0;

	std::ifstream myfileGenealOriginal;

	myfileGenealOriginal.open("ped.txt");

	// ----------------------------
	std::map<int, STreeGen> IndivMap;
	// ----------------------------

	 while(myfileGenealOriginal >> indivV)
	  {
	    STreeGen& current_indiv = IndivMap[indivV];
	    current_indiv.ID = indivV; //assign ID to the new record at ID indivV.

	    myfileGenealOriginal >> fatherV >> motherV;

	    if(fatherV) {
	      current_indiv.father = &IndivMap[fatherV];
	      current_indiv.father->ID = fatherV;
	    } else
	      current_indiv.father = NULL;

	    if(motherV) {
	      current_indiv.mother = &IndivMap[motherV];
	      current_indiv.mother->ID = motherV;
	    } else
	      current_indiv.mother = NULL;
	  };
	std::cout << "PRINTING:" << std::endl;

	std::map<int, STreeGen>::const_iterator it;
	for (it = IndivMap.begin(); it != IndivMap.end(); ++it)
		std::cout << it->first << '\t'
                          << (it->second.father ? it->second.father->ID : 0) << " "
                          << (it->second.mother ? it->second.mother->ID : 0) << std::endl;

	
   return 0;
}

ORIGINAL FILE:
1 0 0
2 0 0
3 14 20
14 999 6
20 10 1000
30 999 7
8 0 1000
77 3 8
500 77 0

PRINTING:
1 0 0
2 0 0
3 14 20
6 0 0
7 0 0
8 0 1000
10 0 0
14 999 6
20 10 1000
30 999 7
77 3 8
500 77 0
999 0 0
1000 0 0

It looks to me like your output so far is correct. The "map" type isn't going to help you with your task, it just provides a space-efficient way of storing an indexed list of objects. Instead, you will want to traverse the tree structure you've built up. Specifically, for parents to have lower ids than their children, you will probably want to use a pre-order traversal of the tree: visit and handle both parent nodes before the individual, recursively. The simplest thing may be to fix the ID of a node and assign it into a new map, both at the same time, then delete the old map when you're finished.

Thanks a lot raptr_dflo!

I will try it.
Have a nice weekend

This question has already been answered. Start a new discussion instead.