fcc項(xiàng)目總結(jié)系列2:calculator

begin: 20170804
version: 20170804

該文是對(duì)fcc上計(jì)算器項(xiàng)目的總結(jié)
項(xiàng)目題目在https://freecodecamp.cn/challenges/build-a-javascript-calculator
我完成的項(xiàng)目在https://codepen.io/jacktown/pen/ZJBdPq
其github地址是https://github.com/jacktown11/fcc/tree/master/calculator苇经。

概述

  • 項(xiàng)目利用css3技術(shù)實(shí)現(xiàn)了一個(gè)較有立體感的計(jì)算器界面坟冲;
  • 可以實(shí)現(xiàn)簡單的加、減撮奏、乘揽惹、除、取模運(yùn)算,用戶在輸入過程中可以取消上步輸入谊却、清空所有輸入;
  • 每次用戶有輸入時(shí)js都會(huì)判斷當(dāng)前輸入的算式是否合法哑芹,如果不合法讓算式顯示為紅色炎辨,以提示用戶有輸入錯(cuò)誤;
  • 支持結(jié)果引用聪姿,但是在結(jié)果為大數(shù)(采用科學(xué)計(jì)數(shù)法表示)時(shí)碴萧,會(huì)有一點(diǎn)問題,但總體不影響使用末购;
  • 不支持高級(jí)數(shù)學(xué)函數(shù)破喻、括號(hào),總體功能比較初級(jí)盟榴。

npm和gulp

該項(xiàng)目在整個(gè)項(xiàng)目過程中采用了npm包管理工具來下載依賴文件曹质,安裝gulp來實(shí)現(xiàn)文件的自動(dòng)化壓縮、導(dǎo)出,對(duì)我來說是一個(gè)新技能的應(yīng)用嘗試咆繁。

界面

界面的實(shí)現(xiàn)主要技術(shù)點(diǎn)是CSS3陰影讳推,實(shí)現(xiàn)了計(jì)算器邊緣立體效果、按鈕的陰影效果玩般、顯示行內(nèi)嵌效果银觅。

寫css過程中遇到的一個(gè)難點(diǎn)是:要讓輸入的算式靠在右邊且不換行,這本可以直接text-align:center;white-space:nowrap;就OK的坏为,但是當(dāng)算式很長時(shí)究驴,文本行卻是靠著顯示框左邊框開始顯示的,右側(cè)的文本顯示到了顯示框之外匀伏,把overflowhidden以后洒忧,結(jié)果顯示框內(nèi)顯示的就是算式開始部分而不是結(jié)尾部分。怎么解決呢够颠?將顯示的文本再包裹上一個(gè)行內(nèi)塊元素熙侍,絕對(duì)定位right:0;,不設(shè)寬度履磨,當(dāng)然還要右對(duì)齊不換行蛉抓,這樣文本右側(cè)總是對(duì)齊在顯示框的右邊了。

在解決上述難點(diǎn)的過程中剃诅,我考慮過讓文本方向從右往左(text-direction:rtl;)巷送,然后在js生成文本顯示是將文本本身翻轉(zhuǎn)一下,這樣就正常右對(duì)齊了矛辕,但是還是不行笑跛,因?yàn)槲谋緩挠彝箫@示是指單詞的顯示順序,然而單詞內(nèi)部的字母卻仍舊是從左往右的聊品!而瀏覽器對(duì)單詞的識(shí)別又不簡單地使用空格飞蹂,由于算式中有小數(shù)點(diǎn)、運(yùn)算符杨刨、數(shù)字晤柄,要把算式文本調(diào)整得符合瀏覽器的識(shí)別方法,其過程會(huì)十分復(fù)雜妖胀。故放棄了這種方案。

算法

該項(xiàng)目界面比較簡單惠勒,除了CSS3外赚抡,主要技術(shù)點(diǎn)都集中在算法上,主要包括四個(gè)方面:

  • 根據(jù)用戶輸入識(shí)別操作數(shù)和操作符
  • 根據(jù)用戶輸入進(jìn)行數(shù)據(jù)的壓入纠屋、回退涂臣、清空等操作
  • 算式合法性檢驗(yàn)
  • 算式計(jì)算

輸入識(shí)別與處理

這兩個(gè)比較細(xì)節(jié),難度并不大。有兩個(gè)思路:

  • 程序直接保存用戶輸入的字一個(gè)長字符串赁遗,每次新輸入后都將這個(gè)長字符串重新解析出操作數(shù)和操作符數(shù)組署辉,那么每次新輸入的計(jì)算都應(yīng)該是O(n)的時(shí)間復(fù)雜度,但是這樣的好處是編程會(huì)相對(duì)清晰一點(diǎn)岩四;
  • 程序保存根據(jù)之前輸入已經(jīng)處理好的操作數(shù)和操作符數(shù)組哭尝,新輸入時(shí)修改這個(gè)數(shù)組。

經(jīng)過該過程以后剖煌,用戶的輸入被處理成一個(gè)算式數(shù)組材鹦,數(shù)組元素是操作符或操作數(shù)。

算式合法性檢驗(yàn)

檢驗(yàn)依據(jù):

  • 算式第一項(xiàng)必須是操作數(shù)或正負(fù)號(hào)
  • 算式最后一項(xiàng)必須是操作數(shù)
  • 操作數(shù)和操作符必須相間出現(xiàn)
  • 單獨(dú)出現(xiàn)的小數(shù)點(diǎn)非法

另外還需要區(qū)分檢驗(yàn)的算式是要立馬用于計(jì)算(用戶點(diǎn)擊了=號(hào))還是后續(xù)還有輸入耕姊。

算式計(jì)算

其中算式計(jì)算相對(duì)復(fù)雜桶唐,有一個(gè)極簡的思路是利用eval()全局函數(shù),直接將用戶輸入的字符串傳入計(jì)算茉兰,得到結(jié)果尤泽,主要問題在于:無法解決浮點(diǎn)數(shù)計(jì)算誤差問題。

為了程序的完善及出于練習(xí)編程的考慮规脸,我選擇了自己根據(jù)算式字符串編寫算法坯约,算法的主要思路如下:

  • 首先算式必須通過合法性檢驗(yàn),之后進(jìn)行計(jì)算燃辖;
  • 計(jì)算分兩步進(jìn)行:先計(jì)算乘鬼店、除、取模高優(yōu)先級(jí)運(yùn)算黔龟,再進(jìn)行加減運(yùn)算妇智;
  • 首先進(jìn)行乘、除氏身、取模運(yùn)算巍棱,我們稱它們?yōu)橐患?jí)操作符,在算式數(shù)組中從左往右找到第一個(gè)一級(jí)操作符蛋欣,將其左右兩個(gè)操作數(shù)用該操作符運(yùn)算得到一個(gè)結(jié)果航徙,將該操作符及其左右兩個(gè)操作數(shù)從算式數(shù)組中剔除,將計(jì)算得到的結(jié)果插入到它們的位置上(利用Array的splice方法可以輕松實(shí)現(xiàn))陷虎。重復(fù)這一查找到踏、計(jì)算、剔除尚猿、插入的過程窝稿,直到算式數(shù)組中不存在一級(jí)運(yùn)算。此后按照同樣的方法進(jìn)行二級(jí)運(yùn)算凿掂。二級(jí)運(yùn)算完畢后伴榔,算式數(shù)組長度為1,其內(nèi)容就是計(jì)算結(jié)果。

上面提到了:計(jì)算中會(huì)出現(xiàn)浮點(diǎn)數(shù)計(jì)算不準(zhǔn)確的問題踪少,比如0.01+0.2的準(zhǔn)確結(jié)果是0.3塘安,但是程序計(jì)算結(jié)果可能類似0.210000000000004,這是由于計(jì)算機(jī)用二進(jìn)制保存浮點(diǎn)數(shù)的精度限制所致援奢。怎樣解決呢兼犯?我們可以將所有浮點(diǎn)運(yùn)算轉(zhuǎn)換為整數(shù)運(yùn)算,如這個(gè)式子我們可以計(jì)算1+20的結(jié)果然后除以100萝究,就可以得到準(zhǔn)確結(jié)果了免都。這個(gè)處理需要貫穿到上述所說的算法的實(shí)現(xiàn)中。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末帆竹,一起剝皮案震驚了整個(gè)濱河市绕娘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌栽连,老刑警劉巖险领,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異秒紧,居然都是意外死亡绢陌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門熔恢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脐湾,“玉大人,你說我怎么就攤上這事叙淌〕诱疲” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵鹰霍,是天一觀的道長闻鉴。 經(jīng)常有香客問我,道長茂洒,這世上最難降的妖魔是什么孟岛? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮督勺,結(jié)果婚禮上渠羞,老公的妹妹穿的比我還像新娘。我一直安慰自己智哀,他們只是感情好堵未,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盏触,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赞辩,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天雌芽,我揣著相機(jī)與錄音,去河邊找鬼辨嗽。 笑死世落,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的糟需。 我是一名探鬼主播屉佳,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼洲押!你這毒婦竟也來了武花?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤杈帐,失蹤者是張志新(化名)和其女友劉穎体箕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挑童,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡累铅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了站叼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娃兽。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖尽楔,靈堂內(nèi)的尸體忽然破棺而出投储,到底是詐尸還是另有隱情,我是刑警寧澤翔试,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布轻要,位于F島的核電站,受9級(jí)特大地震影響垦缅,放射性物質(zhì)發(fā)生泄漏冲泥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一壁涎、第九天 我趴在偏房一處隱蔽的房頂上張望凡恍。 院中可真熱鬧,春花似錦怔球、人聲如沸嚼酝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闽巩。三九已至钧舌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間涎跨,已是汗流浹背洼冻。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留隅很,地道東北人撞牢。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像叔营,于是被迫代替她去往敵國和親屋彪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line)绒尊,也就是一...
    悟名先生閱讀 4,148評(píng)論 0 13
  • 上一篇文章畜挥,我們一起探討了選擇有效需求的三個(gè)建議其中的第一個(gè)建議,判斷需求是否符合產(chǎn)品本身的定位垒酬,這篇文章我們繼續(xù)...
    枯葉咖啡館閱讀 368評(píng)論 0 3
  • 不知不覺已經(jīng)在簡書注冊(cè)了快2年了砰嘁,14年年初的時(shí)候偶然在微博上發(fā)現(xiàn)簡書這個(gè)寫作平臺(tái),便一開始懷著情懷勘究,開始自己一天...
    山楂葉閱讀 244評(píng)論 2 2
  • 桃花落 紅顏傷 又見前世宿緣 誰的心 未曾變 只怨輕許了誓言 空負(fù)那如花美...
    紫雁博達(dá)閱讀 165評(píng)論 0 2
  • 這兩天知乎熱門上有一個(gè)問題是“男朋友一直逼我減肥,欲哭無淚我該怎么辦景描?“注意十办,題主用了一個(gè)“逼”字,說明并非本意超棺。...
    瓶子樂悠悠閱讀 1,786評(píng)論 0 1