我们是不是太关注于语法而忽略了算法

从启明星数学系统Math说起

最近做了一个数学系统(还没做完),中间使用了不少第三方开源插件,但是发现这些插件基本上都是国外的.

事实上这些插件基本上都使用Javascript开发,也并不会涉及太高深的JS知识,但是,这些插件对算法要求甚高。

(1)数学公式

数学公式使用Latex展示,但是把Latex解析为HTML是非常考验基本功的技术。

 

(2)SVG画图,看起来简单,但是做起来也不容易,这通常出现在习题里,例如"三角形ABC,D是BC上一点。。。"类似这样的题目

 

(3)几何图形,包括正弦,余弦,正切,余切,指数,对数,微积分,线性变化,圆,椭圆,双曲线等图形

这种图形适合教学,例如通过图形,很容易让学生知道正弦余弦的效果。

 上面这些都是基本功,事实上,他是和语言无挂的。如果JS做不出,那么用NET/JAVA/GO/等仍然很难做出。

这就像使用AutoCAD进行机械制图,AutoCAD只是一个工具,如果你设计不同出图形,那么无论使用何种CAD,还是作不出。

因此,相比语法,算法可能更重要。

 

语法与算法

语法,这里特指计算机语法,是计算机语言规定的一套规则,不同的语言如Java,NET,甚至Javascript,Typescript都定义了自己的一套语言规则。

要使用该语言,必须符合该语言规则。

算法,是解决一件事情的方法,或者说是一系列解决问题的清晰指令,同样一个问题,可以有不同的方法解决,因此算法有好的算法也有不好的算法。

算法的优劣可以用空间复杂度与时间复杂度来衡量。

软件=语法+算法。一个软件的运行需要“语法+算法”两则缺一不可。

 

计算机只要三个语法即可

事实上,早期,人们编写程序发现,计算机只要三个流程即可:正常的顺序流程,条件流程和循环流程。

顺序流程比较简单,代码一行一行执行,没什么可说明的。

条件流程就是 if 语句

循环流程就是while语句。

除此以外,其它语句都不是必须的,以.NET为例,其实net还提供了goto语句,但是后来人们发现,goto一方面破坏了程序的可读性,让程序跳来跳去,

一方面goto语句可以使用if和whilte替代,所以,goto使用率极低。

掌握了上面的三个流程,就可以写出程序。

顺序的语句

int a=1;
int b=2;
int c=a+b

 

if条件语句

        int a=1;
        int b=2
        if(a<b)
        {
        //do something2
        }
        else
        {
         //do something2
        }  

white循环语句

  int i = 0;
        int sum = 0;
        while (i < 10)
        {
            sum += i;
            i++;
        }

 

由此,.NET的其它语法都可以由这3个基本规则推导而来。

例如switch基本上是和if等效的

 switch (i)
        { 
            case "1":
                break;
                   
            case "2":
                break;

            case "3":
                break;
        }

        if(if=="1")
        {
        //
        }

         if(if=="3")
        {
        //
        }

         if(if=="4")
        {
        //
        }

  

 而.NET的 foreach也是可以由while语句实现

string[] studens = { "s1","stud2"};
        foreach (string stud in studens)
        {
            ....
        }

        int len=studens.Length;
        while(i<len)
        {
          string stud=studens[i];
            i++;
        }

 

所以,任何计算机语言都一定会提供if语句和while语句,否则这个语言就无法真正成为计算机语言。

 

算法是千变万化

和计算机语言相对稳定相比,算法才是千变万化。在计算机教程里,对排序的算法讲解的最多,包括 简单排序、插入排序,快速排序,冒泡排序、希尔排序等

每种排序算法都有优点和确定,例如快速排序虽然快速但是稳定性差, 简单排序效率差但是稳定性强。

这就像“马儿跑的快但是力气小,牛儿力气大但是走的慢”,所以,牛马都有各自的应用场景。

 

软件竞争力核心在算法

在很多情况下,我们感觉“这个软件好,那个软件不好”很大程度上是由算法决定的,这里的算法不仅仅只是排序那么简单。

对NET进行序列化和反序列化,主要有微软提供的DataContractJsonSerializer类和JavaScriptSerializer类,以及开源社区提供的Newtonsoft.Json(JSON.Net)类。

虽然他们都使用.NET开发,但是能明显感觉Newtonsoft.Json优于微软提供的类。(图片来自yanweidie

 

 

 

 

算法是发散思维的

计算机语言是限定思维的,就是你只能使用他定义的语法,但是,算法则是发散思维的。这种发散思维体现的是“解决问题的方法”。

当我们在网页里,双击一个文字时,会自动选择该文字对应的单词,

我相信这背后有微软提供的词库,例如你双击“归纳”的“归”,他会自动选中“归纳”,而不是“妨归”。

 

 

 

但是,在进行svg的操作里,微软并未提供这样的“选中”功能,这就需要我们自己实现“选中对象” 

上次看mrdoob实现的方式很简单,创建一个span,设置它鼠标样式为:none,设置它边框为红色,就可以实现下图的效果。

var selection = document.createElement( 'span' );
		selection.style.position = 'absolute';
		selection.style.display = 'block';
		selection.style.outline = 'solid 2px #ff0000';
		selection.style.pointerEvents = 'none';
		document.body.appendChild( selection );

  

 

类似的例子还有很多。

 

谈一谈Visual Studio的实现

以下内容纯属猜想,我也没找他资料来查证下面的猜想。

Visual Studio号称宇宙开发第一工具,一直很好奇他是怎么实现的,特别是字体变亮,语法提示,效果又准又快。

好在有开源的力量,最早知道的是codemirror,codemirror可以让textarea秒变编辑器。

再配合一些插件,就算非专业人士,也能实现类似部分Visual Studio的效果。

 

 

但是,Codemirror太复杂.

所以,又找到了 PrismJS,这是一个轻量级的代码显示工具,

使用prism能让你的代码,在web上显示时,看起来很专业。

 

 

很容易看到他提供的源代码,核心还是“正则表达式”。也就是系统预定义了样式,当选中所需序言时,切换对应的样式进行变色。

说起来容易,做起来还是很复杂的。

 

 

当然,Visual Stuido的实现肯定比这复杂,例如VS的关键字应该是编译后显示亮度,而不是只靠字面的文字。

虽然leetcode也有算法,可是她只是一个点,不是一条线。

 --------------------------------------------------------------

启明星数学系统 http://demo.dotnetcms.org/math,主要是供老师使用的一套系统。

posted @ 2021-06-14 19:31  启明星工作室  阅读(423)  评论(0编辑  收藏  举报