正剧开始:
星历2016年04月08日 11:41:49, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[集合与函数概念]。
小伟看到这里的时候,是一阵的头晕目眩哪,这些稀奇古怪的符号,是从哪儿冒出来的啊
。而且,如果不能很容易的写出它们,看来是没法进行下去了。
为了找出怎样写出这些符号,小伟找啊找,终于找到了。
<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, 190);*/ var a = '0123456789ABCDEF'; var x = y = 0; var s = ''; for (var i = 0; i < 16; i++) { s = ''; for (var j = 0; j < 16; j++) { s += '\\'+'u22'+a[i]+a[j]; } document.write('\''+s+'\','+'<br/>'); } } if (1) { var s = [ '\u2200\u2201\u2202\u2203\u2204\u2205\u2206\u2207\u2208\u2209\u220A\u220B\u220C\u220D\u220E\u220F', '\u2210\u2211\u2212\u2213\u2214\u2215\u2216\u2217\u2218\u2219\u221A\u221B\u221C\u221D\u221E\u221F', '\u2220\u2221\u2222\u2223\u2224\u2225\u2226\u2227\u2228\u2229\u222A\u222B\u222C\u222D\u222E\u222F', '\u2230\u2231\u2232\u2233\u2234\u2235\u2236\u2237\u2238\u2239\u223A\u223B\u223C\u223D\u223E\u223F', '\u2240\u2241\u2242\u2243\u2244\u2245\u2246\u2247\u2248\u2249\u224A\u224B\u224C\u224D\u224E\u224F', '\u2250\u2251\u2252\u2253\u2254\u2255\u2256\u2257\u2258\u2259\u225A\u225B\u225C\u225D\u225E\u225F', '\u2260\u2261\u2262\u2263\u2264\u2265\u2266\u2267\u2268\u2269\u226A\u226B\u226C\u226D\u226E\u226F', '\u2270\u2271\u2272\u2273\u2274\u2275\u2276\u2277\u2278\u2279\u227A\u227B\u227C\u227D\u227E\u227F', '\u2280\u2281\u2282\u2283\u2284\u2285\u2286\u2287\u2288\u2289\u228A\u228B\u228C\u228D\u228E\u228F', '\u2290\u2291\u2292\u2293\u2294\u2295\u2296\u2297\u2298\u2299\u229A\u229B\u229C\u229D\u229E\u229F', '\u22A0\u22A1\u22A2\u22A3\u22A4\u22A5\u22A6\u22A7\u22A8\u22A9\u22AA\u22AB\u22AC\u22AD\u22AE\u22AF', '\u22B0\u22B1\u22B2\u22B3\u22B4\u22B5\u22B6\u22B7\u22B8\u22B9\u22BA\u22BB\u22BC\u22BD\u22BE\u22BF', '\u22C0\u22C1\u22C2\u22C3\u22C4\u22C5\u22C6\u22C7\u22C8\u22C9\u22CA\u22CB\u22CC\u22CD\u22CE\u22CF', '\u22D0\u22D1\u22D2\u22D3\u22D4\u22D5\u22D6\u22D7\u22D8\u22D9\u22DA\u22DB\u22DC\u22DD\u22DE\u22DF', '\u22E0\u22E1\u22E2\u22E3\u22E4\u22E5\u22E6\u22E7\u22E8\u22E9\u22EA\u22EB\u22EC\u22ED\u22EE\u22EF', '\u22F0\u22F1\u22F2\u22F3\u22F4\u22F5\u22F6\u22F7\u22F8\u22F9\u22FA\u22FB\u22FC\u22FD\u22FE\u22FF' ]; var x =40, y=40; var r1 = 40; var len = s.length; for (var i = 0; i < 8; i++) { plot.fillText(s[i], x, y, 500); y+=r1; } } </span>
于是,阿伟帮助小伟又进化了一下以前写表达式的工具,这下可以写。先看看效果吧。
这是怎么写出来的啊,困不困难呀。
小伟是这样写的:
<span style="font-size:18px;"> var s = [ /* 'a[B]A', 'a[NB]A', '3[B]A, 4[NB]A', '{1, 2}', 'D = {x[B]R | x < 10}', 'E = {x[B]Z | x = 2k+1, k[B]Z}', 'A[S]B', 'B[SS]A', 'if A[S]B, but exist x[B]B and x[NB]A, then A[ST]B, or B[SST]A',*/ 'A[UU]B={x|x[B]A, or x[B]B}', 'A[I]B={x|x[B]A, and x[B]B}', '[C]_[U]A={x|x[B]U, and x[NB]A}', 'y = ax+b, (a!=0)', 'a > 0, B={y|y>=(4ac-b^[2])/4a}', 'a < 0, B={y|y<=(4ac-b^[2])/4a}', 'R[B]{-[INF], +[INF]}', ];</span>
虽然看起来像是天书差不多,不过好在可以用简便一点的方法来写那些稀奇符号了。
这里是对照表:
<span style="font-size:18px;"> if (s != '') { s = s.replace(/\[B\]/ig, '\u2208'); //∈ s = s.replace(/\[NB\]/ig, '\u2209'); //不属于 s = s.replace(/\[S\]/ig, '\u2286'); //包含于(是子集) s = s.replace(/\[SS\]/ig, '\u2287'); //包含 s = s.replace(/\[ST\]/ig, '\u228A'); //真包含于(是真子集) s = s.replace(/\[SST\]/ig, '\u228B'); //真包含 s = s.replace(/\[UU\]/ig, '\u222A'); //并集 ,由于U表示全集,又常为下标,此处错开 s = s.replace(/\[I\]/ig, '\u2229'); //交集 s = s.replace(/\[C\]/ig, '\u2201'); //补集 s = s.replace(/\[INF\]/ig, '\u221E'); //无穷大 }</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 Lt Std"); } this.setScriptFont = function() { plot.setFont("italic normal bold 16px Dark Courier "); } this.print = function(text, xPos, yPos) { xPos = xPos ? xPos : 0; yPos = yPos ? yPos : 0; plot.save(); var s = text ? text : ''; if (s != '') { s = s.replace(/\/\//ig, '÷'); s = s.replace(/>=/ig, '≥'); s = s.replace(/<=/ig, '≤'); s = s.replace(/!=/ig, '≠'); s = s.replace(/pi/ig, 'π'); } //字符串长度 var len = s.length; //不同字体大小设置在此 var r1 = 20; //单个字符暂存处 var c; //文本显示位置 var x = xPos, y = yPos; //正常文本暂存 var s0 = ''; //字符串打印长度 var measure; //记录上一个x位置,可记录三层 var xMem = [x, x, x]; //记录每一层的左括号位置 var bracketPos = [x, x, x]; //记录括号层次 var bracketsLevel = 0; //记录根号层次 var radicalLevel = 0; //记录每一层根号的起始位置和层次数的数组...[[start, end, level], ...] var radicalSpan = []; //设置正常字体 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 subScript = ''; var j = 0; for (j = i+1; s[j]!=']'; j++) { if (s[j] != '[') { subScript+=s[j]; } } if (r1 != 10) {//正常字体状态,需要改为上标字体 r1 = 10; this.setScriptFont(); } measure = plot.measureText(subScript); plot.fillText(subScript, x, y+8, measure); if (j < len-1 && s[j+1] == '^') { } else { x += 1.2*measure; } i = j; } else 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 = ''; var j = 0; for (j = i+1; s[j]!=']'; j++) { if (s[j] != '[') { upperScript+=s[j]; } } //二次根式 if (upperScript == '1/2' || upperScript == '0.5') { var x1, y1; if (i > 0 && s[i-1] == ')') { x1 = bracketPos[bracketsLevel]; } else { x1 = xMem[bracketsLevel]; } /* 存疑代码 if (radicalSpan == []) { radicalLevel = 0; radicalSpan.push([x1, x, radicalLevel]); } else { var len = radicalSpan.length; for (var k = 0; k < len; k++) { if (x1 < radicalSpan[k][0]) { radicalLevel = radicalSpan[k][2]+1; break; } if (k >= len-1) { radicalLevel = 0; } } radicalSpan.push([x1, x, radicalLevel]); }*/ y1 = y-20-5*radicalLevel; plot.save() .setLineWidth(1); plot.beginPath() .moveTo(x1-5, y+5) .lineTo(x1-8, y-3) .moveTo(x1-5, y+5) .lineTo(x1+5, y1) .moveTo(x1+5, y1) .lineTo(x, y1) .closePath() .stroke(); plot.restore(); } else { if (r1 != 10) {//正常字体状态,需要改为上标字体 r1 = 10; this.setScriptFont(); } measure = plot.measureText(upperScript); plot.fillText(upperScript, x, y-8, measure); if (j < len-1 && s[j+1] == '_') { } else { x += 1.2*measure; } } //直接跳跃过上标字符区段 i = j; } else { c = s[i]; if (c == ')') { s0 += c; bracketsLevel -= 1; } else if (c == '(') { //如果整个括号被开根式,根号在括号左边 bracketPos[bracketsLevel] = x + plot.measureText(s0); s0 += c; bracketsLevel+=1; //过了括号就是过了一道关,要刷新坐标 xMem[bracketsLevel] = x + plot.measureText(s0); } else if (c == '+' || c == '-' || c == '*' || c == '/' || c == '÷' || c == '=' || c == ' ') { if (c == '*') { if (i > 0 && /[0-9]/.test(s[i-1]) && /[0-9]/.test(s[i+1])) { //对于乘号前后都是数字的情况,把乘号改成叉号 c = ' \u00D7 '; } else { //对于代数式中,乘号改为点号 c = ' \u00B7 '; } } //如果是运算符后的数被开根式,根号在运算符右边 if (c == '-' || c == '/') { s0 += ' '+c+' '; } else { s0 += c; } if (bracketsLevel < 3) { xMem[bracketsLevel] = x+plot.measureText(s0); } } else { 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(); } //集合符号,集合表达式的书写 this.printSet = function(text, xpos, ypos) { var s = text ? text : ''; if (s != '') { s = s.replace(/\[B\]/ig, '\u2208'); //∈ s = s.replace(/\[NB\]/ig, '\u2209'); //不属于 s = s.replace(/\[S\]/ig, '\u2286'); //包含于(是子集) s = s.replace(/\[SS\]/ig, '\u2287'); //包含 s = s.replace(/\[ST\]/ig, '\u228A'); //真包含于(是真子集) s = s.replace(/\[SST\]/ig, '\u228B'); //真包含 s = s.replace(/\[UU\]/ig, '\u222A'); //并集 ,由于U表示全集,又常为下标,此处错开 s = s.replace(/\[I\]/ig, '\u2229'); //交集 s = s.replace(/\[C\]/ig, '\u2201'); //补集 s = s.replace(/\[INF\]/ig, '\u221E'); //无穷大 } return this.print(s, xpos, ypos); } }</span>
<span style="font-size:18px;"> if (1) { var mathText = new MathText(); var s = [ /* 'a[B]A', 'a[NB]A', '3[B]A, 4[NB]A', '{1, 2}', 'D = {x[B]R | x < 10}', 'E = {x[B]Z | x = 2k+1, k[B]Z}', 'A[S]B', 'B[SS]A', 'if A[S]B, but exist x[B]B and x[NB]A, then A[ST]B, or B[SST]A',*/ 'A[UU]B={x|x[B]A, or x[B]B}', 'A[I]B={x|x[B]A, and x[B]B}', '[C]_[U]A={x|x[B]U, and x[NB]A}', 'y = ax+b, (a!=0)', 'a > 0, B={y|y>=(4ac-b^[2])/4a}', 'a < 0, B={y|y<=(4ac-b^[2])/4a}', 'R[B]{-[INF], +[INF]}', ]; 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.printSet(s[i], x, y); y+=r1; } } }</span>
这个问题好办,取10000个数作为范围,可以知道A有10000, B有5000。
这个恩氏系数小伟还是蛮关心的,先看一下这些数据的直观图吧:
这些数据呢,小伟看不懂,不过感觉很牛的样纸。
<span style="font-size:18px;"> if (1) { var stat = new Statistic(); var data = [53.8,52.9,50.1,49.9,49.9,48.6,46.4,44.5,41.9,39.2,37.9]; var text = []; for (var i = 1991; i <= 2001; i++) { text.push(i.toFixed(0)); } stat.init(data, '时间(年)', '恩格尔系数(%)', 1); stat.barChart(text, 0, 0); } if (1) { var stat = new Statistic(); var data = [53.8,52.9,50.1,49.9,49.9,48.6,46.4,44.5,41.9,39.2,37.9]; var text = []; var size = data.length; //为了绘制折线图,要把一维数组变化成二维数组 for (var i = 0; i < size; i++) { data.push([data.shift()]); } for (var i = 1991; i <= 2001; i++) { text.push(i.toFixed(0)); } stat.init(data, '时间(年)', '恩格尔系数(%)', 1); stat.multiLineGraph(text, ['恩格尔系数'], 0, 0); }</span>
这几位同学的成绩到底怎样啊,小伟决定看一看。
看来这个和小伟同名的同学也是一位学霸啊,每次都考这么多分。
<span style="font-size:18px;"> if (1) { var stat = new Statistic(); var wangWei = [98,87,91,92,88,96], zhangChen = [90,76,88,75,86,80], zhaoLei = [68,65,73,72,75,82], average = [88.2,78.3,85.4,80.3,75.7,82.6]; var text = []; var size = average.length; var data = []; //为了绘制折线图,要把一维数组变化成二维数组 for (var i = 0; i < size; i++) { data.push([wangWei[i], zhangChen[i], zhaoLei[i], average[i]]); } for (var i = 1; i <= 6; i++) { text.push('第'+i.toFixed(0)+'次'); } stat.init(data, '测试次序', '成绩', 4); stat.multiBarChart(text, ['王伟', '张城', '赵磊', '班级平均分'], -15, 50); //stat.multiLineGraph(text, ['王伟', '张城', '赵磊', '班级平均分'], -15, 50); } </span>
小伟做了一个求单调性的小工具:
<span style="font-size:18px;">//判断单调性 //单调性 //[词典] monotonicity; monotone; monotonic; monotony; function monotonicityJudge(array, range) { //传入参数 //array 是[[x1, y1], [x2, y2], ...]的映射对格式 //range 是需要判断的区间[minX, maxX] var size = array.length; if (size < 1 || array[0].length < 2) return false; array.sort(function(a, b) { return (a[0]-b[0]); }); var minX = range[0] < range[1] ? range[0] : range[1], maxX = range[0] < range[1] ? range[1] : range[0]; var y1 = y2 = y3 = 0; for (var i = 1; i < size-1; i++) { if (array[i][0] >= minX && array[i][0] <= maxX) { y1 = array[i-1][1]; y2 = array[i][1]; y3 = array[i+1][1]; //在给定区间中不存在单调性 if ((y1-y2)*(y2-y3)< 0) return [false, '']; } if (array[i][0] > maxX) break; } if (y3 < y2) { return [true, '单调递减']; } else { return [true, '单调递增']; } }</span>
不过好像不是很好玩。
<span style="font-size:18px;"> if (1) { var array = []; var x = y = 0; for (var i = -10; i<=10; i+=1) { x = i; y = 1/x; if (y) { array.push([x, y]); } } var range = [-3, -2]; var minX = range[0] < range[1] ? range[0] : range[1], maxX = range[0] < range[1] ? range[1] : range[0]; var result = monotonicityJudge(array, range); if (result[0] == true) { document.write('数组(映射)在区间'+minX.toFixed(2)+'到' +maxX.toFixed(2)+'上具有单调性,'+result[1]+'<br/>'); } else { document.write('数组(映射)在区间'+minX.toFixed(2)+'到' +maxX.toFixed(2)+'上不具有单调性。'+'<br/>'); } }</span>
这个是求奇偶性的小工具。
<span style="font-size:18px;">if (1) { var array = []; var x = y1 = y2 = 0; var result = []; var range = 10000; var begin = 0; for (var i = 0; i < 10; i++) { x = begin+Math.round(Math.random()*range)%range; //函数写在这里 y1 = 1/(x*x); x = -x; y2 = 1/(x*x); if (y1 == y2) { result.push(1); } else if (y1 == -y2) { result.push(-1); } else { result.push(0); } } var count = 0; var len = result.length; for (var i = 0; i < len; i++) { count += result[i]; } if (count == len) { document.write('是偶函数'+'<br/>'); } else if (count == -len) { document.write('是奇函数'+'<br/>'); } else { document.write('是非奇非偶函数'+'<br/>'); } } }</span>
本节到此结束,欲知后事如何,请看下回分解。