Python源代码文件相似性检测方法_2

文档序号:8269745阅读:来源:国知局
[0047] A9、读取Result字典,获取indexl行的最大相似跨度,并将indexl增加最大相似 跨度的步长;若当前行无相似行,则将indexl增加1 ;
[0048] 在步骤A9中重置indexl的值后,当indexl小于等于列表中最后一个元素编号 时,继续循环进行步骤A3-A9。
[0049] 假设,Result字典中记录的,与标号indexl行开始的若干行相似连续相似行,有5 行相似的,也有10行相似的,这时indexl行的最大相似跨度为10行,将indexl增加10行 的步长。
[0050] 这样,在大循环A3-A9中进行小循环A6-A8,就可以将各个代码行与其他代码行都 进行了相似性比较。
[0051] 用来检测同一个文件夹中所有Python源文件之间相似性的算法B为:
[0052] B1、将所述用户输入的文件夹中所有Python源文件内容读入至列表allFiles,列 表allFiles的每个元素是一个列表,每个列表中的第0个元素为文件名,第1个元素是包 含该文件所有代码行的列表;同时对读取的所有内容进行预处理,删除读取的所有内容中 的所有多余的空格、每行两端的空格以及行尾的换行符;
[0053] 即在读入后,文件夹中的每个文件为列表allFiles中的一个列表,每个列表中的 第0个元素为该文件的文件名,第1个元素是该文件的所有代码行。此处多余的空格与步 骤Al中多余的空格意义相同。
[0054] B2、从0开始,依次为列表allFiles中各个列表标号,令indexO = 0 ;进行步骤 B3-B13 ;
[0055] B3、从0开始依次为标号为indexO的列表中的元素标号,令indexl = 0 ;进行步 骤B4-B12 ;
[0056] B4、如果当前行已被判断为相似行,则跳过该行开始的所有连续相似行;
[0057] B5、如果当前行被判断为注释行,则跳过从当前行开始的所有连续注释行;
[0058] B6、选择标号为index3的列表,其中,index3 = indexO+Ι ;进行步骤B7-B11 ;
[0059] B7、从0开始依次为标号为index3的列表中的元素标号,令index2 = 0 ;进行步 骤B8-B10 ;
[0060] B8、如果当前行已被判断为相似行,则跳过该行开始的所有连续相似行;
[0061] B9、如果当前行被判断为注释行,则跳过从当前行开始的所有连续注释行;
[0062] B10、对比分别以indexl和index2开始的若干连续行相似性,如果符合相似性检 测标准,则更新Result字典,并将index2增加符合相似性检测标准的连续行的步长;否则 将index2增加1行;
[0063] 当index2小于等于编号为index3的列表最后一个元素编号时,继续进行步骤 B8-B10 ;
[0064] 这样循环进行步骤B8-B10,就可以将indexl所标识开始的若干连续行与index3 标识的列表中的所有行都进行了相似性对比。
[0065] B11、将index3增加1,当index3小于等于allFiles列表中最后一个元素编号时, 继续进行步骤B7-B11 ;
[0066] 这样,就可以将indexl所标识的行与剩余文件的列表中的所有行都进行了相似 性对比。
[0067] B12、读取Result字典,获取indexl行的最大相似跨度,并将indexl增加最大相 似跨度的步长;若当前行无相似行,则将indexl增加1 ;
[0068] 在步骤B12中重置indexl的值后,当indexl小于等于indexO的列表中的最后一 个元素编号时,继续循环进行步骤B4-B12。
[0069] B13、将indexO增加1,当indexO小于等于allFiles列表中最后一个元素编号时, 循环进行步骤B3-B13。
[0070] 在具体实现时,如果文件过多过大,为了避免占用太多内存,可以调整本算法为在 循环内部根据需要实时读取文件内容,通过增加文件的IO操作来节省内存占用。
[0071] 所述目标Python源文件与所述目标文件夹中所有Python源文件之间相似性的算 法C为:
[0072] C1、将所述用户输入的目标文件夹中所有Python源文件内容读入至目标列表 allFiles,目标列表allFiles的每个元素是一个列表,该列表的第0个元素为文件名,第1 个元素是包含该文件所有代码行的;列表;同时将所述用户输入的目标Python源文件内容 读入至目标列表currentFile ;对所有读入内容进行预处理,删除文件中所有多余的空格、 每行两端的空格以及行尾的换行符;
[0073] 这里文件夹和文件的读入可以参考步骤Al和Bl中的描述。
[0074] 此步为图2中的预处理。
[0075] C2、从0开始依次为目标列表currentFile中的元素标号,令indexl = 0 ;
[0076] 当indexl小于等于currentFile列表中最后一个元素编号时,进行步骤C3-C9 ;
[0077] 此步为图2中的indexl = 0。
[0078] C3、如果当前行被判断为注释行,则跳过从当前行开始的所有连续注释行;
[0079] C4、从0开始,依次为列表allFiles中各个列表标号,令index3 = 0 ;进行步骤 C5-C8 ;
[0080] 此步相当于图2中的"读取文件夹中的一个文件"。
[0081] C5、从0开始依次为标号为index3的列表中的元素标号,令index2 = 0 ;进行步 骤 C6-C7 ;
[0082] 此步为图2中的index2 = 0。
[0083] C6、如果当前行被判断为注释行,则跳过从当前行开始的所有连续注释行;
[0084] C7、对比分别以indexl和indeX2开始的若干连续行相似性,如果符合相似性检 测标准,则更新Result字典,并将index2增加符合相似性检测标准的连续行的步长;否则 index2增加1 ;若index3的列表中的元素还未检测完,则继续进行步骤C6-C7 ;
[0085] 此处为图2中的判断步:待测文件第indexl行开始与样本文件第index2行开始 是否存在连续相似行;以及判断后的2中情况的描述。若当前文本未遍历完,即index3的 列表中的元素还未检测完,则继续进行步骤C6-C7。
[0086] 这样循环进行步骤C6-C7,就可以将indexl所标识的行与index3标识的列表中的 所有行都进行了相似性对比。
[0087] C8、将index3增加1,当index3小于等于allFiles列表中最后一个元素编号时, 循环进行步骤C5-C8 ;
[0088] 此步为图2中的判断步,文件夹中是否还有未检测的文件,即是否所有的文件都 与indexl所标识的行对比完毕。
[0089] 这样循环进行步骤C5-C8 ;就可以将indexl所标识的行与文件夹中所有文件对应 的列表中的所有行都进行了相似性对比。
[0090] C9、读取Result字典,获取indexl行的最大相似跨度,并将indexl增加最大相似 跨度的步长;若当前行无相似行,则将indexl增加1 ;
[0091] 在步骤C9中重置indexl的值后,继续循环进行步骤C3-C9。
[0092] 算法C的主要思路,可以通过图2来描述,可以参考图2来理解算法3中的描述。
[0093] 从以上的算法描述上来看,这3个算法中有重复功能,而在应用本方法进行软件 编程时,可以将重复功能封装成函数,在需要的地方进行调用,从而减少重复代码,提高代 码复用度。
[0094] 在上述算法中,核心部分为相似性检测算法,根据不同的检测标准调用不同的子 算法,具体来说,相似性检测算法分为以下几种情况:
[0095] 1)如果相似性检测标准要求完全相等,则直接将分别以indexl和index2开始的 若干连续代码行进行比较是否精确相等,若精确相等则认为符合标准,否则认为不符合;
[0096] 2)如果要求两段代码中变量名具有一定的重合度或相似性,并以此作为代码相似 性标准,则需要首先提取类名、函数名、变量名等标识符以及运算符,并统计各自出现的频 率,将结果按标识符和运算符出现频率从高到低进行排序。如果标识符、运算符及其频率分 布达到一定相似性要求,则认为两段代码相似。本发明使用正则表达式进行提取标识符,主 要分为以下几种情况:
[0097] 类定义格式为:claSS类名[(基类名列表)]:,S卩,类名前有关键字class,其后 可能存在使用圆括弧包含的基类名列表,然后是一个英文冒号。因此提取类名可以使用正 则表达式'(? <=class\s)\w+(?=:)'。
[0098] 函数定义格式为:def函数名([参数名列表]):,S卩,函数名前有关键def,其后 为一对圆括弧,圆括弧内可能存在参数名列表,然后是一个英文冒号,有的函数不需要参 数,但是一对圆括号必须要有,如果有多个参数则使用逗号分隔开。使用'(? <=def\s) (\w+)\((·*? )\) (?=:)'进行匹配后,groupl即为函数名,gr〇up2即为参数列表。
[0099] 变量名的情况比较复杂一些,需要分成以下几种情况分别对待:
[0100] 普通变量:在Python中变量不需要事先声明,且为动态类型,当为变量名赋值时 若变量不存在
当前第2页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1