剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第八转的修炼。设想一个场景:
如果允许你带一台不连网的计算机去参加高考,你会放弃选择一个手拿计算器和草稿本吗
?阿伟决定和小伟来尝试一下用计算机算高考题会是怎样的感觉。


本节到此结束,欲知后事如何,请看下回分解。
[机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第八转的修炼。设想一个场景:
如果允许你带一台不连网的计算机去参加高考,你会放弃选择一个手拿计算器和草稿本吗
?阿伟决定和小伟来尝试一下用计算机算高考题会是怎样的感觉。
正剧开始:
星历2016年05月25日 10:40:52, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起做着2012年的江苏省数学高考题]。
这就是传说中的厄尔斯星球末日那一年的考题,这一年的考题难度绝对是在5.5环以上。
可以从上表中看到,由于连续三年难度达到5.5环以上,说明江苏的考卷已经是铁了心要走残酷模式了,
不再像以前那样容易三年难一年,正弦曲线式的遮遮掩掩的难。
这张卷子的素材刚好是答案和题粘在一起,而阿伟又刚好懒得去把它分开,毕竟何必和自己过不去呢,
高考离阿伟已经很遥远了,咱只是观光一下而已啦。
<span style="font-size:18px;">#题22B
def tmp22B():
A_ = [[-1/4, 3/4], [1/2, -1/2]];
A = np.linalg.inv(A_);
print(A);
#求特征值
eig = np.linalg.eig(A);
print(eig);
>>>
[[ 2. 3.]
[ 2. 1.]]
(array([ 4., -1.]), array([[ 0.83205029, -0.70710678],
[ 0.5547002 , 0.70710678]]))
</span>
卷子贴完了,但阿伟这次主要是想做一个测试,测试这样一个题:
这个图如下:
怎样解呢?
<span style="font-size:18px;">#测试
def tmp():
#先化出x^[2]/4
x = alg.strformat(['y^[-1]', '-1']);
x2 = alg.strcombine(alg.strpow_n(x, 2));
print(x2);
x2 = alg.strscale(x2, '1/4');
print('step1: ', x2);
expr = alg.strcombine(alg.stradd(x2, alg.strformat(['0.5y^[2]', '-1'])));
print('step2: ', expr);
solve = StringAlgSolve();
poly_y = solve.coefPoly(expr, 'y');
print('step3: ', poly_y);
roots = np.roots(poly_y);
print('step4: ', roots);
points = [];
for i in range(len(roots)):
real = roots[i].real;
abs_ = abs(roots[i]);
#实数根
if abs(real-abs_) < 0.001:
y = roots[i];
points.append([1/y-1, y]);
print('step6: ', points);
>>>
['(1)*y^[-2]', '(-2)*y^[-1]', '(1)']
step1: ['(0.25)*y^[-2]', '(-0.5)*y^[-1]', '(0.25)']
step2: ['(0.25)*y^[-2]', '(-0.5)*y^[-1]', '(-0.75)', '(0.5)*y^[2]']
step3: [0.5, '0', -0.75, -0.5, 0.25]
step4: [ 1.39972286+0.j -0.86985159+0.54226114j -0.86985159-0.54226114j
0.33998033+0.j ]
step6: [[(-0.28557285734613158+0j), (1.399722855272995+0j)], [(1.9413466331266509+0j), (0.33998033034855202+0j)]]
</span>
<span style="font-size:18px;"> if (1) {
var r = 20;
config.setSector(1,1,1,1);
config.graphPaper2D(0, 0, r);
config.axis2D(0, 0,180);
//坐标轴设定
var scaleX = 2*r, scaleY = 2*r;
var spaceX = 0.4, spaceY = 0.4;
var xS = -10, xE = 10;
var yS = -10, yE = 10;
config.axisSpacing(xS, xE, spaceX, scaleX, 'X');
config.axisSpacing(yS, yE, spaceY, scaleY, 'Y');
var transform = new Transform();
//存放函数图像上的点
var a = [], b = [], c = [], d = [];
//需要显示的函数说明
//希腊字母表(存此用于Ctrl C/V
//ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ
//αβγδεζηθικλμνξοπρστυφχψω
var f1 = 'x^[2]/4+y^[2]/2 = 1', f2 = 'y = 1/(1+x)', f3 = '', f4 = '';
//函数描点
//参数方程
var x, y;
var pointA = [];
for (var thita = 0; thita < Math.PI*2; thita +=Math.PI/48) {
x = 2*Math.cos(thita);
a.push([2*Math.cos(thita), 1.414*Math.sin(thita)]);
b.push([x, 1/(1+x)]);
}
//存放临时数组
var tmp = [];
//显示变换
if (a.length > 0) {
a = transform.scale(transform.translate(a, 0, 0), scaleX/spaceX, scaleY/spaceY);
//函数1
tmp = [].concat(a);
shape.pointDraw(tmp, 'red');
tmp = [].concat(a);
shape.multiLineDraw(tmp, 'pink');
plot.setFillStyle('red');
plot.fillText(f1, 100, -120, 200);
}
//显示变换
if (b.length > 0) {
b = transform.scale(transform.translate(b, 0, 0), scaleX/spaceX, scaleY/spaceY);
//函数1
tmp = [].concat(b);
shape.pointDraw(tmp, 'blue');
tmp = [].concat(b);
shape.multiLineDraw(tmp, '#0088FF');
plot.setFillStyle('blue');
plot.fillText(f2, 100, -150, 200);
}
}
</span>
<span style="font-size:18px;"> //测试
if (1) {
var mathText = new MathText();
//希腊字母表(存此用于Ctrl C/V
//ΑΒΓΔΕΖΗ ΘΙΚΛΜΝΞ ΟΠΡ ΣΤΥ ΦΧΨ Ω
//αβγδεζη θικλμνξ οπρ στυ φχψ ω
//希腊大小写字母
var Gc = 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ';
var Gs = 'αβγδεζηθικλμνξοπρστυφχψω';
var s = [
/*
'测试',
'y = 1/(x+1) _[(1)]',
'x^[2]/4+y^[2]/2 = 1 _[(2)]',
'求交点',
'由_[(1)]得 x = y^[-1]-1, 代入_[(2)]式',
'step1: 先化出x^[2]/4',
'step2: 把_[(2)]整理完全',
'step3: 把step2所得表达式转入参数y的幂次多项式',
'step4: 求幂次多项式的根',
'step5: 上一步解得y=1.4 或 0.34,代入求x',
'step6:得两个点: [-0.286, 1.4], [1.94, 0.34]',
'step7:画图验证',
'这个题是可以这样解决了,大家可见下面的解答。',*/
'那么如果上面 _[(1)]式是 y = 1/(x+1)+1呢,',
'这就不是简单多项式了。这种还好办,',
'可以作一个y-1 = y_[2]的变换,只是麻烦点。',
'那如果是两个二次式联立呢?或者高于二次呢?',
'这个[机器小伟]现在是解不了的了。',
'是不是除了用数值计算方法以外别无选择?',
'民间有高人,阿伟很期待。'
];
var x =40, y=40;
var r1 = 40;
var len = s.length;
for (var i = 0; i < len; i++) {
if (s[i] == '') {
if (x < 100) {
x += 300;
y-=r1*3;
}
else {
x = 20;
y += r1;
}
}
else {
mathText.print(s[i], x, y, 'red', '|');
y+=r1;
}
}
}
</span>
这里贴出相关的工具,作为大家的一个起点吧,
很多以前贴过,但是改了里面几个小Bug:
<span style="font-size:18px;">###
# @usage 代数式字符串的运算
# @author mw
# @date 2016年05月17日 星期二 16:48:56
# @param
# @return
#
###
#计算代数式用, 传入的是单项式,返回coef*expr的形式
def strmono(s):
#'x', '-x', '2x', '-2x', '-2x^[2]', '3x_[2]^[3]', '-3x_[2]^[3]'
stmp = s;
size = len(stmp);
alphaIndex = 0;
signIndex = 0;
for i in range(size):
if (stmp[i].isalpha()):
alphaIndex = i;
break;
if (i >= size-1):
alphaIndex = i+1;
if (stmp[0] == '-'):
signIndex = 1;
if (signIndex >= alphaIndex):
return monoformat('(-1)*'+stmp[alphaIndex:]);
else:
if alphaIndex >= size:
return monoformat('(-'+stmp[signIndex:alphaIndex]+')');
return monoformat('(-'+stmp[signIndex:alphaIndex]+')*'+stmp[alphaIndex:]);
elif (stmp[0] == '('):
#已经格式化的情况,这种情况输入时是(coef)*expr
return monoformat(stmp);
else:
signIndex = 0;
if (signIndex >= alphaIndex):
return monoformat('(1)*'+stmp[alphaIndex:]);
else:
if alphaIndex >= size:
return monoformat('('+stmp[signIndex:alphaIndex]+')');
return monoformat('('+stmp[signIndex:alphaIndex]+')*'+stmp[alphaIndex:]);
#计算两个单项式的乘积
def strmul(mono1, mono2):
#这个处理是保证每个单项式统一格式(coef)*expr
'''
if (mono1[0] != '(' or mono2[0] != '('):
#如果没有规格化,那么就做一下
mono1 = strmono(mono1);
mono2 = strmono(mono2);
'''
stmp1 = mono1;
stmp2 = mono2;
#乘号的位置
signIndex1 = stmp1.find('*');
signIndex2 = stmp2.find('*');
if (signIndex1 == -1):
coef1 = stmp1;
expr1 = '';
else:
coef1 = stmp1[:signIndex1];
expr1 = stmp1[signIndex1+1:];
if (signIndex2 == -1):
coef2 = stmp2;
expr2 = '';
else:
coef2 = stmp2[:signIndex2];
expr2 = stmp2[signIndex2+1:];
coef = coef1+'*'+coef2;
if (signIndex1 == -1 or signIndex2 == -1):
expr = expr1+expr2;
else:
expr = expr1+'*'+expr2;
if (expr == ''):
return '('+str(round(eval(coef), 6))+')';
return '('+str(round(eval(coef), 6))+')*'+expr;
#计算两个单项式的商
def strdiv(s1, s2):
#这个处理是保证每个单项式统一格式(coef)*expr
stmp1 = strmono(s1);
stmp2 = strmono(s2);
#乘号的位置
signIndex1 = stmp1.find('*');
signIndex2 = stmp2.find('*');
if (signIndex1 == -1):
coef1 = stmp1;
expr1 = '';
else:
coef1 = stmp1[:signIndex1];
expr1 = stmp1[signIndex1+1:];
if (signIndex2 == -1):
coef2 = stmp2;
expr2 = '';
else:
coef2 = stmp2[:signIndex2];
expr2 = stmp2[signIndex2+1:];
coef = coef1+'/'+coef2;
if (signIndex1 == -1 and signIndex2 != -1):
expr = '('+expr2+')^[-1]';
elif (signIndex1 == -1 or signIndex2 == -1):
expr = expr1+expr2;
else:
expr = expr1+'/'+expr2;
if (expr == ''):
return '('+str(round(eval(coef), 6))+')';
return '('+str(round(eval(coef), 6))+')*'+expr;
#把多项式中每一项都乘系数
def strscale(array, scale):
scale = '('+str(scale)+')';
for i in range(len(array)):
s = array[i];
for j in range(len(s)):
if (s[j].isdigit()):
index = j;
break;
lbracket = s.find('(');
rbracket = s.find(')', lbracket);
coef = s[lbracket:index]+scale+'*'+s[index:rbracket+1];
coef = '('+str(eval(coef))+')';
array[i] = coef+s[rbracket+1:];
return array;
#找一个字符串中所有待查找子串的位置,返回位置阵列
def findall(string, sub):
size = len(string);
index = [];
cur = string.find(sub);
index.append(cur)
while (index[-1] != -1):
cur = string.find(sub, index[-1]+1);
index.append(cur);
return index;
#计算单项式的乘方, s^n
def strpow(s, n):
stmp = strmono(s);
signIndex = stmp.find('*');
if (signIndex == -1):
coef = stmp+'**'+str(n);
expr = '';
return '('+str(round(eval(coef), 6))+')';
else:
coef = stmp[:signIndex]+'**'+str(n);
expr = '('+stmp[signIndex+1:]+')^['+str(n)+']';
return '('+str(round(eval(coef), 6))+')*'+expr;
#计算代数式用,传入的两个阵列都具有['s1', 's2', ..., 'sn']这样的格式
def strdot(array1, array2):
size1 = len(array1);
size2 = len(array2);
result = [];
for i in range(size1):
for j in range(size2):
result.append(strmul(array1[i], array2[j]));
return result;
#把格式化后的单项式分解成[coef, expr]对组的形式
def explodemono(mono):
stmp = mono;
#乘号的位置
signIndex = stmp.find('*');
if (signIndex == -1):
coef = stmp;
expr = '';
else:
coef = stmp[:signIndex];
expr = stmp[signIndex+1:];
return [coef, expr];
#合并同类项,传入的阵列具有['s1', 's2', ..., 'sn']这样的格式
def strcombine(array):
size = len(array);
explode = [];
for i in range(size):
#这里传入的阵列已经是规格化后的了,否则要加一层strmono处理。
explode.append(explodemono(monocombine(array[i])));
result = [];
for i in range(size):
size_1 = len(result);
if size_1 <= 0:
result.append(explode[i]);
else:
for j in range(size_1):
if result[j][1] == explode[i][1]:
result[j][0] = result[j][0] + '+' + explode[i][0];
break;
if j >= size_1-1:
result.append(explode[i]);
result_1 = [];
size_1 = len(result);
for j in range(size_1):
result[j][0] = str(round(eval(result[j][0]), 6));
if (result[j][0] == '0'):
result_1.append('(0)');
else:
tmps = result[j][1];
if (tmps == ''):
result_1.append('('+result[j][0]+')');
else:
result_1.append('('+result[j][0]+')*'+result[j][1]);
return result_1;
#指数为正整数的乘方
def strpow_n(array, n):
#计算
result = [];
if (n == 1):
result = array;
elif (n == 2):
result = strdot(array, array);
elif (n >= 3):
tmp = strdot(array, array);
n -= 2;
while (n > 0):
result = strdot(tmp, array);
tmp = result;
n -= 1;
return result;
#阵列取负
def minus(array):
for i in range(len(array)):
if array[i][1] == '-':
#array[i][0]是'(, 这是规范
array[i] = array[i][0]+array[i][2:];
else:
array[i] = array[i][0]+'-'+array[i][1:];
return array;
###
# @usage 代数式运算
# @author mw
# @date 2016年05月18日 星期三 07:37:01
# @param
# @return
#
###
#两个多项式相加,合并同类项不在此进行
def stradd(array1, array2):
#两个多项式相加,这里直接返回数组的相加
return array1+array2;
#为了简便输入,不要求输入规范化代数式,(coef)*expr形式
#所以在此对多项式进行规范化
#至于单项式规范化,调用strmono函数即可
def strformat(array):
for i in range(len(array)):
array[i] = strmono(array[i]);
return array;
#把单项式完全格式化,使经过运算的没运算过的都具有统一的格式
def monoformat(mono):
#规范化单项式,保证任意两个参数之间都添加一个'*'号
#这是为了和经过代数式乘法运算之后的格式统一
chars = len(mono);
s = '';
for i in range(chars-1):
if (mono[i] == ']' or mono[i] == ')') and mono[i+1].isalpha():
s += mono[i]+'*';
elif mono[i].isalpha() and mono[i+1].isalpha():
s += mono[i]+'*';
#这里还有一个死角,就是下标或指数如果是用的代数式,并且是多项相乘
#可能会有一点问题,暂时不考虑了
else:
s += mono[i];
s += mono[-1];
return s;
#把单项式炸开,这里的单项式已经达到最大规范化,是(coef)*x_[1]^[2]*y_[2]^[2]这种结构形式了
#'*'号是要作为分隔符的,不可缺少
def explodemono_2(mono):
part = mono.split('*');
#每个部分的[前部,指数部]的对组
map_ = [];
for i in range(len(part)):
expIndex = part[i].find('^');
if (expIndex != -1):
map_.append([part[i][:expIndex], part[i][expIndex:]]);
else:
s = part[i];
#系数
if s[0] == '(':
map_.append([part[i], '']);
#代数式
else:
map_.append([part[i], '^[1]']);
map_ = sorted(map_, key = lambda a : a[0]);
return map_;
#单项式同类项合并
def monocombine(mono):
map_ = explodemono_2(mono);
size = len(map_);
result = [];
for i in range(size):
size_1 = len(result);
if (size_1 <= 0):
result.append(map_[i]);
else:
for j in range(size_1):
if result[j][0] == map_[i][0]:
#双方的中括号位置
#由于规范化后的原因,这个括号是一定有的
p1 = result[j][1].find('[');
p2 = result[j][1].find(']');
p3 = map_[i][1].find('[');
p4 = map_[i][1].find(']');
s = result[j][1][p1+1:p2]+'+'+map_[i][1][p3+1:p4];
size_2 = len(s);
for k in range(size_2):
if s[k].isalpha():
break;
#如果没有字符参数,可以计算出结果,就计算
if (k >= size_2-1):
s = str(eval(s));
result[j][1] = '^['+s+']';
break;
if (j >= size_1-1):
result.append(map_[i]);
size_1 = len(result);
s = '';
for i in range(size_1):
if (i > 0 and result[i][1] == '^[0]'):
continue;
s += result[i][0]+result[i][1];
if (i < size_1-1):
s += '*';
return s;
#排列公式
def arrangement(n, m):
if n < m:
return arrangement(m, n);
else:
factorial = 1;
for i in range(n, n-m, -1):
factorial*=i;
return factorial;
#组合公式
def combination(n, m):
if (n < m):
return combination(m, n);
else:
return arrangement(n, m)/arrangement(m,m);
#解一元二次方程
class Equation():
def quadratic(self, array):
a, b, c = array[0], array[1], array[2];
if (a < 0):
a, b, c = -a, -b, -c;
p = q = delta = 0;
x1 = x2 = 0;
s = '';
if (a == 0):
return [-c/b];
else:
delta = b**2 - 4*a*c;
if (delta < 0):
real = -b/(2*a);
image = (-delta)**0.5;
return [complex(real, -image), complex(real, image)];
else:
if (abs(delta) < 1e-6):
x1 = x2 = -b/(2*a);
else:
x1 = (-b-delta**0.5)/(a*2);
x2 = (-b+delta**0.5)/(a*2);
return [x1, x2];
###
# @usage 数据的集中分析类
# @author mw
# @date 2016年05月20日 星期五 10:06:47
# @param
# @return
#
###
class DataAnalyze():
#由于numpy的方法接口只对narray开放,所以,数组先要格式化一下
#对于自己的数组而言,这个方法是必须要先调用一下,才能使用numpy方法的
def format(self, array):
return numpy.array(array);
#求和
def sum(self, array):
return array.sum();
#均值
def average(self, array):
return self.sum(array)/len(array);
#方差
def variance(self, array):
array_ = array*array;
sum_ = array_.sum();
aver_ = self.average(array);
result = sum_/len(array) - aver_**2;
return result;
#标准差
def RMS(self, array):
return (self.variance)**0.5;
###
# @usage 多项式运算相关
# @author mw
# @date 2016年05月23日 星期一 09:36:12
# @param
# @return
#
###
class Polynomial():
#格式化打印
def printPoly(self, array, variable = 'x'):
len_ = len(array);
poly = [];
for i in range(len_):
if (i < len_ -1):
s = '('+str(array[i])+')*'+variable+'^['+str(len_-1-i)+']';
else:
s = '('+str(array[i])+')';
poly.append(s);
s = '';
for i in range(len_):
s += poly[i];
if (i < len_ - 1):
s += '+';
print(s); #格式:(1)*x^[3]+(2)*x^[2]+(-3)*x^[1]+(4)
return poly;
#解不等式
def inequality(self, array, symbol = '<'):
#方程的根
roots = np.roots(array);
roots = sorted(roots);
#print(roots);
len_ = len(roots);
p = np.poly1d(array);
#符合要求的区间
section = [];
if (symbol == '<'):
if (p(roots[0]-1) < 0):
section.append(['-inf', roots[0]]);
if (p(roots[len_-1]+1))< 0:
section.append([roots[len_-1], 'inf']);
elif (symbol == '>'):
if (p(roots[0]-1)) > 0:
section.append(['-inf', roots[0]]);
if (p(roots[len_-1]+1)) > 0:
section.append([roots[len_-1], 'inf']);
for i in range(len_-1):
mid = (roots[i]+roots[i+1])/2;
if (symbol == '<'):
if p(mid) < 0:
section.append([roots[i], roots[i+1]]);
elif (symbol == '>'):
if p(mid) > 0:
section.append([roots[i], roots[i+1]]);
return section;
#计算代数式的值
#代数式具有[(coef)*expr^[exp], ...]这种形式
#要加载自制的alg模块
def algValue(self, stralg, valueTable):
#多项式的项数
len_s = len(stralg);
#参数对照表的项数
#参数对照表具有[['x', '1'], ['y', '3']]这样的形式
len_v = len(valueTable);
for i in range(len_s):
s = stralg[i];
for j in range(len_v):
s = s.replace(valueTable[j][0], str(valueTable[j][1]));
s = s.replace('^[', '**(');
s = s.replace(']', ')');
stralg[i] = eval(s);
return stralg;
</span>
<span style="font-size:18px;">import numpy.f2py
import numpy.random
import numpy.polynomial
import numpy.ma
import numpy.distutils
import numpy.compat
import numpy as np;
import numpy.linalg
import numpy.matrixlib
import numpy.fft
import numpy.distutils.fcompiler
import numpy.core
import numpy.distutils.command
###
# @usage 对于含有代数符号的等式及相关类型进行计算
# @author mw
# @date 2016年05月24日 星期二 08:21:57
# @param
# @return
#
###
#所有输入的字符串都是要符合(coef)*expr这种规范的
#相应转换可以调用alg.strmono处理单项式
#或调用alg.strformat来处理多项式
class StringAlgSolve():
#格式化输入的多项式阵列
def format(self, array):
return alg.strformat(array);
#把一个字符串阵列表示的多项式,转换成指定变量的系数多项式
#比如 ['(1/4)x^[2]', '-(1/12)y^[2]', '-1'], 以y作为参数 => ['(-(1/12))', 0, '(1/4)x^[2]+(-1)']
#传入的格式必须是已经格式化过的(coef)*x^[2]*y_[2]^[3]...这种类似形式
def coefTransfer(self, array, element):
coefMap = [];
len_ = len(array);
len_2 = len(element);
for i in range(len_):
s = array[i];
len_3 = len(s);
index = s.find(element);
#参数的0次方
if (index == -1):
coefMap.append([array[i], 0]);
elif (index+len_2 < len_3 and s[index+len_2] != '^'):
#参数的一次方
coefMap.append([s[:index-1]+s[index+len_2:], 1]);
elif (index+len_2 >= len_3):
#这里回退一个位置是因为根据格式参数之间有一个'*'号相连,要退掉
coefMap.append([s[:index-1], 1]);
else:
#左右中括号作为定界符,这就是为什么要求先格式化
LBracket = index+len_2+1;
RBracket = s.find(']', LBracket);
#幂的次数
exp_ = int(s[LBracket+1:RBracket]);
coefMap.append([s[:index-1]+s[index+len_2:], exp_]);
#对coefMap中的项按参数的次数进行合并
coefMap_2 = [];
coefMap_2.append(coefMap[0]);
for i in range(1, len(coefMap)):
len_3 = len(coefMap_2);
for j in range(len_3):
if (coefMap_2[j][1] == coefMap[i][1]):
coefMap_2[j][0] = coefMap_2[j][0]+ '+'+coefMap[i][0];
break;
if (j >= len_3-1):
coefMap_2.append(coefMap[i]);
coefMap = coefMap_2;
#把系数映射由高到低排列
coefMap = sorted(coefMap, key = lambda a : a[1], reverse = True);
#返回的是参数的系数映射表[[coef, exp]...]对组
return coefMap;
#返回参数的系数阵列
def coefArray(self, array, element):
coefMap = self.coefTransfer(array, element);
len_4 = len(coefMap);
maxCoef, minCoef = coefMap[0][1], coefMap[len_4-1][1];
coefArray = ['0']*(maxCoef-minCoef+1);
for i in range(len_4):
coefArray[maxCoef-coefMap[i][1]] = coefMap[i][0];
return coefArray;
#获取多项式的系数值,比如5x^2+4x+1 = 0应该返回[5, 4, 1]
def coefPoly(self, array, element):
coefMap = self.coefTransfer(array, element);
len_4 = len(coefMap);
maxCoef, minCoef = coefMap[0][1], coefMap[len_4-1][1];
coefArray = ['0']*(maxCoef-minCoef+1);
for i in range(len_4):
index = coefMap[i][0].find('^');
if (index != -1):
s = coefMap[i][0][:index];
else:
s = coefMap[i][0];
#这里是必须要能求值的,这个方法是为了便于调用numpy.roots求多项式的根
coefArray[maxCoef-coefMap[i][1]] = eval(s);
return coefArray;
#求解多项式的根(在参数情况下)
def solvePoly(self, coefArray):
len_ = len(coefArray);
#
#求解二次方程
if (len_ == 3):
a, b, c = str(coefArray[0]), str(coefArray[1]), str(coefArray[2]);
#注意,由于此处得出的系数阵列是这样的形式:['(-(1/12))', 0, '(1/4)x^[2]+(-1)']
#已经无法用alg中函数去做任何计算,只能纯粹进行字符串的叠加处理
delta = self.strAdd(self.strPow(b, '2'), self.strMul('-4', self.strMul(a, c)));
#分子,分母
numerator = self.strAdd(self.strMinus('0', b), self.strPow(delta, '0.5'));
numerator2 = self.strMinus(self.strMinus('0', b), self.strPow(delta, '0.5'));
denomerator = self.strMul('2', a);
return [self.strDiv(numerator, denomerator),
self.strDiv(numerator2, denomerator)];
#求解一次方程
if (len_ == 2):
a, b = str(coefArray[0]), str(coefArray[1]);
return [self.strDiv(b, self.strMinus('0', a))];
return '';
#代数式里的两个代数式相乘,这里就是两个字符串相加的处理而已
def strMul(self, str1, str2):
if (self.judgeZero(str1)):
return '';
else:
if (self.judgeZero(str2)):
return '';
else:
return '('+str1+')*('+str2+')';
#两个代数式相除
def strDiv(self, str1, str2):
if (self.judgeZero(str1)):
return '';
else:
if (self.judgeZero(str2)):
return '(inf)';
else:
return '('+str1+')/('+str2+')';
#代数式相减
def strMinus(self, str1, str2):
if (self.judgeZero(str1)):
if (self.judgeZero(str2)):
return '';
else:
return '(-('+str2+'))';
else:
if (self.judgeZero(str2)):
return '('+str1+')';
else:
return '('+str1+')-('+str2+')';
#代数式相加
def strAdd(self, str1, str2):
if (self.judgeZero(str1)):
if (self.judgeZero(str2)):
return '';
else:
return '('+str2+')';
else:
if (self.judgeZero(str2)):
return '('+str1+')';
else:
return '('+str1+')+('+str2+')';
#代数式里的代数式乘方,这里就是字符串的处理而已
def strPow(self, str1, str2):
str2 = str(str2);
if (self.judgeZero(str1)):
return '';
else:
if (self.judgeZero(str2)):
return '('+str1+')';
else:
return '('+str1+')^['+str2+']';
#判断字符串是否为0
def judgeZero(self, str1):
for i in range(len(str1)):
if (str1[i].isdigit() and str1[i] != '0'):
#存在数字不为0, 所以这个代数式不为0
return False;
#由于在规范化输出时已经保证了如果系数为0, 无论有多少参数都取0
#所以只要存在参数就说明代数式不为0
elif (str1[i].isalpha()):
return False;
return True;
#给参数赋值,计算代数式的值
#比如输入 ('x^[2]+1', 'x', 3) => 10
#要确保给的条件足以让代数式计算出数值,否则肯定报错
def strEval(self, str1, element, elementValue):
#代入数值,去指数
str1 = str1.replace(element, str(elementValue));
str1 = str1.replace('^[', '**');
str1 = str1.replace(']', '');
return eval(str1);
#对于本身不带参数的字符串,清除格式即可计算出数值
def arrayEval(self, array):
for i in range(len(array)):
str1 = array[i];
str1 = str1.replace('^[', '**');
str1 = str1.replace(']', '');
str1 = eval(str1);
array[i] = str1;
return array;</span>
本节到此结束,欲知后事如何,请看下回分解。