public Dictionary <int, List <FinalNode1> > BTLevelScore(String queryLaTeX, String resultLaTeX) { AABTreeStructure acquireBtreeStructure = new AABTreeStructure(); //调用这个类,获取树结构的类 List <FinalNode1> queryLaTeXAdjacentNodeList = new List <FinalNode1>(); //存放“查询表达式”邻接节点有序对的集合 List <FinalNode1> resultLaTeXAdjacentNodeList = new List <FinalNode1>(); //存放“结果表达式”邻接节点有序对的集合 queryLaTeXAdjacentNodeList = acquireBtreeStructure.AdjacentNodeList(queryLaTeX); //已经存放“查询表达式”邻接节点有序对的集合 resultLaTeXAdjacentNodeList = acquireBtreeStructure.AdjacentNodeList(resultLaTeX); //已经存放“结果表达式”邻接节点有序对的集合 //=====这个方法一开始只是默认查询表达式是结果表达式的子式,但是如果查询表达式不是结果表达式的子式,那就不能用这个指标了======================= //如果查询表达式的长度“大于”结果表达式的长度,那说明一定没有包含,所以此时该指标得分为0 if (queryLaTeXAdjacentNodeList.Count > resultLaTeXAdjacentNodeList.Count) { return(null); } //=====这个方法一开始只是默认查询表达式是结果表达式的子式,但是如果查询表达式不是结果表达式的子式,那就不能用这个指标了======================= //我先算一下查询表达式的树在结果表达式的树中的高度 int panduan1 = queryLaTeXAdjacentNodeList.Count;//这个是查询表达式的节点的个数 int panduan2 = 0; int i = 0; int p = 0; int counts = 1; Dictionary <int, List <FinalNode1> > tempdic = new Dictionary <int, List <FinalNode1> >(); for (int j = 0; j < resultLaTeXAdjacentNodeList.Count; j++) { p = j; while (i != queryLaTeXAdjacentNodeList.Count) { //Console.WriteLine("查询表达式集合:" + i); //Console.WriteLine("查询表达式总共个数:" + queryLaTeXAdjacentNodeList.Count); //Console.WriteLine("结果表达式集合:" + p); //Console.WriteLine("结果表达式总共个数:" + resultLaTeXAdjacentNodeList.Count); //Console.WriteLine("=============================="); if (queryLaTeXAdjacentNodeList[i].zifu.Equals(resultLaTeXAdjacentNodeList[p].zifu)) { i++; p++; panduan2++; } else//一旦有不相等的,说明肯定不相等,那就直接终止循环 { //这里得添加一个标志吧,直接结束 panduan2 = 0; break; } if (p == resultLaTeXAdjacentNodeList.Count) { break; } }//这个是循环比较完每一个查询表达式与结果表达式的j从0开始 if (panduan2 == panduan1)//说明结果表达式里面至少有一个查询表达式,既然有的话,那就添加一下不就行了 { //Console.WriteLine("panduan2:"+panduan2+"panduan1:"+panduan1); //Console.WriteLine("第一次出现的j是多少:"+j); List <FinalNode1> tempList = new List <FinalNode1>(); for (int k = j; k < j + queryLaTeXAdjacentNodeList.Count; k++) { //Console.WriteLine("哪里超界限了:"+k); //Console.WriteLine("哪里超界限了:"+ resultLaTeXAdjacentNodeList[k].zifu); tempList.Add(resultLaTeXAdjacentNodeList[k]); } tempdic.Add(counts, tempList); counts++; i = 0; panduan2 = 0; } else//如果不相等的话,说明目前没找到 { i = 0; panduan2 = 0; continue; } //也就是说“p”是从结果表达式一个一个字符开始, //开始找和查询表达式具有相同首字符的时候,所以有的是从结果表达式快最后的时候 //才可能找到查询表达式的开始 if (p == resultLaTeXAdjacentNodeList.Count) { break; } } List <AAAAData> list = new List <AAAAData>(); return(tempdic); }//第一个指标:树的层次(高度)这个指标
}//第四个指标://这个是树的结构属性 public double OperateBTLevelAndType(String queryLaTeX, String resultLaTeX) { AABTreeStructure acquireBtreeStructure = new AABTreeStructure(); //调用这个类,获取树结构的类 List <FinalNode1> queryLaTeXAdjacentNodeList = new List <FinalNode1>(); //存放“查询表达式”邻接节点有序对的集合 List <FinalNode1> resultLaTeXAdjacentNodeList = new List <FinalNode1>(); //存放“结果表达式”邻接节点有序对的集合 queryLaTeXAdjacentNodeList = acquireBtreeStructure.AdjacentNodeList(queryLaTeX); //已经存放“查询表达式”邻接节点有序对的集合 resultLaTeXAdjacentNodeList = acquireBtreeStructure.AdjacentNodeList(resultLaTeX); //已经存放“结果表达式”邻接节点有序对的集合 /*//第一步:我先统计一下查询表达式树的深度(先用遍历的方法,以后如果慢的话,我再用递归,我先做出来再说!!!) * int queryLaTeXBTreeDepth = 0; * for (int i = 0; i < queryLaTeXAdjacentNodeList.Count; i++) * { * if (queryLaTeXAdjacentNodeList[i].BTreeLevel > queryLaTeXBTreeDepth) * { * queryLaTeXBTreeDepth = queryLaTeXAdjacentNodeList[i].BTreeLevel; * } * }*/ //我应该算结果表达式的二叉树对应的高度吧 int resultLaTeXBTreeDepth = 0; for (int i = 0; i < resultLaTeXAdjacentNodeList.Count; i++) { if (resultLaTeXAdjacentNodeList[i].BTreeLevel > resultLaTeXBTreeDepth) { resultLaTeXBTreeDepth = resultLaTeXAdjacentNodeList[i].BTreeLevel; } } //===================先在这按照二叉树所有节点,按照树的高度进行排序============================== FinalNode1 tempdata = new FinalNode1(); for (int i = 0; i < queryLaTeXAdjacentNodeList.Count - 1; i++) { for (int j = i + 1; j < queryLaTeXAdjacentNodeList.Count; j++) { if (queryLaTeXAdjacentNodeList[j].BTreeLevel < queryLaTeXAdjacentNodeList[i].BTreeLevel) { tempdata = queryLaTeXAdjacentNodeList[j]; queryLaTeXAdjacentNodeList[j] = queryLaTeXAdjacentNodeList[i]; queryLaTeXAdjacentNodeList[i] = tempdata; } } } for (int i = 0; i < resultLaTeXAdjacentNodeList.Count - 1; i++) { for (int j = i + 1; j < resultLaTeXAdjacentNodeList.Count; j++) { if (resultLaTeXAdjacentNodeList[j].BTreeLevel < resultLaTeXAdjacentNodeList[i].BTreeLevel) { tempdata = resultLaTeXAdjacentNodeList[j]; resultLaTeXAdjacentNodeList[j] = resultLaTeXAdjacentNodeList[i]; resultLaTeXAdjacentNodeList[i] = tempdata; } } } //===================先在这按照二叉树所有节点,按照树的高度进行排序============================== //第二步:开始统计查询表达式对应二叉树的树的层次(用字典存储)(其实可以层次遍历二叉树的,到时候再说,先做出来) Dictionary <int, List <FinalNode1> > queryDictionary = new Dictionary <int, List <FinalNode1> >(); for (int j = 0; j < queryLaTeXAdjacentNodeList.Count; j++) { //遍历查询表达式邻接节点有序对,开始对每一个节点进行判断,如果某一个节点是运算符的话, if (isOperator(queryLaTeXAdjacentNodeList[j].zifu)) { if (queryDictionary.Count == 0) { //这个是添加的第一个元素 List <FinalNode1> lists = new List <FinalNode1>(); lists.Add(queryLaTeXAdjacentNodeList[j]); queryDictionary.Add(queryLaTeXAdjacentNodeList[j].BTreeLevel, lists); continue; } //如果下一个是运算符,并且树的层次之前有出现了,那就把它再添加到对应后面 if (queryDictionary.ContainsKey(queryLaTeXAdjacentNodeList[j].BTreeLevel)) { queryDictionary[queryLaTeXAdjacentNodeList[j].BTreeLevel].Add(queryLaTeXAdjacentNodeList[j]); } //如果下一个树的层次没有,那么,就添加进去 else { List <FinalNode1> lists = new List <FinalNode1>(); lists.Add(queryLaTeXAdjacentNodeList[j]); queryDictionary.Add(queryLaTeXAdjacentNodeList[j].BTreeLevel, lists); } } } /*foreach (var it in queryDictionary) * { * Console.WriteLine("查询表达式的树的层次================"+it.Key); * }*/ //第三步:开始统计结果表达式对应二叉树的树的层次(用字典存储) Dictionary <int, List <FinalNode1> > resultDictionary = new Dictionary <int, List <FinalNode1> >(); for (int j = 0; j < resultLaTeXAdjacentNodeList.Count; j++) { //遍历查询表达式邻接节点有序对,开始对每一个节点进行判断,如果某一个节点是运算符的话, if (isOperator(resultLaTeXAdjacentNodeList[j].zifu)) { if (resultDictionary.Count == 0) { //这个是添加的第一个元素 List <FinalNode1> lists = new List <FinalNode1>(); lists.Add(resultLaTeXAdjacentNodeList[j]); resultDictionary.Add(resultLaTeXAdjacentNodeList[j].BTreeLevel, lists); continue; } //如果下一个是运算符,并且树的层次之前有出现了,那就把它再添加到对应后面 if (resultDictionary.ContainsKey(resultLaTeXAdjacentNodeList[j].BTreeLevel)) { resultDictionary[resultLaTeXAdjacentNodeList[j].BTreeLevel].Add(resultLaTeXAdjacentNodeList[j]); } //如果下一个树的层次没有,那么,就添加进去 else { List <FinalNode1> lists = new List <FinalNode1>(); lists.Add(resultLaTeXAdjacentNodeList[j]); resultDictionary.Add(resultLaTeXAdjacentNodeList[j].BTreeLevel, lists); } } } /*foreach (var it in resultDictionary) * { * Console.WriteLine("结果表达式树的高度:"+it.Key); * }*/ //======================================排序啊,排序前======================================= ////我先查看一下字典里面的层次 //foreach (var it in queryDictionary) //{ // Console.WriteLine("查询字典是啥:"+it.Key); //} //foreach (var it in resultDictionary) //{ // Console.WriteLine("结果字典是啥:"+it.Key); //} /*第四步:开始统计查询表达式从第一层到最后一层, * 查询表达式每一层运算符的节点个数,在结果表达式每一层找到的运算符相同的个数 * 除以结果表达式对应该层的运算符的总个数的比值,再乘以1-层次除以结果表达式树的层次高度 */ //设置一个存放每一层分数的集合 List <double> scoreList = new List <double>(); //下面这个是开始遍历查询表达式的每一层,假如现在是第一层,也就是第一个元素 for (int i = 0; i < queryDictionary.Count; i++) { //这里在每一层设置一个计算相同运算符或者相同类型运算符的个数的计数工具 int SameBTLevelCount = 0; //注释一下,我怕那个了,此时这个i是查询表达式的高度(或者说元素序号) //如果查询表达式的高度大于结果表达式,比如查询表达式现在 //比如查询表达式高度为5,此时i取0-4,结果表达式也应该是0-4, //结果表达式高度为3,但是此时结果表达式高度为0-2,所以当i取3也就是 //i等于resultDictionary.count时,直接结束 if (i == resultDictionary.Count) { break; } //下面就是i不等于 //下面这个是开始遍历查询表达式每一层的节点, //用集合存储,可能很多,以第一层为例,也就是说遍历第一层的每一个节点 //去和结果表达式里面的每一层去比较“是否相同或者是否是同类运算符” for (int j = 0; j < queryDictionary[i + 1].Count; j++) { //上面这个对于查询表达式每一层的每一个节点,要去结果表达式里面 //去和结果表达式里面的每一个节点进行比较,看看是否相同 //Console.WriteLine("草拟吗傻逼:"+i); for (int k = 0; k < resultDictionary[i + 1].Count; k++) { //这里是相同的运算符或者相似的运算符 if (queryDictionary[i + 1][j].zifu.Equals(resultDictionary[i + 1][k].zifu)) { SameBTLevelCount++; } } } //第一层统计完相似的运算符的个数之后,开始计算该层的分数,就以第一层为例 double BTLevelSum = Convert.ToDouble(resultDictionary[i + 1].Count); //结果表达式中第一层运算符的节点的总个数 double b = Convert.ToDouble(SameBTLevelCount) / BTLevelSum; //结果表达式中,与查询表达式相似的运算符的个数除以结果表达式的总个数 //该层相同的节点数不是唯一决定因素,还得乘以所在层次的高度这个权值,占的比重大 double c = Convert.ToDouble(i + 1); //结果表达式的层次为 i + 1 double d = Convert.ToDouble(resultLaTeXBTreeDepth); //结果表达式里面对应二叉树的总高度 //double BTLevelQuanZhong = 1 - c/d; //树的每一层,所有层的总和 int a = 0; for (int j = 1; j <= resultLaTeXBTreeDepth; j++) { a = a + j; } double BTLevelZongHe = Convert.ToDouble(a);//树的每一层的总和 //结果表达式树的高度不就是结果表达式那个字典里面的总个数么,还用遍历然后计算最大值啊!!!不用呢!(哎呀不对,我这个字典里面存的是树的运算符的层次,不是完整的二叉树啊) //double BTreeHeight = Convert.ToDouble(resultDictionary.Count); double BTreeHeight = resultLaTeXBTreeDepth;//这个才是结果表达式二叉树的最大高度,我在最上面遍历了一下所有节点,找到高度最大的那个 double BTLevelQuanZhong = (BTreeHeight - (i + 1) + 1) / BTLevelZongHe; double BTLevelScore = b * BTLevelQuanZhong;//这个是该层的相似运算符的个数和所在层次的权重相乘的得分 scoreList.Add(BTLevelScore); //Console.WriteLine("每层相似节点的个数:"+SameBTLevelCount); //Console.WriteLine("每层结果表达式节点总个数:"+BTLevelSum); //Console.WriteLine("树的高度,也就是最大层次为:"+BTreeHeight); //Console.WriteLine("树的每一层加起来比如1+2+...总和:"+BTLevelZongHe); //Console.WriteLine("结果表达式二叉树节点高度:"+d); //Console.WriteLine("每层权重:"+BTLevelQuanZhong); //Console.WriteLine("================================"); } double finalScore = 0; //把每一层高度的分数的和遍历打印一下,看看弄的对不对 foreach (var it in scoreList) { finalScore = finalScore + it; //Console.WriteLine("看看每一层的分数算的对不对:"+it); } //Console.WriteLine("运算符层次和类型最终分数:"+finalScore); return(finalScore); }//第五个
}//第一个指标:树的层次(高度)这个指标 //其次是,所包含查询表达式的个数越多越相似 public double childrenCountScore(String queryLaTeX, String resultLaTeX) { AABTreeStructure acquireBtreeStructure = new AABTreeStructure(); //调用这个类,获取树结构的类 List <FinalNode1> queryLaTeXAdjacentNodeList = new List <FinalNode1>(); //存放“查询表达式”邻接节点有序对的集合 List <FinalNode1> resultLaTeXAdjacentNodeList = new List <FinalNode1>(); //存放“结果表达式”邻接节点有序对的集合 queryLaTeXAdjacentNodeList = acquireBtreeStructure.AdjacentNodeList(queryLaTeX); //已经存放“查询表达式”邻接节点有序对的集合 resultLaTeXAdjacentNodeList = acquireBtreeStructure.AdjacentNodeList(resultLaTeX); //已经存放“结果表达式”邻接节点有序对的集合 //=====这个方法一开始只是默认查询表达式是结果表达式的子式,但是如果查询表达式不是结果表达式的子式,那就不能用这个指标了======================= //艹艹艹艹艹艹艹艹艹我一开始没想那么多,“默认查询表达式比结果表达式长度小,但是实际上不是这样的”都是从简单入手,然后慢慢用其它例子来测试,然后调BUG,不过一开始确实难受 //如果查询表达式的长度“大于”结果表达式的长度,那说明一定没有包含,那就更别说是查询表达式在结果表达式中的个数了,所以此时该指标得分为0 if (queryLaTeXAdjacentNodeList.Count > resultLaTeXAdjacentNodeList.Count) { return(0); } //=====这个方法一开始只是默认查询表达式是结果表达式的子式,但是如果查询表达式不是结果表达式的子式,那就不能用这个指标了======================= //我先算一下查询表达式的树在结果表达式的树中的高度 List <FinalNode1> tempList = new List <FinalNode1>(); int panduan1 = queryLaTeXAdjacentNodeList.Count;//这个是查询表达式的节点的个数 int panduan2 = 0; int i = 0; int p = 0; int count1 = 0; //我想的是既然是包含匹配,查询表达式的个数,以及下面这个,这个占0.8,不一定非得仅仅包含比如a+b,有很多虽然包含a+b,但是其它部分可能就杂乱无章了,这就没考虑到 int count2 = 0; //以及其它与查询表达式具有相同节点的个数,分成两个比重,这个占0.2,可以“起到扩充的效果”,或者更能接近用户想要的,去除一些无关的节点,比如虽然包含a+b,但是后面跟了一连串的没用的什么欧拉公式,这就不好了,可以起到更加接近用户需求 //第一、下面这个是求查询表达式在结果表达式中的个数 for (int j = 0; j < resultLaTeXAdjacentNodeList.Count; j++) { p = j; while (i != queryLaTeXAdjacentNodeList.Count) { //Console.WriteLine("查询表达式集合:" + i); //Console.WriteLine("查询表达式总共个数:" + queryLaTeXAdjacentNodeList.Count); //Console.WriteLine("结果表达式集合:" + p); //Console.WriteLine("结果表达式总共个数:" + resultLaTeXAdjacentNodeList.Count); //Console.WriteLine("=============================="); if (queryLaTeXAdjacentNodeList[i].zifu.Equals(resultLaTeXAdjacentNodeList[p].zifu)) { i++; p++; panduan2++; } else//一旦有不相等的,说明肯定不相等,那就直接终止循环 { //这里得添加一个标志吧,直接结束 panduan2 = 0; break; } //这里P的结果表达式可能会超界,因为我已开始定义的是“i”,一开始我的界限是i不超出就行了,还得考虑p不超出 //这里p标记的是在结果表达式里面,与查询表达式第一个字母相同的字母的位置, //从结果表达式里面该位置开始找与查询表达式对应字母相同的, //就是向后过滤,扫描一个一个去比较,我都不知道怎么就想到了,但是放在现在我不一定能想到2020-1-30-20点59分 if (p == resultLaTeXAdjacentNodeList.Count) { break; } }//这个是循环比较完每一个查询表达式与结果表达式的j从0开始 if (panduan2 == panduan1)//说明结果表达式里面至少有一个查询表达式,既然有的话,那就添加一下不就行了 { count1++; i = 0; panduan2 = 0; } else//如果不相等的话,说明目前没找到 { i = 0; panduan2 = 0; //continue;//这里其实没必要放个continue继续吧,这都到最后了 } //这个和上面那个差不多吧 //也就是说“p”是从结果表达式一个一个字符开始, //开始找和查询表达式具有相同首字符的时候,所以有的是从结果表达式快最后的时候 //才可能找到查询表达式的开始 if (p == resultLaTeXAdjacentNodeList.Count) { break; } } //第二、找一下与查询表达式含有相同节点,但是又不属于包含的 for (int j = 0; j < resultLaTeXAdjacentNodeList.Count; j++) //遍历最外层,也就是结果表达式的节点,对于每一个节点 { for (int k = 0; k < queryLaTeXAdjacentNodeList.Count; k++) //查询表达式 { if (resultLaTeXAdjacentNodeList[j].zifu.Equals(queryLaTeXAdjacentNodeList[k].zifu)) { count2++; } } } double finalChildrenCountScore = 0; //查询表达式的节点个数 double queryCount = Convert.ToDouble((count1 * queryLaTeXAdjacentNodeList.Count)); //与查询表达式具有相同节点但是不包含查询表达式的个数 double temp = Convert.ToDouble(count2 - queryCount); //剩下的和查询表达式节点不相关的,也就是噪声节点 double other = Convert.ToDouble((resultLaTeXAdjacentNodeList.Count - count2)); finalChildrenCountScore = queryCount / resultLaTeXAdjacentNodeList.Count * 0.7 + Convert.ToDouble(temp) / resultLaTeXAdjacentNodeList.Count * 0.2 + other / resultLaTeXAdjacentNodeList.Count * 0.1; /*Console.WriteLine("查询表达式节点个数:"+queryCount); * Console.WriteLine("与查询表达式具有相同节点但是不包含查询表达式的个数:" + temp); * Console.WriteLine("剩下的无关噪声节点个数:" + other); * Console.WriteLine("结果表达式节点个数:" + resultLaTeXAdjacentNodeList.Count); * Console.WriteLine("分数:"+ queryCount / resultLaTeXAdjacentNodeList.Count * 0.7); * Console.WriteLine("分数:" + Convert.ToDouble(temp) / resultLaTeXAdjacentNodeList.Count * 0.2); * Console.WriteLine("分数:" + other / resultLaTeXAdjacentNodeList.Count * 0.1);*/ return(finalChildrenCountScore); }//第二个指标:查询表达式在结果表达式中的个数*0.8 + 与查询表达式节点相同的个数*0.2 这个指标
//也就是说我这个可以使包含匹配也可以是模糊匹配或者结构匹配,当没有包含匹配的时候 //就是结构匹配,所以提高了之前所存在的局限性,也就是说,如果没有包含那就打分为0,么 //到底怎么分类 //一、树的高度属性 //二、树型 匹配的子树和相似结点数量属性,两棵树匹配相同部分的属性 //三、树型结构属性(结构匹配) //四、这也算结构属性吧,运算符相似的个数再弄个运算符类型, //我突然明白了,就是判断两个表达式,比如查询表达式,要找到和查询表达式相似的表达式, //首先是包含的话是,是最匹配的,并且树的层次越接近根的话,以最接近根的那个为标准,就越相似,这是第一点 public double BTLevelScore(String queryLaTeX, String resultLaTeX) { AABTreeStructure acquireBtreeStructure = new AABTreeStructure(); //调用这个类,获取树结构的类 List <FinalNode1> queryLaTeXAdjacentNodeList = new List <FinalNode1>(); //存放“查询表达式”邻接节点有序对的集合 List <FinalNode1> resultLaTeXAdjacentNodeList = new List <FinalNode1>(); //存放“结果表达式”邻接节点有序对的集合 queryLaTeXAdjacentNodeList = acquireBtreeStructure.AdjacentNodeList(queryLaTeX); //已经存放“查询表达式”邻接节点有序对的集合 resultLaTeXAdjacentNodeList = acquireBtreeStructure.AdjacentNodeList(resultLaTeX); //已经存放“结果表达式”邻接节点有序对的集合 //=====这个方法一开始只是默认查询表达式是结果表达式的子式,但是如果查询表达式不是结果表达式的子式,那就不能用这个指标了======================= //如果查询表达式的长度“大于”结果表达式的长度,那说明一定没有包含,所以此时该指标得分为0 if (queryLaTeXAdjacentNodeList.Count > resultLaTeXAdjacentNodeList.Count) { return(0); } //=====这个方法一开始只是默认查询表达式是结果表达式的子式,但是如果查询表达式不是结果表达式的子式,那就不能用这个指标了======================= //我先算一下查询表达式的树在结果表达式的树中的高度 List <FinalNode1> tempList = new List <FinalNode1>(); int panduan1 = queryLaTeXAdjacentNodeList.Count;//这个是查询表达式的节点的个数 int panduan2 = 0; int i = 0; int p = 0; for (int j = 0; j < resultLaTeXAdjacentNodeList.Count; j++) { p = j; while (i != queryLaTeXAdjacentNodeList.Count) { //Console.WriteLine("查询表达式集合:" + i); //Console.WriteLine("查询表达式总共个数:" + queryLaTeXAdjacentNodeList.Count); //Console.WriteLine("结果表达式集合:" + p); //Console.WriteLine("结果表达式总共个数:" + resultLaTeXAdjacentNodeList.Count); //Console.WriteLine("=============================="); if (queryLaTeXAdjacentNodeList[i].zifu.Equals(resultLaTeXAdjacentNodeList[p].zifu)) { i++; p++; panduan2++; } else//一旦有不相等的,说明肯定不相等,那就直接终止循环 { //这里得添加一个标志吧,直接结束 panduan2 = 0; break; } if (p == resultLaTeXAdjacentNodeList.Count) { break; } }//这个是循环比较完每一个查询表达式与结果表达式的j从0开始 if (panduan2 == panduan1)//说明结果表达式里面至少有一个查询表达式,既然有的话,那就添加一下不就行了 { //Console.WriteLine("panduan2:"+panduan2+"panduan1:"+panduan1); //Console.WriteLine("第一次出现的j是多少:"+j); for (int k = j; k < j + queryLaTeXAdjacentNodeList.Count; k++) { //Console.WriteLine("哪里超界限了:"+k); tempList.Add(resultLaTeXAdjacentNodeList[k]); } i = 0; panduan2 = 0; } else//如果不相等的话,说明目前没找到 { i = 0; panduan2 = 0; continue; } //也就是说“p”是从结果表达式一个一个字符开始, //开始找和查询表达式具有相同首字符的时候,所以有的是从结果表达式快最后的时候 //才可能找到查询表达式的开始 if (p == resultLaTeXAdjacentNodeList.Count) { break; } } int BTreeLevel = 0;//这个是查询表达式在结果表达式中的最大高度,不对,应该找最小高度才行 for (int m = 0; m < tempList.Count; m++) { if (m == 0) { BTreeLevel = tempList[m].BTreeLevel; continue; } else { if (tempList[m].BTreeLevel < BTreeLevel) { BTreeLevel = tempList[m].BTreeLevel; } } } //现在求一下结果表达式的全部高度 int ALLBTreeLevel = 0;//这个是结果表达式的全部高度 for (int n = 0; n < resultLaTeXAdjacentNodeList.Count; n++) { if (resultLaTeXAdjacentNodeList[n].BTreeLevel > ALLBTreeLevel) { ALLBTreeLevel = resultLaTeXAdjacentNodeList[n].BTreeLevel; } } double finalBTLevelScore = 0; //Console.WriteLine("查询表达式在树中的高度:"+BTreeLevel+"结果表达式高度:"+ALLBTreeLevel); //如果“查询表达式”在“结果表达式”里面的树的高度为0,说明“查询表达式”根本就没有在“结果表达式里面”,所以返回为“0” if ((Convert.ToDouble(BTreeLevel) / Convert.ToDouble(ALLBTreeLevel)) == 0) { finalBTLevelScore = 0; } else { finalBTLevelScore = Convert.ToDouble((1 - Convert.ToDouble(BTreeLevel) / Convert.ToDouble(ALLBTreeLevel)).ToString("0.00")); } return(finalBTLevelScore); }//第一个指标:树的层次(高度)这个指标
public List <double> tfidf(String queryLaTeX) { AABTreeStructure acquireBtreeStructure = new AABTreeStructure(); //调用这个类,获取树结构的类 List <FinalNode1> queryLaTeXAdjacentNodeList = new List <FinalNode1>(); //存放“查询表达式”邻接节点有序对的集合 List <FinalNode1> resultLaTeXAdjacentNodeList = new List <FinalNode1>(); //存放“结果表达式”邻接节点有序对的集合 queryLaTeXAdjacentNodeList = acquireBtreeStructure.AdjacentNodeList(queryLaTeX); resultLaTeXAdjacentNodeList = acquireBtreeStructure.AdjacentNodeList(queryLaTeX); //我得先把查询表达式的“关键字”放入一个集合 //(那个徐彩云论文引用的英文论文里面有很多规定, //但是许彩云只只把“运算符”,“括号”,“子表达式作为关键字,到时候回去看那篇英文论文再添加再添加) List <String> queryLaTeXKeyWords = new List <String>(); //结果表达式关键字集合 List <String> resultLaTeXKeyWords = new List <String>(); Dictionary <int, List <FinalNode1> > children = new Dictionary <int, List <FinalNode1> >(); ChildrenBTree childrenBTree = new ChildrenBTree(); children = childrenBTree.childrenBTree(queryLaTeX); //foreach (var it in children) //{ // Console.WriteLine("KEY值:"+it.Key); // foreach (var itt in it.Value) // { // Console.WriteLine("值为:"+itt.zifu); // } // Console.WriteLine("====================================="); //} //================(我这里关键词只算了运算符,子式,没有算括号group,到时候还得把所有LaTeX以树形结点形式包含group放入数据库以便sql语句查找)=====下面写的代码是找到查询表达式里面的所有关键字,可以重复========================================= //首先先把里面的运算符作为关键字放入一个集合里面 foreach (var it in queryLaTeXAdjacentNodeList) { if (isOperator(it.zifu)) { queryLaTeXKeyWords.Add(it.zifu); } } //我这里子表达式是一个一个节点的,因为我要弄那个邻接节点有序对,所以是一个一个的节点, //但是我要把子表达式作为关键字,所以我得把一个一个的节点的字符“以字符串”的形式连接起来,真正作为一个关键字 foreach (var it in children) { String temp = ""; foreach (var itt in it.Value) { //Console.WriteLine("值为:" + itt.zifu); temp = temp + itt.zifu; } //获取到第一个子式关键字之后temp,然后装入集合 queryLaTeXKeyWords.Add(temp); //Console.WriteLine("====================================="); } //================================================上面写的代码是找到查询表达式里面的所有关键字,可以重复========================================= /*foreach (var it in queryLaTeXKeyWords) * { * Console.WriteLine("AATfIdf.cs:tfIdf集合关键字"+it); * }*/ //查询表达式每一个关键字在表达式中关键词中出现的次数 Dictionary <String, int> KeyWordsCount = new Dictionary <string, int>(); for (int i = 0; i < queryLaTeXKeyWords.Count; i++) { int a = 0; if (KeyWordsCount.Count == 0) { //如果一开始为空的话,就是出现一次 KeyWordsCount.Add(queryLaTeXKeyWords[i], 1); continue; } //现在开始去遍历专门存放关键字和次数的字典,查看有没有这个关键字 foreach (var it in KeyWordsCount) { if (queryLaTeXKeyWords[i].Equals(it.Key)) //说明有这个关键字 { a = 1; //说明有重复的关键字了 break; //KeyWordsCount[queryLaTeXKeyWords[i]]++; } } if (a == 1) { KeyWordsCount[queryLaTeXKeyWords[i]]++; } else { KeyWordsCount.Add(queryLaTeXKeyWords[i], 1); } } //===============下面里面的代码是我现在做实验临时弄的,这个是读取txt文本(我构建的临时数据集)(到时候读一下数据库数据集)里面的数学公式======================== Dictionary <String, String> txt = new Dictionary <String, String>(); StreamReader sr = new StreamReader("E:\\我要用的东西\\1我的论文2第二篇论文\\实验\\最终版组合测试添加数据用来修改的\\14最终版组合测试模糊匹配有点毛病啊,已解决14\\第二个实验测试数据\\1.txt", Encoding.Default); String read = sr.ReadLine(); while (read != null) { //Console.WriteLine("看看行不啊:"+read); String temp = ""; List <FinalNode1> List = new List <FinalNode1>(); //存放“查询表达式”邻接节点有序对的集合 List = acquireBtreeStructure.AdjacentNodeList(read); //已经存放“查询表达式”邻接节点有序对的集合 foreach (var it in List) { temp = temp + it.zifu; } txt.Add(read, temp); read = sr.ReadLine(); } sr.Close(); //===============上面里面的代码是我现在做实验临时弄的,这个是读取txt文本(我构建的临时数据集)(到时候读一下数据库数据集)里面的数学公式======================== //现在开始求每一个关键字的权值了,tf*idf int allKeyWordsCount = queryLaTeXKeyWords.Count(); //一个“查询表达式”中“所有关键字”的总次数 List <double> queryLaTeXtfIdfs = new List <double>(); //这个是放入所有关键字的最终权重值得集合,到时候计算相似度 foreach (var it in KeyWordsCount) { double tf = Convert.ToDouble(it.Value) / Convert.ToDouble(allKeyWordsCount); //===下面这两个权重到底是在数据库所有数学表达式呢,还是检索结果表达式里面的数学表达式呢?======= double LaTeXCount = txt.Count;//所有公式的数量 //===========包含关键词的数量(这是我临时测试关键词的数量)================ int tempCount = 0;//包含关键词的数量 foreach (var it1 in txt) { if (it1.Key.Contains(it.Key)) { tempCount++; } } //===========包含关键词的数量(这是我临时测试关键词的数量)================ //Console.WriteLine("包含关键词:"+it.Key + "数量为:"+tempCount); double ContainKeyWordLaTeXCount = tempCount;//包含关键词的数学公式的数量 double idf = Math.Log10(LaTeXCount / (1 + ContainKeyWordLaTeXCount)); double tfIdf = tf * idf;//现在这个算出来的是每一个关键字的权值 queryLaTeXtfIdfs.Add(tfIdf); } return(queryLaTeXtfIdfs); }