iT邦幫忙

1

node.js 求解

  • 分享至 

  • xImage
ccutmis iT邦高手 2 級 ‧ 2019-11-07 20:47:28 檢舉
用String.split太麻煩了,用evil一行搞定...

let calc = calcString => eval(calcString);
console.log(calc('8*2')); /* 印出16 */
dragonH iT邦超人 5 級 ‧ 2019-11-07 20:50:20 檢舉
>用String.split太麻煩了,用evil一行搞定...

有夠 evil
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
dragonH
iT邦超人 5 級 ‧ 2019-11-07 20:26:55
最佳解答

提示你

先找出運算子 (+、-、*、/)

再來

算數學

String.includes 是用來找出字串有沒有存在你要找的目標

e.g.

'8*2'.includes('*'); // true
'8*2'.includes('/'); // false

String.split 是用來切字串

e.g.

'8*2'.split('*') //["8", "2"]

看起來沒有括號的四則運算

題目也都只有一個運算子

應該很簡單的

ps. 哪間學校教 Typescript 這麼潮XD /images/emoticon/emoticon07.gif

標準寫法

let calc = function (calcString: string) {
    if (如果運算式有 "*") {
        const data = 處理過只有數字的陣列
        console.log(第一個數字 * 第二個數字)
    }
}

叛逆寫法

let calc = function (calcString: string) {
    console.log(eval(calcString))
}
看更多先前的回應...收起先前的回應...

是問完就刪題目嗎0.0

dragonH iT邦超人 5 級 ‧ 2019-11-07 21:58:52 檢舉

怕老師抓到吧 /images/emoticon/emoticon50.gif

froce iT邦大師 1 級 ‧ 2019-11-08 08:08:19 檢舉

這種就要引言給他保留證據啊。

dragonH iT邦超人 5 級 ‧ 2019-11-08 08:45:38 檢舉

以後疑似功課題 先備份再說XD /images/emoticon/emoticon39.gif

1
fillano
iT邦超人 1 級 ‧ 2019-11-12 14:21:06

藉機練習了一下中序式轉後序式並計算後序式...以前都沒好好寫過XD

先準備環境:

  1. makedir mathrun; cd mathrun
  2. npm init
  3. touch index.js
  4. npm i --save minimist

index.js

const args = require('minimist')(process.argv.slice(2));

if(args._.length === 1) {
    main(args._[0]);
} else {
    help();
}

function main(str) {
    console.log(`input:\t\t${str}`);
    let a = tokenize(str);
    console.log(`tokenized:\t${JSON.stringify(a)}`);
    let b = infix2postfix(a);
    console.log(`postfix:\t${JSON.stringify(b)}`);
    let c = calculate(b);
    console.log(`result:\t\t${c[c.length-1]}`);
}

function help() {
    console.log('[Usage] node mathrun {string of math expression to run}')
}

function tokenize(str) {
    str = str.replace(/[ ]+/g, '');//去掉空格
    let ret = [];
    let tmp = '';
    for(let i=0; i<str.length; i++) {
        if(isNaN(parseInt(str[i]))) {
            //非數字,可能是運算子或括號
            if(tmp.length > 0) {
                ret.push(tmp);
                tmp = '';
            }
            switch(str[i]) {
                case '*':
                case '/':
                case '+':
                case '-':
                case '(':
                case ')':
                    ret.push(str[i]);
                    break;
                default:
                    throw new Error(`Illegal Operator: ${str[i]}.`);
            }
        } else {
            //數字
            tmp += str[i];
        }
    }
    if(tmp.length > 0) {
        ret.push(tmp);
    }
    return ret;
}

function infix2postfix(arr) {
    let ret = [];
    let stk = [];
    arr.forEach(s => {
        if(isNaN(parseInt(s))) {
            switch(s) {
                case '(':
                    stk.push(s);
                    break;
                case ')':
                    while(stk.length > 0 && stk[stk.length-1] !== '(') {
                        ret.push(stk.pop());
                    }
                    if(stk[stk.length-1] === '(') stk.pop();
                    break;
                case '*':
                case '/':
                case '+':
                case '-':
                    if(preced(s) > preced(stk[stk.length-1])) {
                        stk.push(s);
                    } else {
                        while(stk.length > 0 && preced(s) <= preced(stk[stk.length-1])) {
                            ret.push(stk.pop())
                        }
                        stk.push(s);
                    }
                    break;
                default:
                    throw new Error(`Illegal Operator: ${s}`);
                    break;
            }
        } else {
            ret.push(s);
        }
    });
    while(stk.length > 0) {
        ret.push(stk.pop());
    }
    return ret;
}

function preced(s) {
    let ret = 0;
    switch(s) {
        case '*':
        case '/':
            ret = 2;
            break;
        case '+':
        case '-':
            ret = 1;
            break;
        default:
            ret = 0;
    }
    return ret;
}

function calculate(arr) {
    let stk = [];
    let op = {
        '+': (arg0, arg1) => arg0 + arg1,
        '-': (arg0, arg1) => arg1 - arg0,
        '*': (arg0, arg1) => arg0 * arg1,
        '/': (arg0, arg1) => arg1 / arg0
    }
    arr.forEach(s => {
        if(isNaN(parseInt(s))) {
            stk.push(op[s](stk.pop(), stk.pop()));
        } else {
            stk.push(parseInt(s));
        }
    });
    return stk;
}

執行起來:

$ node mathrun 1*4+2*3-4/2+3-5+36/6
input:		1*4+2*3-4/2+3-5+36/6
tokenized:	["1","*","4","+","2","*","3","-","4","/","2","+","3","-","5","+","36","/","6"]
postfix:	["1","4","*","2","3","*","+","4","2","/","-","3","+","5","-","36","6","/","+"]
result:		12

有括號的話:

$ node mathrun "(1+2)*(3+4)"
input:		(1+2)*(3+4)
tokenized:	["(","1","+","2",")","*","(","3","+","4",")"]
postfix:	["1","2","+","3","4","+","*"]
result:		21

我要發表回答

立即登入回答