Как реализовать многоотраслевую древовидную структуру в C - PullRequest
4 голосов
/ 18 мая 2011

Я давно не писал код на C. Я пытаюсь сделать многолистовое дерево. Я пытаюсь преобразовать реализацию C # trie в C, чтобы запустить его на GPU с CUDA. Но я застрял на этом. Можете ли вы мне помочь?

Моя реализация узла выглядит следующим образом:

struct Node2 {
char *Key;
char *ConsAlterKey;
char *MasterKey;
bool VowelDeletion;
char *Data;
char *MasterData;
Node2 *Childs;
int ChildCount;
};

А вот моя функция, которая добавляет узлы в три:

void AddAsChildren2(Node2 *Trie,int count)
{

//Trie->Childs=new Node2[count];
Trie->Childs=(Node2 *)malloc(sizeof(Node2)*count);

for(int i=0;i<count;i++)
{
    Trie->Childs[i].Key= GetKey();
    Trie->Childs[i].ConsAlterKey=GetConsAlterKey();
    Trie->Childs[i].MasterKey=GetMasterKey();
    Trie->Childs[i].VowelDeletion=GetVowelDeletion();
    Trie->Childs[i].Data=GetData();
    Trie->Childs[i].MasterData=GetMasterData();
    Trie->Childs[i].ChildCount=GetChildCount();

    if(Trie->Childs[i].ChildCount> 0)
    {
        AddAsChildren2(&(Trie->Childs[i]),Trie->Childs[i].ChildCount);
    }
}
}

который я вызываю из основной функции следующим образом:

Node2 NodeNew;
    .
    .
    . 
AddAsChildren2(&NodeNew,NodeNew->ChildCount);
TraverseTree2(&NodeNew);

Но когда я пытаюсь обойти дерево, я получаю неправильные значения, а иногда и исключения (возможно, проблема выделения памяти дочерних узлов)

Что я здесь не так делаю?

Ps. У первого узла есть дочерние узлы, и у меня нет проблем с присвоением значений, поэтому игнорируйте функции "getter". Я изменил их порядок на упрощенный код. Моя проблема в том, что я теряю значения после того, как код завершит эту часть.

Спасибо за быстрый ответ. Я читаю значения из файла.

Структура файла выглядит следующим образом.

Если строка / элемент не имеет дочерних узлов, она заканчивается символом «>», иначе она заканчивается значением ChildCount. А здесь символ «-» представляет значение NULL.

< root - - - - - 2
 < a - - False - - 4
  < aö - - False 184 - > 
  < dfı - - False 188 - > 
  < et ed - False 189 - 3 
   < aö - - False 184 - > 
   < dfı - - False 188 - > 
   < k ğ - False 191 - > 
  >
  < k ğ - False 191 - > 
 >
 < a - - False - - 4
  < aö - - False 184 - > 
  < dfı - - False 188 - > 
  < et ed - False 189 - 3 
   < aö - - False 184 - > 
   < dfı - - False 188 - > 
   < k ğ - False 191 - > 
  >
  < k ğ - False 191 - > 
 >
>

И не упрощенная версия моего кода выглядит следующим образом:

void AddAsChildren2(Node2 *Trie,FILE *fp,int count)
{

  char string[50];
  char *line=NULL;
  char *Temp;

  Trie->Childs=(Node2 *)malloc(sizeof(Node2)*count);
  //Trie->Childs=new Node2[count];


  for(int i=0;i<count;i++)
  {
if(fgets(string,50,fp))
{
        line=strtok(string," ");

    if(strcmp (line,"<")==0)
    {
        line=strtok( NULL, " ");
        Trie->Childs[i].Key= (strcmp(line,"-")==0?"":line);

        line=strtok( NULL, " ");
        Trie->Childs[i].ConsAlterKey=(strcmp(line,"-")==0?"":line);

        line=strtok( NULL, " ");
        Trie->Childs[i].MasterKey=(strcmp(line,"-")==0?"":line);

        line=strtok( NULL, " ");
        Trie->Childs[i].VowelDeletion=(strcmp(line,"-")==0?"":line);

        line=strtok( NULL, " ");
        Trie->Childs[i].Data=(strcmp(line,"-")==0?"":line);

        line=strtok( NULL, " ");
        Trie->Childs[i].MasterData=(strcmp(line,"-")==0?"":line);


        Temp = strtok( NULL, " ");

        if(strcmp(Temp,">")==0)
        {
                             //ends with >
            Trie->Childs[i].ChildCount=0;
        }
        else if((strcmp(Temp,"\n")!=0)&&(strlen(Temp)> 0))
        {
                           //ends with childcount value so it have childs

            Trie->Childs[i].ChildCount=atoi(Temp);

            AddAsChildren2(&(Trie->Childs[i]),fp,Trie->Childs[i].ChildCount);
        }


    }
}

}

}

Функция перемещения следующим образом:

void traversetree2(Node2 *tree)
{

printf("Key %s\n",tree->Key);
printf("ConsAlterKey %s\n",tree->ConsAlterKey);
printf("MasterKey %s\n",tree->MasterKey);

printf("Data %s\n",tree->Data);
printf("MasterData %s\n",tree->MasterData);

if(tree->ChildCount>0)
{
    for(int i=0;i<tree->ChildCount;i++)
    {
        traversetree2(&(tree->Childs[i]));
    }
}

}

И вывод:

Key root
ConsAlterKey
MasterKey
Data
MasterData
Key ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
ConsAlterKey
MasterKey
Data
MasterData
Key ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░÷E
ConsAlterKey
MasterKey
Data ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░÷E
MasterData
Key ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░÷E
ConsAlterKey
MasterKey
Data ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░÷E
MasterData
Key ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░÷E
ConsAlterKey ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░÷E
MasterKey
Data ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠░÷E
MasterData
Key ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠§E
ConsAlterKey
MasterKey
Data ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠§E
MasterData
Key ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠§E
ConsAlterKey
MasterKey
Data ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠§E
MasterData
Key ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠§E
ConsAlterKey ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠§E
MasterKey
Data ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠§E
MasterData

1 Ответ

3 голосов
/ 18 мая 2011

Ах, с большим количеством кода это легко: ваша проблема в том, что char string[50] является локальной переменной, и вы сохраняете много указателей в этот локальный массив, который теряется при возврате AddAsChildren2.В зависимости от того, нужно ли вам когда-либо освобождать эту структуру, вы можете strdup() всю строку и затем сохранить токены из нее или strdup() каждый отдельный токен (для упрощения освобождения).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...