chili 默默学编程

SICP(6):符号化求导程序


本文目录:

1、符号化求导程序目标;

2、实现步骤;

3、JavaScript 代码;


符号化求导程序

就是写一个程序,能够计算符号化多项式的导函数:

deriv('5x^5+3x^4', 'x')  // 25x^4+12x^3

课程以此为例子,讲述程序的设计原则(设计新语言的方法:抽象屏蔽)


实现步骤

1、设计出一些 “类” 方法

2、组合起来

Image


JavaScript 代码

const log = function() {
    console.log.apply(console, arguments)
}

const isConstant = function(s, x) {
    return s.indexOf(x) == -1
}
const zero = function(s, x) {
    return '0'
}

const isSameVar = function(s, x) {
    return s == x
}
const one = function(s, x) {
    return '1'
}

const makeSum = function(s1, s2) {
    if (s1 == '' || s1 == '0') {
        return s2
    } else if (s2 == '' || s2 == '0') {
        return s1
    } else {
        return s1 + '+' + s2
    }
}
const isSum = function(s, x) {
    return s.indexOf('+') != -1
}
const derivSum = function(s, x) {
    let arr = s.split('+')
    let result = ''
    for (var i = 0; i < arr.length; i++) {
        result = makeSum(result, deriv(arr[i], x))
    }
    return result
}

const parse = function(s, x) {
    let result = []
    result.push(s.split(x)[0])
    if (s.split(x).length == 1) {
        result.push(0)
    } else if (s.split('^')[1] == '') {
        result.push(1)
    } else {
        result.push(parseInt(s.split('^')[1]))
    }
    return result
}
const makeProduct = function(s1, s2, x) {
    let base = x
    let arrS1 = parse(s1, x)
    let arrS2 = parse(s2, x)
    let exp = arrS1[1] + arrS2[1]
    if (exp > 1) {
        base = base + '^' + String(exp)
    }
    if (arrS1[0] * arrS2[0] == 0) {
        return ''
    } else {
        return arrS1[0] * arrS2[0] + base
    }
}
const isProduct = function(s, x) {
    return s.indexOf(x) != 0
}
const derivProduct = function(s, x) {
    let arr = s.split(x)
    let firstPart = arr[0]
    if (arr[1] != '') {
        let leftPart = x + arr[1]
        return makeSum(makeProduct(firstPart, deriv(leftPart, x), x), makeProduct(deriv(firstPart, x) , leftPart, x))
    } else {
        return firstPart
    }
}

const isPow = function(s, x) {
    return s.indexOf('^') != -1
}
const derivPow = function(s, x) {
    let base = x
    let exp = parseInt(s.split('^')[1])
    if (exp == 2) {
        return String(exp) + base
    } else {
        return String(exp) + base + '^' + String(exp - 1)
    }

}

const deriv = function(s, x) {
    let derivArr = [
        [isConstant, zero],
        [isSameVar, one],
        [isSum, derivSum],
        [isProduct, derivProduct],
        [isPow, derivPow],
    ]

    for (var i = 0; i < derivArr.length; i++) {
        let d = derivArr[i]
        if (d[0](s, x)) {
            return d[1](s, x)
        }
    }
}
log("deriv('5x^5+3x^4', 'x'): ", deriv('5x^5+3x^4', 'x'))

reply ( 0 )