正剧开始:
星历2016年03月12日 11:13:44, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[整式的乘法与因式分解]。
今天这部分功法的名字特别的长,内容也是特别的多。不过小伟不在乎。
[工程师阿伟]刚给小伟做了一件新玩具,来玩一玩吧;
这个是怎么出来的呢?是这样的:
<span style="font-size:18px;">function myDraw(xGlobal, yGlobal) { var config = new PlotConfiguration(); config.init(); config.setPreference(); var r = 15; config.setSector(1,1,1,1); //config.graphPaper2D(0, 0, r); //config.axis2D(0, 0,180); var s = [ 'a^[m]*a^[m] = (a*a*a*...*a) * (a*a*a*...*a)', '= a*a*...*a', '= a^[m+n]' ]; var x = -250, y = -100; var mathText = new MathText(); for (var i = 0; i < s.length; i++) { mathText.print(s[i], x, y); y += 50; } }</span>
<span style="font-size:18px;">/** * @usage 数学表达式,代数式的书写 * @author mw * @date 2016年03月12日 星期六 11:05:12 * @param * @return * */ function MathText() { //上标标记形式为...^[内容]... //分数不进行处理, 根式不进行处理,都转成指数式进行 //特殊数学符号设想加\[alpha]进行转义,待续 //可以进行指数上标代数式的书写 //可扩展下标,待续 this.setNormalFont = function() { plot.setFont("normal normal normal 24px Times New Roman"); } this.setScriptFont = function() { plot.setFont("italic normal normal 16px Arial Black"); } this.print = function(text, xPos, yPos) { xPos = xPos ? xPos : 0; yPos = yPos ? yPos : 0; plot.save(); var s = text ? text : 'undefined'; //字符串长度 var len = s.length; //不同字体大小设置在此 var r1 = 20; //单个字符暂存处 var c; //文本显示位置 var x = xPos, y = yPos; //正常文本暂存 var s0 = ''; //字符串打印长度 var measure; //设置正常字体 this.setNormalFont(); for (var i = 0; i < len; i++) { if (s[i] == '^') { //上标开始 //上标标记形式为...^[内容]... if (s0 != '') { //先把正常字符打印出 if (r1 != 20) { //字体字号大小还在上标状态 r1 = 20; this.setNormalFont(); } measure = plot.measureText(s0); plot.fillText(s0, x, y, measure); s0 = ''; x += measure; } var upperScript = ''; for (var j = i+1; s[j]!=']'; j++) { if (s[j] != '[') { upperScript+=s[j]; } } if (r1 != 10) {//正常字体状态,需要改为上标字体 r1 = 10; this.setScriptFont(); } measure = plot.measureText(upperScript); plot.fillText(upperScript, x, y-10, measure); x += 1.2*measure; //直接跳跃过上标字符区段 i = j; } else { c = s[i]; if (c == '*') { c = ' \u00B7 '; } s0 += c; } } if (s0 != '') { //先把正常字符打印出 if (r1 != 20) { //字体字号大小还在上标状态 r1 = 20; this.setNormalFont(); } measure = plot.measureText(s0); plot.fillText(s0, x, y, measure); x += measure; } plot.restore(); } }</span>
小伟想试着算一算,就又拿出了多项式的工具。
<span style="font-size:18px;">>>> ['x2x5', 'aa6'] 多项式x2x5 具有以下的项: ['x2x5'] 其中各单项分别是: 单项式x2x5 的系数是1, 次数是7,详细是[['x', 7]]。 合并同类项后详细情况是: [[1, 7, [['x', 7]]]] 合并同类项后是:x7 多项式aa6 具有以下的项: ['aa6'] 其中各单项分别是: 单项式aa6 的系数是1, 次数是7,详细是[['a', 7]]。 合并同类项后详细情况是: [[1, 7, [['a', 7]]]] 合并同类项后是:a7</span>
<span style="font-size:18px;"> var s = [ '(a^[m])^[n]', '= a^[m]*a^[m]*...*a^[m]', '= a^[m+m+...+m]', '= a^[mn]' ];</span>
<span style="font-size:18px;"> var s = [ '(ab)^[n]', '= (ab)*(ab)*...*(ab)', '= a*a*...*a*b*b*...*b', '= a^[n]b^[n]' ];</span>
<span style="font-size:18px;">['ac5bc3', '-12x2x-4x2', '0.333333ab2ab-abab'] 多项式ac5bc3 具有以下的项: ['ac5bc3'] 其中各单项分别是: 单项式ac5bc3 的系数是1, 次数是10,详细是[['a', 1], ['b', 1], ['c', 8]]。 合并同类项后详细情况是: [[1, 10, [['a', 1], ['b', 1], ['c', 8]]]] 合并同类项后是:abc8 多项式-12x2x-4x2 具有以下的项: ['-12x2x', '-4x2'] 其中各单项分别是: 单项式-12x2x 的系数是-12, 次数是3,详细是[['x', 3]]。 单项式-4x2 的系数是-4, 次数是2,详细是[['x', 2]]。 合并同类项后详细情况是: [[-12, 3, [['x', 3]]], [-4, 2, [['x', 2]]]] 合并同类项后是:-12x3-4x2 多项式0.333333ab2ab-abab 具有以下的项: ['0.333333ab2ab', '-abab'] 其中各单项分别是: 单项式0.333333ab2ab 的系数是0.333333, 次数是5,详细是[['a', 2], ['b', 3]]。 单项式-abab 的系数是-1, 次数是4,详细是[['a', 2], ['b', 2]]。 合并同类项后详细情况是: [[0.333333, 5, [['a', 2], ['b', 3]]], [-1, 4, [['a', 2], ['b', 2]]]] 合并同类项后是:0.333333a2b3-a2b2</span>
接着是多项式的除法:
<span style="font-size:18px;"> var s = [ '(a+b)(a-b)=a^[2]-b^[2]', '(a+b)^[2]=a^[2]+2ab+b^[2]', '(a-b)^[2]=a^[2]-2ab+b^[2]' ];</span>
活动1:
<span style="font-size:18px;"> var s = [ '(a+5)(a+5)', '=a*a+2*5*a+25', '=(a+10)a+25', '=(a/10)*(a/10+1)*100+25' ];</span>
<span style="font-size:18px;"> var s = [ '(a*10+b)(a*10+(10-b))', '=(a*10)^[2]+a*10*(b+10-b)+b*(10-b)', '=(a*10)^[2]+100*a+b*(10-b)', '=a*(a+1)*100+b*(10-b)', ];</span>
<span style="font-size:18px;">>>> 53*57 3021 >>> 95*95 9025 >>> 71*79 5609 >>> 38*32 1216 >>> 84*86 7224 >>> 58*52 3016 >>> 63*67 4221 >>> 75*75 5625</span>
<span style="font-size:18px;">### # @usage 单项式相关概念 # @author mw # @date 2016年02月26日 星期五 10:00:14 # @param # @return # ### #单项式 #可以有**, ^号,暂时只能处理代号为一个字母的式子,像x_1, x_n, ...这种还不能处理。 def monomial(s): #原始复本 s0 = s; s = s.replace('**', '^'); s = s.replace('*', ''); if (s.find('+') != -1 or (s.find('-') != -1 and s.find('-')!=0)): print(s0, '不是单项式。'); return []; try: #系数 sign = 1; if s[0] == '-': #负号 sign = -1; s = s[1:]; coefficient = 1; #字符串长度 length = len(s); index = 0; while (not s[index].isalpha()): index+=1; if index >= length: index = length; break; if (index > 0): coefficient = float(s[:index]); if abs(int(coefficient)-coefficient) < 0.001: coefficient = int(coefficient); s = s[index:]; coefficient = sign * coefficient; #系数为0的项,其实就是0 if (coefficient == 0): return []; #print(coefficient, s); length = len(s); array = []; result = []; if (length > 0): index = 0; index2 = 0; name = ''; degree = 0; while index < length: if s[index].isalpha(): if (name != ''): array.append([name, degree]); name = ''; degree = 0; name = s[index]; degree = 1; index += 1; else: index2 = index; tmp = ''; while (not s[index2].isalpha()): index2+=1; if (index2 >= length): index2 = length; break; tmp = s[index:index2]; tmp = tmp.replace('^', ''); degree = float(tmp); if abs(int(degree)-degree) < 0.001: degree = int(degree); index = index2; if (name != ''): array.append([name, degree]); name = ''; degree = 0; #print(array); #所有字母,去除重复的 setA = set(); size = len(array); #单项式的次数 totalDegree = 0; for i in range(size): setA.add(array[i][0]); totalDegree += array[i][1]; listA = list(setA); listA.sort(); size2 = len(listA); result = []; for i in range(size2): #计算每个字母的次数(degree) tmp = 0; for j in range(size): if listA[i] == array[j][0]: tmp += array[j][1]; result.append([listA[i], tmp]); print('单项式{0} 的系数是{1}, 次数是{2},详细是{3}。'.format(\ s0, coefficient, totalDegree, result)); else: totalDegree = 0; if (coefficient != 0): print('单项式{0} 的系数是{1}, 次数是{2},'.format(\ s0, coefficient, 0)); else: print('这个数是0, 暂无规定。'); #返回单项式的次数 return [coefficient, totalDegree, result]; except: print(s0, '有误,无法正确计算。'); ### # @usage 多项式相关概念 # @author mw # @date 2016年02月26日 星期五 10:30:37 # @param 如果有括号,需要先自行去除, # @return # ### def polynomial(s): if (s == ''): return; #预留复本 s0 = s; #只能有+或-号连接各项,不能有括号,分数要先化成小数 s = s.replace('-', '+-'); if (s[0] == '+'): s = s[1:]; #各项 terms = s.split('+'); print('多项式{0} 具有以下的项: {1}\n其中各单项分别是:'.format(s0, terms)); try: size = len(terms); array = []; for i in range(size): #此处也可扩展单项的合法性检查。 if (terms[i] == ''): pass; else: tmp = monomial(terms[i]); #对于返回[]的项,剔除掉 if len(tmp)>0: array.append(tmp); #print(array); size2 = len(array); for i in range(size2): #判断系数是否是0 if array[i][0] == 0: continue; for j in range(i+1, size2): if array[j][0] == 0: continue; else: if (sameTerm(array[i], array[j])): #合并同类项 array[i][0]+=array[j][0]; array[j][0] = 0; result = []; for i in range(size2): #判断系数是否是0 if array[i][0] == 0: continue; else: #保留三位小数 array[i][0] = round(array[i][0], 6); result.append(array[i]); print('合并同类项后详细情况是:', result); sResult = ''; size3 = len(result); if (size3)>0: for i in range(size3): tmp1 = result[i][0]; if (tmp1 >= 0): if (tmp1 != 1): sResult += '+'+str(tmp1); else: sResult += '+'; if (tmp1 < 0): if (tmp1!=-1): sResult += str(tmp1); else: sResult += '-'; tmp2 = result[i][2]; length = len(tmp2); if (length == 0 and abs(tmp1)==1): sResult += '1'; else: for j in range(length): if tmp2[j][1] != 1: sResult += tmp2[j][0]+str(tmp2[j][1]); else: sResult += tmp2[j][0]; if sResult[0] == '+': sResult = sResult[1:]; else: #所有项的系数刚好抵消,导致结果为0 sResult = '0'; print('合并同类项后是:{0}\n\n'.format(sResult)); except: print(s0, '有误,无法进行多项式操作。'); return; #同类项判断 def sameTerm(a, b): #由于a, b具有以下格式[1, 1, [['v', 1]]] [系数, 次数, 详细元素] if (a[1] == 0 and b[1] == 0): return True; if (a[1] != b[1]): #次数不同 return False; if (len(a[2]) != len(b[2])): #元素个数不同 return False; a1 = list(a[2]); b1 = list(b[2]); a1 = sorted(a1, key=lambda num:num[0]); b1 = sorted(b1, key=lambda num:num[0]); size = len(a1); for i in range(size): if a1[i][0] != b1[i][0] or a1[i][1] != b1[i][1]: return False; return True; ### # @usage 代数式,可以对系数中含计算式的情况进行计算,得出简化后的多项式字符串 # @author mw # @date 2016年02月27日 星期六 09:23:44 # @param # @return # ### #代数式 def algExpr(s): s0 = s; #判断字符串中左右括号是否匹配 if s.count('(') - s.count(')') != 0: print(s, '左右括号数目不匹配,表达式有误。'); return ''; #去除空格 s = s.replace(' ', ''); #存放需要计算的表达式子串 sub = ''; length = len(s); #新字符串 sNew = ''; #括号层次 bracket = 0; result = []; #需要计算的部分,是从每一个单项的开始处,一般只需要计算系数 need = 1; #精度 precision = 6; #遍历字符串s i = 0; while i < length: if (s[i] == '('): bracket+=1; sub += s[i]; elif (s[i] == ')'): bracket -=1; sub += s[i]; elif (s[i].isalpha()): if sub != '': if (sub[-1]=='*'): sub=sub[:-1]; sNew += str(round(eval(sub), precision))+ s[i]; sub = ''; else: sNew += s[i]; #由于字母后面是次数,不需要计算 #need = 0; elif (s[i] == '+' or s[i] == '-'): if (bracket == 0): if sub != '': if (sub[-1]=='*'): sub=sub[:-1]; sNew += str(round(eval(sub), precision))+ s[i]; sub = ''; else: sNew += s[i]; #need = 1; else: sub += s[i]; else: if (need == 1): sub += s[i]; else: sNew += s[i]; i += 1; if sub != '': if (sub[-1]=='*'): sub=sub[:-1]; sNew += str(round(eval(sub), precision)); sub = ''; #print(sNew); return sNew; def tmp(): a = ['ac5bc3', '-12x2x-4x2', '1/3ab2ab-abab']; size = len(a); for i in range(size): a[i] = algExpr(a[i]); print(a); for i in range(size): #print('<{0}>\n'.format(i+1)); polynomial(a[i]); return; </span>