עבור לתוכן

עץ חיפוש

Featured Replies

פורסם

אני מעונינת לערוך חיפוש בקובץ טקסט- ולשם כך: יצרתי את העת הבא השומר את המילים בקובץ: (יש לי מערך בגודל 26, וכל אינדקס מצביע על מערך חדש בגודל 26 בשביל האות הבאה במילה):

צומת בעץ:


public class trieNode
{
//dataחלק ה
public char Letter { get; set; }
public bool WordEnd { get; set; }
public long FirstOffset { get; set; }
public long NumberOfOccurrences { get; set; }

//האינדקס של האלמנט מיצג את האות התוכן מייצג את המצביע לבא
public int[] nodes;

//פונקציה בונה ריקה שבה אנחנו מבטיחים שמערך המצביעים יאותחל במלואו
public trieNode()
{
nodes = new int[26];
for (int i = 0; i < 26; i++)
{
nodes[i] = 0;
}
WordEnd = false;
FirstOffset = 0;
NumberOfOccurrences = 0;
}
}

עץ:


public class Trie
{
private trieNode tr;

//פונקציה בונה זו ממירה ממחרוזת שלמה שמייצגת צומת בעץ לאוביקט שמייצג צומת בעץ
public Trie(List<trieNode> list, string objectstring)
{
int i, moneWord = 0, j;
string word;
int check = 0, index;
trieNode rootNode = new trieNode();//בניית צומת השורש


list.Add(rootNode);

//הפונקציה הבונה של הטוקנייזר מקבלת את המחרוזת שיש לחלקה
//וכן את התו שיציין את סוף המחרוזת החלקית שיש להפריד מהמחרוזת הכוללת
StringTokenizer strTokenizer = new StringTokenizer(objectstring, new char[] { ' ' });

while (strTokenizer.Next() != null)//כל עוד יש מילים
{
word = strTokenizer.getWord(moneWord);//קליטת מילה
if (word == "\t\r\n")//סוף הקובץ
{
break;
}

word.ToCharArray();
index = 0;

//הכנסת המילה לעץ
i = 0;
check = 0;
while (i < word.Length)
{
if (i == 0)//אם זו האות הראשונה של המילה
{
if (list[0].nodes[word[0] - 'a'] == 0)//עוד לא התחילו מילה באות הזו
{
tr = new trieNode();//יצירת נוד חדש
tr.Letter = word[0];

list.Add(tr);

rootNode.nodes[word[0] - 'a'] = list.Count - 1;
index = list.Count - 1;
}
else
{//קיימת מילה המתחילה באות זו
index = getNode(list, word[0]);
check++;
}
}
else
{//לא האות הראשונה

j = i - 1;
//אינדקס מכיל את הנוד שבה מתחילה המילה

if (list[index].nodes[word[i] - 'a'] == 0)
{//אין 1 באות המתאימה בנוד
//ניצור חדש
tr = new trieNode();
tr.Letter = word[i];

list.Add(tr);

list[index].nodes[word[i] - 'a'] = list.Count-1;
index = list.Count - 1;
}
else
{//יש תחילית כזו

check++;
index = list[index].nodes[word[i] - 'a'];
}

j = i + 1;
if (j == word.Length)//סוף מילה
{//לבדוק שהנוד שנמצא הוא סוף המילה

if (tr.Letter != word[i])
{
tr = list[index];
}

tr.nodes[word[i] - 'a'] = -1;
tr.WordEnd = true;

if (check == word.Length)
{
tr.NumberOfOccurrences++;
}
}

}
i++;//מעבר לאות הבאה
}

moneWord++;
}
}

שאלותי: איך אפשר לשמור את העץ בקובץ טקסט על מנת לאחזר ממנו את המידע אח"כ?

פורסם

בשביל מה שאת מחפשת צריך להשתמש ב-attribute שנקרא Serializable או לממש ממשק ISerializable על ה-class שרוצים לשמור ואז יש מתודות שישמרו ויקראו אותו מהדיסק. הכי פשוט זה לעשות את זה לקובץ XML למשל:

http://www.switchonthecode.com/tutorials/csharp-tutorial-xml-serialization

פורסם
  • מחבר

איך עוברים על כל העץ המסועף - בלי לפספס , כד יליצור סרליזציה באופן ידני?

פורסם

עברתי על הקוד ולא הצלחתי להבין למה את קוראת לזה עץ - אין פה התפצלויות (left,right - כמו בעץ בינארי, או רשימה של מצביעים כמו בעצים מסוג אחר) אלא סוג של רשימה מקושרת חד כיוונית. דרך אגב, את לא שומרת ב-NODE את המילה המקורית, רק את המילה החלקית?

בעקרון, המימוש של הסרליזציה תלוי במבנה הנתונים של העץ - אפשר לעבור בריקורסיה על העץ כדי לעבור בכל העלים שלו.

פורסם
  • מחבר

ברשימה המקושרת יש 'הצבעה' על ידי אינדקס לצומת הבאה (ו'עץ' כי ככה זה נראה כשמציירים על דף).

בNODE אני שומרת רק את האות הקודמת - ולא את כל המילה.

אז איך עוברים על כל הרשימה לפי ההצבעות?

פורסם

משהו פה מאוד מוזר. מה המשמעות של הפרמטרים שמקבל הבנאי של העץ?

כי שמתי לב שהעץ בעצם משנה את הרשימה שהוא מקבל בבנאי... משהו שם לא נראה הגיוני. מאיפה מגיעה הרשימה הזו? איפה היא נשמרת? כי לפי המימוש הזה, העץ הוא חסר משמעות בלי הרשימה (אם כל צומת מכיל את האינדקסים של הצמתים הבנים שלה, אז בשביל לדעת מי הבנים באמת העץ צריך להכיל את הרשימה, והוא לא).

אגב, עץ כותבים Tree ולא Trie :)

פורסם
  • מחבר

הפרמטרים שהעץ מקבל:

מחרוזת שיש בתוכה קובץ שנקרא, ורשימה ריקה כדי לשמור בתוכה את המילים מהקובץ.

והשם -זה סוג של מבנה נתונים, מהמילה reTRIEval.

פורסם

למה העץ מקבל רשימה לשמור בה את הנתונים, במקום ליצור את הרשימה הזו בעצמו (ולהחזיק אותה בתור משתנה פנימי, פרטי, שלו)?

פורסם
  • מחבר

המטרה היא שהבנאי ייצר רשימה לעצמו, ואחרי שיכניס את הנתונים לעץ- יעשה סרליזציה וישמור אותם בקובץ טקסט כדי שאוכל להשתמש בהם בהמשך.

לכן -רק לבינתיים הוא מקבל אותה מהתכנית.

פורסם

אין שום הגיון בזה שהעץ מקבל את הרשימה מבחוץ. תהפכי את הרשימה למשתנה פנימי.

בשביל לשמור, כל מה שהתכנית צריכה לעשות זה לעבור על הרשימה, ולשמור כל איבר בנפרד. אחר כך כשקוראים את העץ מתוך הקובץ, צריך לדאוג שהרשימה נוצרת בדיוק באותו סדר שבו היא נשמרה לקובץ, וזהו.

פורסם

ה-List באמת צריך להיות פנימי אבל אם כבר עובדים object oriented אז הרבה יותר הגיוני שכל trieNode יחזיק רשימה של ה-trieNodes שיושבים מתחתיו, ולא מערך של מספרים שמייצגים מצביעים. בשפה כבר יש מצביעים מובנים, לא צריך לייצר ולנהל מבנה נתונים חדש שייצג מצביעים.

כדי לשמור את כל ה-nodes צריך פשוט לעשות serialize על הרשימה או רק על ה-node הראשון במקרה שהוא מחזיק תחתיו את כל האחרים.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים