代码变种策略文档说明:
cpp/java:
1、替换if while for 中的运算符:
{
"+": ["-"],
"-": ["+"],
"<": [">", ">=", "<=", "=="],
">": ["<", ">=", "<=", "=="],
"<=": [">", ">=", "<", "=="],
">=": [">", "<=", "<", "=="],
"/": ["*"],
"==": ["!=", ">", "<", "<=", ">="],
"!=": ["==", ">", "<", "<=", ">="],
"++": ["--"],
"--": ["++"],
"&": ["|"],
"|": ["&"],
"&&": ["|", '!'],
"||": ["&", '!'],
"!": ['', '0 == ', '0 != ', '0 >= ', '0 <= ']
}
从代码中找出['\tif', '\tfor', '\twhile']
所在的行索引,替换这些代码行中包含的运算符
例子:
int main ()
{
int a = 100;
if( a < 20 )
{
a--
}
return 0;
}
首先找出可以变种的行索引为:3
将图中的 a < 20 变为:
a > 20
a >= 20
a <= 20
a == 20
将变种好的选项替换源代码中if
中的内容,作为侯选项。
2、从代码中寻找['\tif', '\twhile']
所在的行索引,两两交换if、while
中的判断条件:
int main ()
{
int a = 100;
if( a < 20 )
{
a--
}
if(a > 20)
{
a++
}
while(a < 0)
a=0
return 0;
}
取出可变种的行索引为:3、7、11
则会生成以下候选项:
int main ()
{
int a = 100;
if( a > 20 )
{
a--
}
if(a < 20)
{
a++
}
while(a < 0)
a=0
return 0;
}
int main ()
{
int a = 100;
if( a < 0 )
{
a--
}
if(a > 20)
{
a++
}
while(a < 20)
a=0
return 0;
}
int main ()
{
int a = 100;
if( a < 20 )
{
a--
}
if(a < 0)
{
a++
}
while(a < 20)
a=0
return 0;
}
int main ()
{
int a = 100;
if( a < 20 )
{
a--
}
if(a < 20)
{
a++
}
while(a < 0)
a=0
return 0;
}
int main ()
{
int a = 100;
if( a > 20 )
{
a--
}
if(a > 20)
{
a++
}
while(a < 0)
a=0
return 0;
}
int main ()
{
int a = 100;
if( a < 0 )
{
a--
}
if(a > 20)
{
a++
}
while(a < 0)
a=0
return 0;
}
int main ()
{
int a = 100;
if( a < 20 )
{
a--
}
if(a > 20)
{
a++
}
while(a < 20)
a=0
return 0;
}
int main ()
{
int a = 100;
if( a < 20 )
{
a--
}
if(a < 0)
{
a++
}
while(a < 0)
a=0
return 0;
}
int main ()
{
int a = 100;
if( a < 20 )
{
a--
}
if(a > 20)
{
a++
}
while(a > 20)
a=0
return 0;
}
原本3、7、11的顺序,变种后会生成
7、3、11
11、3、7
3、11、7
3、3、11
7、7、11
11、7、11
3、7、3
3、7、7
3、11、11
其中3、7、11代表的是if、while
中判断条件
3、若以上部分生成的候选项的数量小于3,则从以下列表中寻找可变种的索引:
['\tif', '\twhile', '\tcontinue', '\tbreak',
'->', '+', '%', '+=', '-=', '/=', '%=', '^=', '.pop', '.push']
找出索引后,然后替换一下字典中的关键字及运算符:
{
'if': ['while'],
'while': ['if'],
'break': ['continue'],
'continue': ['break'],
'.pop': ['.push'],
'.push': ['.pop'],
'->': ['.'],
'+': ['-', '*', '/', '%', '&', '&&', '|', '||'],
'%': ['+', '-', '*', '/', '&', '&&', '|', '||'],
'+=': ['-=', '/=', '%=', '^='],
'-=': ['+=', '/=', '%=', '^='],
'/=': ['+=', '-=', '%=', '^='],
'^=': ['+=', '-=', '/=', '%='],
}
例子:
int main ()
{
int a = 100;
if( a < 20 )
{
a = a - 1
}
if(a > 20)
{
a = a + 1
}
while(a < 0)
a=0
return 0;
}
将以上代码作为输入,则会得到可变种索引3、5、7、9、11
替换的规则与第一点一样,这里不再赘述。
python:
每日一题
python语言与java/cpp有比较大的不同,因此变种策略需要分开来写。但总体思路一致,只不过是寻找可变种索引的列表有些许不同。
python语言遵循以下变种策略
1、替换一些关键字及运算符:
从以下列表中寻找可替换索引
['\tif', '\twhile', '\tcontinue', '\tbreak',
'+', '-', 'and', 'or', 'not', '%', '+=',
'-=', '/=', '%=', '^=', '//', 'True', 'False']
得到索引后,从以下字典中替换,生成候选项:
{
' if ': [' while '],
' while ': [' if '],
'break': ['continue'],
'continue': ['break'],
' is ': [' is not '],
' is not ': [' is '],
' and ': [' or ', ' not '],
' or ': [' and ', ' not '],
' not ': [' and ', ' or '],
'True': ['False'],
'False': ['True'],
"<": [">", ">=", "<=", "==", '!='],
">": ["<", ">=", "<=", "==", '!='],
"<=": [">", ">=", "<", "==", '!='],
">=": [">", "<=", "<", "==", '!='],
"==": ["!=", ">", "<", "<=", ">="],
"!=": ["==", ">", "<", "<=", ">="],
'+': ['-', '*', '/', '%', '//'],
'%': ['+', '-', '*', '/', '//'],
'-': ['+', '*', '/', '%', '//'],
'/': ['-', '*', '+', '%', '//'],
'//': ['-', '*', '/', '%', '+'],
'+=': ['-=', '/=', '%=', '^=', '*=', ],
'-=': ['+=', '/=', '%=', '^=', '*='],
'/=': ['+=', '-=', '%=', '^=', '*='],
'^=': ['+=', '-=', '/=', '%=', '*=']
}
例子:
def test(line):
for c in line:
if c == '1':
break
提取出的可替换索引为:2、3
生成的候选项为:
def test(line):
for c in line:
if c != '1':
break
def test(line):
for c in line:
if c >= '1':
break
def test(line):
for c in line:
if c <= '1':
break
def test(line):
for c in line:
if c > '1':
break
def test(line):
for c in line:
if c < '1':
break
def test(line):
for c in line:
if c == '1':
continue
以上变种策略为每日一题的变种策略
技能树习题
对于习题,变种策略比每日一题多了一些,下面开始介绍:
1、替换
从以下列表中寻找可变种索引:
['\tif', 'while', '\tcontinue', '\tbreak',
'+', '-', 'and', 'or', 'not', '%', '+=',
'-=', '/=', '%=', '^=', '!=', '//', 'True', 'False',
'.extend', '.append', 'range', '\tfor', '\telif',
'.keys()', '.values()', '.findall', '.search',
'.compile', '.sub', '.match', '*', ' open',
'.read', '.write', 'else:', 'except:', 'try:', '__test', '_func']
可见,技能树习题的可替换列表比每日一题要多很多,主要是因为技能树习题基本都不是算法题,不能仅仅根据运算符变种
替换的字典:
{
'for': ['if', 'while'],
'if': ['while'],
'elif': ['if'],
'while': ['if'],
'else:': [''],
'break': ['continue', ''],
'continue': ['break', ''],
'self,': [''],
' is ': [' is not '],
' is not ': [' is '],
' and ': [' or ', ' not '],
' or ': [' and ', ' not '],
' not ': [' and ', ' or '],
'True': ['False'],
'False': ['True'],
'.append': ['.extend'],
'.extend': ['.append'],
'range': ['xrange'],
'.keys()': ['.values()'],
'.values()': ['.keys()'],
'except:': ['catch:', 'finally:', 'else:'],
'try:': ['try'],
'finally:': ['except:', 'else:'],
'findall': ['.search', '.compile', '.sub', '.match'],
'.search': ['.findall', '.compile', '.sub', '.match'],
'.compile': ['.search', '.findall', '.sub', '.match'],
'.sub': ['.search', '.compile', '.findall', '.match'],
'.match': ['.search', '.compile', '.sub', '.findall'],
'[]': ['{}'],
'{}': ['[]'],
"<": [">", ">=", "<=", "==", '!='],
">": ["<", ">=", "<=", "==", '!='],
"<=": [">", ">=", "<", "==", '!='],
">=": [">", "<=", "<", "==", '!='],
"==": ["!=", ">", "<", "<=", ">="],
"!=": ["==", ">", "<", "<=", ">="],
'+': ['-', '*', '/', '%', '//'],
'*': ['**', '+', '-', '/', '%', '//'],
'%': ['+', '-', '*', '/', '//'],
'-': ['+', '*', '/', '%', '//'],
'/': ['-', '*', '+', '%', '//'],
'//': ['-', '*', '/', '%', '+'],
'+=': ['-=', '/=', '%=', '^=', '*=', ],
'-=': ['+=', '/=', '%=', '^=', '*='],
'/=': ['+=', '-=', '%=', '^=', '*='],
'^=': ['+=', '-=', '/=', '%=', '*='],
'*=': ['+=', '-=', '/=', '%=', '^='],
'\'r\'': ['\'w\'', '\'rb\''],
'\'w\'': ['\'r\'', '\'rb\'', '\'wb\''],
'.read': ['.write', '.readline', '.readlines'],
'.write': ['.read', '.readline', '.readlines'],
'__test': ['_test', '__test__'],
'_func': ['__func'],
}
替换字典也比每日一题的多很多。
替换规则与前面的规则一致
2、备用策略:
基于上述策略,并不能将所有题都变种产生至少三个的候选项,因此,加入了一些备用策略:
-
.append 变成 +=
例子 a = [] b = 2 a.append(b) 变种后: a = [] b = 2 a+=b
-
改变for循环中变量的位置
例子 line = [1, 3, 5, 7] for i in line: print(i) 变种后 line = [1, 3, 5, 7] for line in i: print(i) 例子 line = [1, 3, 5, 7] for i in range(len(line)): print(i) 变种后 line = [1, 3, 5, 7] for len(line) in range(i): print(i)
-
修改continue、break的缩进
例子 x = [1,2,3] for i in x: if i == 2: break 变种后 x = [1,2,3] for i in x: if i == 2: break
-
交换函数名(未使用)
例子 def test1(): print('hello') def test(2): print('你好') test1() test2() 变种后 def test2(): print('hello') def test1(2): print('你好') test1() test2()
加入“以上都不对选项”
生成的候选项中,“以上都不对”
选项会随机出现在候选项中,一旦出现,一定是出现在最后一项。
若候选项中有“以上都不对”
选项时,前三个答案中有可能有正确答案,也有可能没有。
以上就是代码变种目前的使用的所有策略