用C#实现基于查寻字符串的文件行查询器(3)-设计与实现
2005-06-02 23:19
736 查看
作者:yxin1322
http://blog.csdn.net/yxin1322
转载请注明出处
上面2节我们已经很了解了程序应该具有的功能以及采用的算法,下面我们可以开始设计并实现程序了。
首先我们要有一些类来完成查询字符串从中缀到后缀的转换,将它们放在SearchEngine.Expression名字空间中:
ExpressionEntry 类:用于存储查询串分割后的元素,可以看做一个包含元素值和类型的结构体
ExpressionProcess 类:用于将中缀查询串转换成后缀查询串。
注:ExpressionEntry 类的两个属性分别存查询串元素的值和类型,例如a || b && c可以分割成5个元素:a、||、b、&&和c,分别可以存入5个ExpressionEntry 类的对象中,各对象的值就是元素本身,而它们的类型则分别为string、Or、 string、And、string。之所以要给它们分类,是因为这样可以减少后阶段在对逆波兰式进行运算时的复杂度,具体为什么请读者自己思考。将5个对象放入ArrayList中,形成的集合就可以代表一个表达式,并且中缀与后缀的转换就是改变个元素在集合中的位置。
//ExpressionEntry.cs using System; namespace SearchEngine { namespace Expression { /// <summary> /// ExpressionEntry 的摘要说明。 /// 类ExpressionEntry用于存储表达式分割后的每一个元素,它有两个字段组成,第一个是元素的值,可以是符号 /// 或者是字符串,一个是元素的类型,表明它是运算符还是字符串 /// </summary> public class ExpressionEntry { private string entry_value;//存表达式分离后的各个节点 private string entry_type;//存表达式分离后的各个节点的类型 public ExpressionEntry() { EntryValue=null; EntryType=null; } public ExpressionEntry(string Entryvalue,string Entrytype) { EntryValue=Entryvalue; EntryType=Entrytype; } public string EntryValue { get{return entry_value;} set{entry_value=value;} } public string EntryType { get{return entry_type;} set{entry_type=value;} } } } } |
//ExpressionProcess.cs using System; using System.Collections; using System.Text.RegularExpressions; namespace SearchEngine { namespace Expression { //该类用与处理输入的查询表达式,可以得到查询表达式的中序分割元素集合和后续分割元素集合 //集合中存储着ExpressionEntry对象 public class ExpressionProcess { private string expression; public ExpressionProcess() { Expression=null; } public ExpressionProcess(string ex) { Expression=ex; } public string Expression { get{return expression;} set{expression=value;} } //返回拆分好的表达式节点集合,属性为中序表达式 private ArrayList getExpressionEntries() { ArrayList al=new ArrayList(); string tem=expression; tem=tem.Replace("!"," ! ");//在运算符两边加空格 tem=tem.Replace("||"," || "); tem=tem.Replace("&&"," && "); tem=tem.Replace("("," ( "); tem=tem.Replace(")"," ) "); tem=Regex.Replace(tem,@"/s+"," ");//将多个空格变为一个空格 tem=tem.Trim();//删除两边的空格 string [] ExpressionEntries=Regex.Split(tem," "); for(int i=0;i<ExpressionEntries.Length;i++)//遍历拆分好的式子,构造表达式节点集合 { if(ExpressionEntries[i].Equals("!")) { al.Add(new ExpressionEntry(ExpressionEntries[i],"Not")); } else if(ExpressionEntries[i].Equals("||")) { al.Add(new ExpressionEntry(ExpressionEntries[i],"Or")); } else if(ExpressionEntries[i].Equals("&&")) { al.Add(new ExpressionEntry(ExpressionEntries[i],"And")); } else if(ExpressionEntries[i].Equals("(")) { al.Add(new ExpressionEntry(ExpressionEntries[i],"Left")); } else if(ExpressionEntries[i].Equals(")")) { al.Add(new ExpressionEntry(ExpressionEntries[i],"Right")); } else if(ExpressionEntries[i].Equals("")) { ; } else { al.Add(new ExpressionEntry(ExpressionEntries[i],"string"));//非逻辑符号的一律视为字符串 } } return al; } //返回拆分好的表达式节点集合,属性为后序表达式,即逆波兰式 public ArrayList getContradictoryPolandExpressionEntries() { ArrayList PolandExpression=new ArrayList();//存储逆波兰式 ArrayList Stack=new ArrayList();//符号栈 Stack.Add(new ExpressionEntry("#","#"));//符号栈底先存垫底符号 ArrayList Ex=getExpressionEntries();//得到中序节点集合 for(int i=0;i<Ex.Count;i++)//遍历中序节点集合 { ExpressionEntry ee=(ExpressionEntry)Ex[i];//对每一个节点判断优先关系 if(ee.EntryType.Equals("Left"))//对左括号的操作 { Stack.Add(ee); } else if(ee.EntryType.Equals("Right"))//对右括号的操作 { while(!((ExpressionEntry)Stack[Stack.Count-1]).EntryType.Equals("Left") && Stack.Count!=1) { PolandExpression.Add(Stack[Stack.Count-1]); Stack.RemoveAt(Stack.Count-1); } Stack.RemoveAt(Stack.Count-1); } else if(ee.EntryType.Equals("Or"))//对或运算符的操作 { while(Stack.Count!=1 && !((ExpressionEntry)Stack[Stack.Count-1]).EntryType.Equals("Left")) { PolandExpression.Add(Stack[Stack.Count-1]); Stack.RemoveAt(Stack.Count-1); } Stack.Add(ee); } else if(ee.EntryType.Equals("And"))//对与运算符的操作 { while(((ExpressionEntry)Stack[Stack.Count-1]).EntryType.Equals("And") || ((ExpressionEntry)Stack[Stack.Count-1]).EntryType.Equals("Not")) { PolandExpression.Add(Stack[Stack.Count-1]); Stack.RemoveAt(Stack.Count-1); } Stack.Add(ee); } else if(ee.EntryType.Equals("Not"))//对非运算符的操作 { while(((ExpressionEntry)Stack[Stack.Count-1]).EntryType.Equals("Not")) { PolandExpression.Add(Stack[Stack.Count-1]); Stack.RemoveAt(Stack.Count-1); } Stack.Add(ee); } else //对查询字符串的操作 { PolandExpression.Add(ee); } } while(Stack.Count!=1)//将符号栈的剩余符号放入逆波兰式集合,垫底符号不放入 { PolandExpression.Add(Stack[Stack.Count-1]); Stack.RemoveAt(Stack.Count-1); } return PolandExpression; //返回逆波兰式 } //打印表达式节点集合,可以是中序集合也可以是后序集合 public static void PrintExpressionEntries(ArrayList ExpressionEntriesList,int Mode) { if(Mode==0) { for(int i=0;i<ExpressionEntriesList.Count;i++) { System.Console.WriteLine("{0,9} : {1}",((ExpressionEntry)ExpressionEntriesList[i]).EntryType, ((ExpressionEntry)ExpressionEntriesList[i]).EntryValue); } } else { System.Console.Write("/n尼波兰表达式:"); for(int i=0;i<ExpressionEntriesList.Count;i++) { System.Console.Write("{0} ",((ExpressionEntry)ExpressionEntriesList[i]).EntryValue); } System.Console.WriteLine("/n"); } } } } } |
Query 类:作为所有查询类的基类,定义了一个查询结果集,一个查询结果集打印函数以及一个所有派生类必须独自实现的抽象函数Search( )。
NameQuery 类:用于“关键字”查询,继承自Query类,拥有Query的成员和方法。
AndQuery 类:用于“与”查询,继承自Query类,拥有Query的成员和方法。
OrQuery 类:用于“或”查询,继承自Query类,拥有Query的成员和方法。
NotQuery 类:用于“非”查询,继承自Query类,拥有Query的成员和方法。
SearchResultCompare 类:为了使查询结果集中的SearchResultEntry类对象能够在ArrayList中排序,定此类并实现IComparer接口。SearchResultEntry类存储着查询的结果,每一个SearchResultEntry类的对象存储一条满足查询条件的记录,该类将在后面详细描述。
//Query.cs using System; using System.Collections; namespace SearchEngine { namespace QueryClass { /// <summary> /// Query 的摘要说明。 /// 作为查询类的基类 /// </summary> public abstract class Query { private ArrayList search_results;//用于存储查询结果 public Query() { search_results=new ArrayList(); } public ArrayList SearchResults//属性 { get { ArrayList al=(ArrayList)search_results.Clone(); return al; } set { search_results=(ArrayList)value.Clone(); } } public abstract void Search();//抽象函数 public void PrintSearchResult() { System.Console.WriteLine("查询结果:共找到{0}条记录。",this.SearchResults.Count); System.Console.WriteLine("----------------------------------------------------------------------"); for(int i=0;i<this.SearchResults.Count;i++) { SearchResultEntry sre=(SearchResultEntry)SearchResults[i]; System.Console.WriteLine("[{0,2}]:{1}",sre.LineNumber,sre.LineStr); } System.Console.WriteLine("----------------------------------------------------------------------"); } } } } |
//NameQuery.cs using System; using System.Collections; using System.IO; namespace SearchEngine { namespace QueryClass { /// <summary> /// NameQuery 的摘要说明。 /// 单关键字查询类 /// </summary> public class NameQuery:Query { private string keyword;//存储查询关键字 private string filename;//存储文件名 //默认构造函数 public NameQuery():base() { KeyWord=""; FileName=""; } //带参数的构造函数 public NameQuery(string key,string fn):base() { KeyWord=key; filename=fn; this.Search();//初始化完毕立即搜索 } //属性 public string KeyWord { set{keyword=value;} get{return keyword;} } //属性 public string FileName { set{filename=value;} get{return filename;} } //重写Search函数:将包含有keyword的行写入结果集合 public override void Search() { if(this.FileName=="" || this.KeyWord=="")//如果文件未指定或关键字未指定 { System.Console.WriteLine("查询关键字或查询目标未设置"); return; } if(!File.Exists(FileName))//如果文件不存在 { System.Console.WriteLine("待查询的目标文件不存在!"); return ; } ArrayList result=new ArrayList(); StreamReader sr=File.OpenText(FileName); string tem=sr.ReadLine(); int i=1; while(tem!=null) { if(tem.IndexOf(KeyWord)!=-1) result.Add(new SearchResultEntry(i,tem)); tem=sr.ReadLine(); i++; } sr.Close(); this.SearchResults=result; } } } } |
//AndQuery.cs using System; using System.Collections; namespace SearchEngine { namespace QueryClass { /// <summary> /// AndQuery 的摘要说明。 /// “与”查询类 /// </summary> public class AndQuery:Query { private ArrayList param1;//存储第一个结果集参数 private ArrayList param2;//存储第二个结果结参数 //默认构造函数 public AndQuery():base() { param1=new ArrayList(); param2=new ArrayList(); } //带参构造函数 public AndQuery(Query q1,Query q2):base() { param1=q1.SearchResults; param2=q2.SearchResults; this.Search(); } public ArrayList Param1//属性 { get { ArrayList al=(ArrayList)param1.Clone(); return al; } set { param1=(ArrayList)value.Clone(); } } public ArrayList Param2//属性 { get { ArrayList al=(ArrayList)param2.Clone(); return al; } set { param2=(ArrayList)value.Clone(); } } public override void Search() { ArrayList result=new ArrayList(); for(int i=0;i<this.Param1.Count;i++) { for(int j=0;j<this.Param2.Count;j++) { if(((SearchResultEntry)Param1[i]).LineNumber==((SearchResultEntry)Param2[j]).LineNumber) result.Add((SearchResultEntry)Param1[i]); } } result.Sort(new SearchResultCompare());//将结果按照行号排序 this.SearchResults=result;//将结果写入最终结果 } } } } |
//OrQuery.cs using System; using System.Collections; namespace SearchEngine { namespace QueryClass { /// <summary> /// OrQuery 的摘要说明。 /// “或”查询类 /// </summary> public class OrQuery:Query { private ArrayList param1;//存储第一个结果集参数 private ArrayList param2;//存储第二个结果结参数 //默认构造函数 public OrQuery():base() { param1=new ArrayList(); param2=new ArrayList(); } //带参构造函数 public OrQuery(Query q1,Query q2):base() { param1=q1.SearchResults; param2=q2.SearchResults; this.Search(); } public ArrayList Param1//属性 { get { ArrayList al=(ArrayList)param1.Clone(); return al; } set { param1=(ArrayList)value.Clone(); } } public ArrayList Param2//属性 { get { ArrayList al=(ArrayList)param2.Clone(); return al; } set { param2=(ArrayList)value.Clone(); } } // public override void Search() { ArrayList result=new ArrayList(); int sign=0; for(int i=0;i<this.Param1.Count;i++) { for(int j=0;j<this.Param2.Count;j++) { if(((SearchResultEntry)Param1[i]).LineNumber==((SearchResultEntry)Param2[j]).LineNumber) sign=1; } if(sign==0) { result.Add((SearchResultEntry)Param1[i]); } sign=0; } for(int k=0;k<this.Param2.Count;k++) { result.Add((SearchResultEntry)Param2[k]); } result.Sort(new SearchResultCompare());//将结果按照行号排序 this.SearchResults=result;//将结果写入最终结果 } } } } |
//NotQuery.cs using System; using System.Collections; using System.IO; namespace SearchEngine { namespace QueryClass { /// <summary> /// NotQuery 的摘要说明。 /// 取反查询的类 /// </summary> public class NotQuery:Query { private ArrayList unNotResult; private string filename;//存储文件名 public NotQuery():base() { UnNotResult=new ArrayList(); FileName=""; } //带参数的构造函数 public NotQuery(Query q,string file_name):base() { UnNotResult=q.SearchResults; filename=file_name; this.Search();//初始化完毕立即搜索 } public ArrayList UnNotResult//属性 { get { ArrayList al=(ArrayList)unNotResult.Clone(); return al; } set { unNotResult=(ArrayList)value.Clone(); } } //属性 public string FileName { set{filename=value;} get{return filename;} } //重写Search函数:将不含有keyword的行写入结果集合 public override void Search() { if(this.FileName=="")//如果文件未指定或关键字未指定 { System.Console.WriteLine("查询文件未设置"); return; } if(!File.Exists(FileName))//如果文件不存在 { System.Console.WriteLine("待查询的目标文件不存在!"); return ; } ArrayList result=new ArrayList();//结果集合 StreamReader sr=File.OpenText(FileName); string tem=sr.ReadLine(); int i=1;//行号 int sign=0;//判定当前行是否出现在参数结果集中的标志,如果当前行出现在参数结果集中,sign置1 while(tem!=null)//遍历文件所有行 { for(int j=0;j<this.UnNotResult.Count;j++) { if(((SearchResultEntry)UnNotResult[j]).LineNumber==i)//当发现当前行与参数结果集重复,置标志sign sign=1; } if(sign==0)//如果标志未置1,则将当前行加如结果集合 { result.Add(new SearchResultEntry(i,tem)); } sign=0;//标志未重新置为0 tem=sr.ReadLine(); i++; } sr.Close(); this.SearchResults=result;//将结果写入最终结果 } } } } |
//SearchResultCompare.cs using System; using System.Collections; namespace SearchEngine { namespace QueryClass { /// <summary> /// SearchResultCompare 的摘要说明。 /// 为了SearchResultEntry能够在ArrayList中排序,特实现IComparer接口 /// </summary> public class SearchResultCompare:System.Collections.IComparer { public int Compare(Object x,Object y) { return ((SearchResultEntry)x).LineNumber-((SearchResultEntry)y).LineNumber; } } } } |
注:以上查询类中真正操作了文件的只是NameQuery类,它负责从文件中找出含有关键字的行,并生成SearchResultCompare对象存入结果集合,而其他查询类,诸如AndQuery、OrQuery、NotQuery等类只是在多个NameQuery的查询结果集上进行以、或、非的运算。
注:以上查询类中真正操作了文件的只是NameQuery类,它负责从文件中找出含有关键字的行,并生成SearchResultCompare对象存入结果集合,而其他查询类,诸如AndQuery、OrQuery、NotQuery等类只是在多个NameQuery的查询结果集上进行以、或、非的运算。
注:以上查询类中真正操作了文件的只是NameQuery类,它负责从文件中找出含有关键字的行,并生成SearchResultCompare对象存入结果集合,而其他查询类,诸如AndQuery、OrQuery、NotQuery等类只是在多个NameQuery的查询结果集上进行以、或、非的运算。
注:以上查询类中真正操作了文件的只是NameQuery类,它负责从文件中找出含有关键字的行,并生成SearchResultCompare对象存入结果集合,而其他查询类,诸如AndQuery、OrQuery、NotQuery等类只是在多个NameQuery的查询结果集上进行以、或、非的运算。
注:以上查询类中真正操作了文件的只是NameQuery类,它负责从文件中找出含有关键字的行,并生成SearchResultCompare对象存入结果集合,而其他查询类,诸如AndQuery、OrQuery、NotQuery等类只是在多个NameQuery的查询结果集上进行以、或、非的运算。
核心的类已经实现,接下来就是定义测试类将他们有机地结合起来,成为一个整体。类列表如下:SearchText类:该类的每个对象绑定一个文件,并对文件进行查询操作。
SearchResultEntry类:该类存储查询到的结果信息,每个SearchResultEntry对象存储一条查询结果,每个SearchResultEntry包括两个部分,第一部分为结果的行号,第二部分为结果的内容。
SearchDoor类:定义程序的主函数。
//SearchText.csusing System; using System.Collections; using SearchEngine.QueryClass; using SearchEngine.Expression;namespace SearchEngine { /// <summary> /// 该类提供了搜索文件的类实现 /// 搜索文件的类 /// </summary> public class SearchText { private string file_name; private ArrayList expression_entries; public SearchText() { FileName=""; ExpressionEntries=new ArrayList(); } public SearchText(string filename,ArrayList expressionEntries) { FileName=filename; ExpressionEntries=(ArrayList)expressionEntries.Clone(); } public string FileName { set{file_name=value;} get{return file_name;} } public ArrayList ExpressionEntries { set{expression_entries=(ArrayList)value.Clone();} get { ArrayList al=(ArrayList)expression_entries.Clone(); return al; } } public ArrayList getSearchResult() { if(this.FileName=="") { System.Console.WriteLine("没有指定查询的文件!"); return null; } if(this.expression_entries.Count==0) { System.Console.WriteLine("查询字符串为空!"); return null; } ArrayList expression=this.ExpressionEntries; ArrayList Stack=new ArrayList(); for(int i=0;i<expression.Count;i++) { ExpressionEntry ee=(ExpressionEntry)expression[i]; if(ee.EntryType.Equals("string")) { Stack.Add(new NameQuery(ee.EntryValue,this.FileName)); } else if(ee.EntryType.Equals("And")) { if(Stack.Count<2) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q1=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Query q2=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new AndQuery(q1,q2)); } else if(ee.EntryType.Equals("Or")) { if(Stack.Count<2) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q1=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Query q2=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new OrQuery(q1,q2)); } else if(ee.EntryType.Equals("Not")) { if(Stack.Count<1) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new NotQuery(q,this.FileName)); } else { System.Console.WriteLine("表达式出现异常!"); return null; } } if(Stack.Count!=1) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } return ((Query)Stack[0]).SearchResults; } public static void PrintSearchResult(ArrayList Result) { System.Console.WriteLine("查询结果:共找到{0}条记录。",Result.Count); System.Console.WriteLine("----------------------------------------------------------------------"); for(int i=0;i<Result.Count;i++) { SearchResultEntry sre=(SearchResultEntry)Result[i]; System.Console.WriteLine("[{0,2}]:{1}",sre.LineNumber,sre.LineStr); } System.Console.WriteLine("----------------------------------------------------------------------/n/n"); } } } |
SearchResultEntry类:该类存储查询到的结果信息,每个SearchResultEntry对象存储一条查询结果,每个SearchResultEntry包括两个部分,第一部分为结果的行号,第二部分为结果的内容。
SearchDoor类:定义程序的主函数。
//SearchText.csusing System; using System.Collections; using SearchEngine.QueryClass; using SearchEngine.Expression;namespace SearchEngine { /// <summary> /// 该类提供了搜索文件的类实现 /// 搜索文件的类 /// </summary> public class SearchText { private string file_name; private ArrayList expression_entries; public SearchText() { FileName=""; ExpressionEntries=new ArrayList(); } public SearchText(string filename,ArrayList expressionEntries) { FileName=filename; ExpressionEntries=(ArrayList)expressionEntries.Clone(); } public string FileName { set{file_name=value;} get{return file_name;} } public ArrayList ExpressionEntries { set{expression_entries=(ArrayList)value.Clone();} get { ArrayList al=(ArrayList)expression_entries.Clone(); return al; } } public ArrayList getSearchResult() { if(this.FileName=="") { System.Console.WriteLine("没有指定查询的文件!"); return null; } if(this.expression_entries.Count==0) { System.Console.WriteLine("查询字符串为空!"); return null; } ArrayList expression=this.ExpressionEntries; ArrayList Stack=new ArrayList(); for(int i=0;i<expression.Count;i++) { ExpressionEntry ee=(ExpressionEntry)expression[i]; if(ee.EntryType.Equals("string")) { Stack.Add(new NameQuery(ee.EntryValue,this.FileName)); } else if(ee.EntryType.Equals("And")) { if(Stack.Count<2) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q1=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Query q2=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new AndQuery(q1,q2)); } else if(ee.EntryType.Equals("Or")) { if(Stack.Count<2) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q1=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Query q2=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new OrQuery(q1,q2)); } else if(ee.EntryType.Equals("Not")) { if(Stack.Count<1) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new NotQuery(q,this.FileName)); } else { System.Console.WriteLine("表达式出现异常!"); return null; } } if(Stack.Count!=1) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } return ((Query)Stack[0]).SearchResults; } public static void PrintSearchResult(ArrayList Result) { System.Console.WriteLine("查询结果:共找到{0}条记录。",Result.Count); System.Console.WriteLine("----------------------------------------------------------------------"); for(int i=0;i<Result.Count;i++) { SearchResultEntry sre=(SearchResultEntry)Result[i]; System.Console.WriteLine("[{0,2}]:{1}",sre.LineNumber,sre.LineStr); } System.Console.WriteLine("----------------------------------------------------------------------/n/n"); } } } |
SearchResultEntry类:该类存储查询到的结果信息,每个SearchResultEntry对象存储一条查询结果,每个SearchResultEntry包括两个部分,第一部分为结果的行号,第二部分为结果的内容。
SearchDoor类:定义程序的主函数。
//SearchText.csusing System; using System.Collections; using SearchEngine.QueryClass; using SearchEngine.Expression;namespace SearchEngine { /// <summary> /// 该类提供了搜索文件的类实现 /// 搜索文件的类 /// </summary> public class SearchText { private string file_name; private ArrayList expression_entries; public SearchText() { FileName=""; ExpressionEntries=new ArrayList(); } public SearchText(string filename,ArrayList expressionEntries) { FileName=filename; ExpressionEntries=(ArrayList)expressionEntries.Clone(); } public string FileName { set{file_name=value;} get{return file_name;} } public ArrayList ExpressionEntries { set{expression_entries=(ArrayList)value.Clone();} get { ArrayList al=(ArrayList)expression_entries.Clone(); return al; } } public ArrayList getSearchResult() { if(this.FileName=="") { System.Console.WriteLine("没有指定查询的文件!"); return null; } if(this.expression_entries.Count==0) { System.Console.WriteLine("查询字符串为空!"); return null; } ArrayList expression=this.ExpressionEntries; ArrayList Stack=new ArrayList(); for(int i=0;i<expression.Count;i++) { ExpressionEntry ee=(ExpressionEntry)expression[i]; if(ee.EntryType.Equals("string")) { Stack.Add(new NameQuery(ee.EntryValue,this.FileName)); } else if(ee.EntryType.Equals("And")) { if(Stack.Count<2) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q1=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Query q2=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new AndQuery(q1,q2)); } else if(ee.EntryType.Equals("Or")) { if(Stack.Count<2) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q1=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Query q2=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new OrQuery(q1,q2)); } else if(ee.EntryType.Equals("Not")) { if(Stack.Count<1) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new NotQuery(q,this.FileName)); } else { System.Console.WriteLine("表达式出现异常!"); return null; } } if(Stack.Count!=1) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } return ((Query)Stack[0]).SearchResults; } public static void PrintSearchResult(ArrayList Result) { System.Console.WriteLine("查询结果:共找到{0}条记录。",Result.Count); System.Console.WriteLine("----------------------------------------------------------------------"); for(int i=0;i<Result.Count;i++) { SearchResultEntry sre=(SearchResultEntry)Result[i]; System.Console.WriteLine("[{0,2}]:{1}",sre.LineNumber,sre.LineStr); } System.Console.WriteLine("----------------------------------------------------------------------/n/n"); } } } |
SearchResultEntry类:该类存储查询到的结果信息,每个SearchResultEntry对象存储一条查询结果,每个SearchResultEntry包括两个部分,第一部分为结果的行号,第二部分为结果的内容。
SearchDoor类:定义程序的主函数。
//SearchText.csusing System; using System.Collections; using SearchEngine.QueryClass; using SearchEngine.Expression;namespace SearchEngine { /// <summary> /// 该类提供了搜索文件的类实现 /// 搜索文件的类 /// </summary> public class SearchText { private string file_name; private ArrayList expression_entries; public SearchText() { FileName=""; ExpressionEntries=new ArrayList(); } public SearchText(string filename,ArrayList expressionEntries) { FileName=filename; ExpressionEntries=(ArrayList)expressionEntries.Clone(); } public string FileName { set{file_name=value;} get{return file_name;} } public ArrayList ExpressionEntries { set{expression_entries=(ArrayList)value.Clone();} get { ArrayList al=(ArrayList)expression_entries.Clone(); return al; } } public ArrayList getSearchResult() { if(this.FileName=="") { System.Console.WriteLine("没有指定查询的文件!"); return null; } if(this.expression_entries.Count==0) { System.Console.WriteLine("查询字符串为空!"); return null; } ArrayList expression=this.ExpressionEntries; ArrayList Stack=new ArrayList(); for(int i=0;i<expression.Count;i++) { ExpressionEntry ee=(ExpressionEntry)expression[i]; if(ee.EntryType.Equals("string")) { Stack.Add(new NameQuery(ee.EntryValue,this.FileName)); } else if(ee.EntryType.Equals("And")) { if(Stack.Count<2) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q1=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Query q2=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new AndQuery(q1,q2)); } else if(ee.EntryType.Equals("Or")) { if(Stack.Count<2) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q1=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Query q2=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new OrQuery(q1,q2)); } else if(ee.EntryType.Equals("Not")) { if(Stack.Count<1) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new NotQuery(q,this.FileName)); } else { System.Console.WriteLine("表达式出现异常!"); return null; } } if(Stack.Count!=1) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } return ((Query)Stack[0]).SearchResults; } public static void PrintSearchResult(ArrayList Result) { System.Console.WriteLine("查询结果:共找到{0}条记录。",Result.Count); System.Console.WriteLine("----------------------------------------------------------------------"); for(int i=0;i<Result.Count;i++) { SearchResultEntry sre=(SearchResultEntry)Result[i]; System.Console.WriteLine("[{0,2}]:{1}",sre.LineNumber,sre.LineStr); } System.Console.WriteLine("----------------------------------------------------------------------/n/n"); } } } |
SearchResultEntry类:该类存储查询到的结果信息,每个SearchResultEntry对象存储一条查询结果,每个SearchResultEntry包括两个部分,第一部分为结果的行号,第二部分为结果的内容。
SearchDoor类:定义程序的主函数。
//SearchText.csusing System; using System.Collections; using SearchEngine.QueryClass; using SearchEngine.Expression;namespace SearchEngine { /// <summary> /// 该类提供了搜索文件的类实现 /// 搜索文件的类 /// </summary> public class SearchText { private string file_name; private ArrayList expression_entries; public SearchText() { FileName=""; ExpressionEntries=new ArrayList(); } public SearchText(string filename,ArrayList expressionEntries) { FileName=filename; ExpressionEntries=(ArrayList)expressionEntries.Clone(); } public string FileName { set{file_name=value;} get{return file_name;} } public ArrayList ExpressionEntries { set{expression_entries=(ArrayList)value.Clone();} get { ArrayList al=(ArrayList)expression_entries.Clone(); return al; } } public ArrayList getSearchResult() { if(this.FileName=="") { System.Console.WriteLine("没有指定查询的文件!"); return null; } if(this.expression_entries.Count==0) { System.Console.WriteLine("查询字符串为空!"); return null; } ArrayList expression=this.ExpressionEntries; ArrayList Stack=new ArrayList(); for(int i=0;i<expression.Count;i++) { ExpressionEntry ee=(ExpressionEntry)expression[i]; if(ee.EntryType.Equals("string")) { Stack.Add(new NameQuery(ee.EntryValue,this.FileName)); } else if(ee.EntryType.Equals("And")) { if(Stack.Count<2) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q1=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Query q2=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new AndQuery(q1,q2)); } else if(ee.EntryType.Equals("Or")) { if(Stack.Count<2) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q1=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Query q2=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new OrQuery(q1,q2)); } else if(ee.EntryType.Equals("Not")) { if(Stack.Count<1) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } Query q=(Query)Stack[Stack.Count-1]; Stack.RemoveAt(Stack.Count-1); Stack.Add(new NotQuery(q,this.FileName)); } else { System.Console.WriteLine("表达式出现异常!"); return null; } } if(Stack.Count!=1) { System.Console.WriteLine("表达式语法出错,请检查!"); return null; } return ((Query)Stack[0]).SearchResults; } public static void PrintSearchResult(ArrayList Result) { System.Console.WriteLine("查询结果:共找到{0}条记录。",Result.Count); System.Console.WriteLine("----------------------------------------------------------------------"); for(int i=0;i<Result.Count;i++) { SearchResultEntry sre=(SearchResultEntry)Result[i]; System.Console.WriteLine("[{0,2}]:{1}",sre.LineNumber,sre.LineStr); } System.Console.WriteLine("----------------------------------------------------------------------/n/n"); } } } |
//SearchResultEntry.csusing System;namespace SearchEngine { /// <summary> /// SearchResultEntry 的摘要说明。 /// 该类存储查询到的结果信息,每个SearchResultEntry对象存储一条查询结果 /// 每个SearchResultEntry包括两个部分,第一部分为结果的行号,第二部分为结果的内容 /// </summary> public class SearchResultEntry { private int line_number; private string line_str; //默认构造函数 public SearchResultEntry() { LineNumber=-1; LineStr=null; } //带参构造函数 public SearchResultEntry(int ln,string ls) { LineNumber=ln; LineStr=ls; } //line_number属性 public int LineNumber { get{return line_number;} set{line_number=value;} } //line_str属性 public string LineStr { get{return line_str;} set{line_str=value;} } } } |
//SearchDoor.csusing System; using System.Collections; using SearchEngine.Expression; using SearchEngine.QueryClass; using System.IO;namespace SearchEngine { //该类用做程序入口 public class SearchDoor { public static void Main() { System.Console.WriteLine(" ---------------------------------------------- "); System.Console.WriteLine(" 文件行搜索引擎 /n"); System.Console.WriteLine(" 1.支持与、或、非组合 2.支持括号嵌套 "); System.Console.WriteLine(" ---------------------------------------------- "); System.Console.WriteLine(" 运行环境:Microsoft .Net FrameWork "); System.Console.WriteLine(" ---------------------------------------------- "); System.Console.Write("-请输入文件路径及文件名:"); String FileName=System.Console.ReadLine(); while(!File.Exists(FileName)) { System.Console.WriteLine("-你指定的文件不存在,请重新指定!/n"); System.Console.Write("-请输入文件路径及文件名:"); FileName=System.Console.ReadLine(); } while(true) { System.Console.Write("/n-请输入查询串(支持括号):"); string QueryString=System.Console.ReadLine(); ExpressionProcess ep=new ExpressionProcess(QueryString); ArrayList expression=ep.getContradictoryPolandExpressionEntries(); ExpressionProcess.PrintExpressionEntries(expression,1); SearchText st=new SearchText(FileName,expression); ArrayList ResultSet=st.getSearchResult(); if(ResultSet!=null) SearchText.PrintSearchResult(ResultSet); } } } } |
2.面向对象设计方法中的继承可以使设计的类在概念与实现上有层次关系,多态的实质是方法的调用在执行期动态决定,如果多个类继承自一个父类,那么其父类的对象可以用它的子类的构造函数来构造,换句话说就是父类的指针可以指向并操作子类的对象,利用这一特性,我们在设计方法时,如果将参数的类型定义为父类的类型,那么将其子类的对象作为参数传入都是合法的,这样就不需要为每个子类都单独定义一个函数。 无论如何,我的第一步是迈出了,程序虽然很小,但一定还存在着许多逻辑的错误和设计上的不足,还请读过我文章的朋友能够留言给予指正,我都将虚心接受。代码下载:http://free5.ys168.com/?yxin1322
相关文章推荐
- 用C#实现基于查寻字符串的文件行查询器(1)-概述
- 用C#实现基于查寻字符串的文件行查询器(2)-相关技术介绍
- 基于.Net(C#开发)平台的三层框架架构软件的设计与实现
- 【出版直播】博客园征途系列,《设计模式--基于C#的工程化实现及扩展》专题上线
- resumable.js —— 基于 HTML 5 File API 的文件上传组件 支持续传后台c#实现
- 【加密解密】基于CryptoAPI的文件加解密系统设计与实现
- 基于XML的配置文件访问接口设计和实现
- [毕业设计-基于android的手机网盘的设计与实现] java中文件的socket传输问题
- 【C#网络编程系列】专题十一:实现一个基于FTP协议的程序—文件上传下载器
- [C# 网络编程系列]专题十一:实现一个基于FTP协议的程序——文件上传下载器
- 基于python智慧树刷课脚本在C#语言下的设计与实现
- 基于XML的配置文件访问接口设计和实现
- 《设计模式--基于C#的工程化实现及扩展》补充 Security Design Pattern 系列 1 公钥体系与分布式环境要求
- C#利用Tamir.SharpSSH类库实现SFTP(基于ssh)文件操作
- “基于关键字匹配的文本过滤系统”配置文件的设计和实现(C/C++源码)
- 基于魔兽哈希算法的Ogre资源文件扩展的设计与实现
- 基于μcosII的嵌入式文件系统的设计与实现
- 【现场直播】博客园征途系列,《设计模式——基于C#的工程化实现及扩展》封面火热出炉
- c#、asp.net 基于ajaxfileupload.js 实现文件异步上传
- C#实现使用API函数播放MP3等音频文件的类设计