程式目的:將中序式(infix)轉換為後序式(postfix),並將postfix的值計算出來
程式語言:C 語言
開發工具:Dev-c++ 5.2.0.2
程式碼分享:cpp檔案、exe檔案
執行結果:
程式碼:
演算法:
理所當然的,要了解一個程式得從其演算法開始理解,若是搞懂了,基本上程式就完成7成囉,剩下的只是把這些步驟轉換為程式語言而已!
讓我們先從最基本的開了解:何謂中序式(infix)與後序式(postfix)?infix就是我們一般所寫的算式,將運算子放在運算元的中間,例如1 * ( 2 + 3 );而postfix則是把運算子放在運算元的後面,以剛剛的例子而言, 則變為1 2 3 + *,並且可以注意到我們將括號都拿掉了。這次我們要做的就是從infix變為postfix的方法。
當我們拿到一個算式,首先來分析它的組成。一個算式可以簡單分成運算子(符號)及運算元(數字)兩個部分,處理的時候也大致就是分成兩種來工作:凡是遇到運算元,則直接輸出;遇到運算子則與我們準備好的stack最上層的運算子判斷,若是優先權低於等於stack中的運算子(例如 + → * ),輸出stack中的運算子,直到stack中的運算子優先權較低再把比較的運算子存入stack中,若是比較的stack原本優先權就較高,則直接存入stack中。一直重複上面兩種動作來處理運算子及運算元,直到算式結尾,再把stack中剩下的運算子一次輸出,最後即成我們所要求的postfix運算式。
在轉換的過程中,要注意的是遇到括號需要特別處理,括號可以分為左右括號來看。遇到左括號,無條件存入stack中;遇到右括號,從stack最上層開始輸出,直到遇到左括號為止,左右括號本身都不輸出。
好,現在我們有一個postfix算式了(假設前面沒算錯......),現在該來把它的值計算出來。postfix的計算比起轉換簡單的多,一樣準備一個stack,遇到運算元就丟入stack中,遇到運算子就將stack最上層的兩個數取出來做運算,運算結果再存回stack中,這樣最終stack裡就是我們所求的答案哩!
以上就是本次程式的演算法,若是看不懂,放心不是你太笨,是我表達太差!建議可以參考這位作者的中序式轉後序式以及後序式的運算,寫的相當詳盡喔,同時裡面也有各種語言的程式碼範例,本程式也是以其為架構改寫的。
程式解析:
演算法了解了以後,就來看看這支程式要怎麼實作吧!
本程式分為5個function,分別為main、InToPost、Priority、PostToInt與Cal,main用來做資料的輸入以及輸出,InToPost實作infix與postfix的轉換,Priority比較運算子之間的優先權,PostToInt處理postfix算式的運算,Cal則做兩兩運算元間的計算。
在本程式中,所有的算式以及stack都以陣列來實作,運算元設定為整數,運算子僅處理+ - * / %五種,並且支援正負號,若有其他需要可自行調整,以下就依序來解析。
#define LENGTH 9999
首先在最外面,我們define了一個LENGTH,這個變數代表了未知的陣列長度,可以依需求來調整,通常會給它一個大一點的值,除非我們能明確的知道這個"未知"的範圍是多少。
#include "memory.h"
這個memory.h是用來支援我們在PostToInt所使用的memset,功能是設置陣列的值。
int Err=0;
宣告一個全域變數作為判斷錯誤的依據。
long long int PostToInt(char*);
long long int Cal(char, long long int, long long int);
注意到此處的宣告形態為long long int,是為了因應計算結果可能出現的超長整數,同裡除非我們能確定"值"的範圍,不然預設較寬裕的立場以防錯誤。
int main(void) {...}
main的部分相當單純,在讀入算式之後,分別做轉換、運算以及各自的錯誤判斷。需注意的是錯誤判斷必須分開處理,因為運算邏輯錯誤(例如除以0)只會在計算層面出錯,轉換並無影響。另外印出計算結果因應long long int型態,需使用%lld來取代%d。
void InToPost(char* Infix, char* Postfix) {...}
InToPost在轉換的過程中,除了使用switch case對運算子及運算元做基本的處理之外,最重要的就是大量的錯誤判斷,以下將分別解釋。
for(i = 0; Infix[i] != '\0'; i++){...}
if(temp!=0){...}
在轉換開始之前,先使用一個for loop及if來判斷左右括號的正確性,以temp計算左右括號,左括號+1,右括號-1,如此即可判斷,若是有先右括號再左括號的情形(計算中隨時temp<1),又或是左右括號數量不對(計算完成temp!=0),皆為錯誤。
for(i = 0, j = 0, Stack_Top = 0; Infix[i] != '\0'; i++)
{if(i==0){...}
...
switch(Infix[i]){...}
...}
轉換的最主要部分,一開始的if對首位做判斷,如果是數字當然沒問題,運算子的話,+-可以視為正負號,若是其他的則錯誤。switch case的部分,針對不同狀況做出相對的處理,並且判斷錯誤情形,例如右括號後面不會直接接數字之類,此為數學邏輯故不贅述,詳細的請自行參照程式碼。比較特別的是允許類似--3(減負三)或++7(加正七)的寫法。另外在顯示的部分,每個token之間以一個空格隔開,以助分辨,不然數字會擠在一起(例如13和5變成135)。
int Priority(char op) {...}
簡單的判斷符號的優先權,先乘除後加減,相信大家都會。
long long int PostToInt(char* /*Infix*/Postfix)
{...
switch(Postfix[i]){...}
...}
一樣使用switch case做不同運算子與運算元的處理,由於之前是使用字串做儲存,現在遇到數字先存入另一暫存陣列,並使用atoll轉換為long long int型態後再存入stack。其餘仍為數學邏輯判斷,請自行參考程式碼。
long long int Cal(char op, long long int N1, long long int N2){...}
最後的一個部分,由於邏輯判斷在前面都做過了,這裡單純的把傳來的運算子與運算元做計算即可。
結語:
本程式碼相當簡單,並沒有使用什麼高深的方法,例如A情況會是錯誤的,就單純的加個遇到A則回傳錯誤的判斷,相當的直觀,故應該很容易理解,當然相對的程式優化程度低,效能也會比較差,只希望對有需要的人有所幫助,有任何錯誤也請不吝指教!
2012年11月24日 星期六
2012年9月3日 星期一
ASP.NET MVC 4 Display Modes 實作 PC / Mobile 轉換 (四)後續
在經過了幾次測試之後,我們可以發現,這MVC 4的確有這種隨裝置轉換畫面的功能,可是似乎不是所有裝置都支援?
沒錯,根據實驗結果,目前有完整支援的只有IOS系統以及Windows Phone系列,其他如Android之類都不能確實的判斷,那該怎麼解決好呢?以下就要教大家來實作。
MVC 4無法自動判定IOS和Windows Phone系統以外的裝置,沒關係,我們可以使用它另一個內建的功能,來強制使網頁針對不同的裝置做出正確判斷!
首先讓我們再度開啟Mvc4Internet專案底下的Global.asax.cs檔案。
將上面紅色框框中的程式碼加在檔案的最後,而其中紅字顯示的”Android”,就是我們要讓它判斷的裝置了。
使用這個方法,可以針對各種不同的裝置呈現出不同的畫面,例如Android、iPhone等等,另外也可以指定相異的瀏覽器,如MSIE9。
讓我們以Android為例子,修改完Global.asax.cs檔案之後,只要網頁偵測到使用者是使用Android系列的裝置,自動就會去抓取含有 .Android字樣的 .cshtml檔案。
由於我們只是要測試是否能夠成功轉換,因此只針對首頁用的到的檔案去做變更。
將Index.Mobile.cshtml、_Layout.mobile.cshtml、以及 _LoginPartial.mobile.cshtml三個檔案複製一份,並分別改名為Index.Android.cshtml、_Layout.Android.cshtml、與 _LoginPartial.Android.cshtml,這樣我們就有了Android專用的首頁了。
在開始測試之前,別忘了先對專案進行rebuild。
這時我們可能會碰到一個錯誤,告訴我們剛剛加入的DisplayModeProvider沒有定義!別擔心,將你的滑鼠移過去將它反白起來,會在左下角出現一個圖示,點選以後會出現一個下拉選單,我們選擇第一個選項using System.Web.WebPages,這時候再重新rebuild一次就正常囉,這是由於我們剛剛沒有將DisplayModeProvider所需要的library所import近來。
接下來再打開您的Firefox,隨便選擇一種Android device,這邊以Android 2.2 - HTC
Evo – Mobile Safari 533.1為例子。
選取之後再度執行我們的專案,發現Android裝置也可以正常的判斷為行動裝置,並顯示Android的專用頁面了!
以上使用ASP.NET MVC 4,讓您的網頁在一般PC以及行動裝置上呈現不同的面貌教學告一段落,若有任何錯誤或疑問請不吝指教。
ASP.NET MVC 4 Display Modes 實作 PC / Mobile 轉換 (三)實作
實做步驟:
從這開始我們以Mvc4Internet為主體,將mobile的部分import過來,使得不同的裝置可以顯示不同畫面。
首先,在Mvc4Internet專案底下,新增一個資料夾,我們將它命名為MobileContent,表示這個資料夾是用來擺放行動版的content,並且和PC版的content做個區別。
再來我們將要把原本存放在行動版專案底下的檔案移轉過來,對MobileContent點選右鍵→選擇Add→選擇Existing
Item…來插入現有的檔案。
找到行動版專案Mvc4M obile中的Content資料夾,將底下的7個 .css檔案選起來,並按下Add加入我們的資料夾。
完成之後您的專案應該長這樣。
接下來依照上面的步驟,在MobileContent底下新增一個資料夾,命名為Images。
接著在Images資料夾底下插入現有檔案。
找到Mvc4M obile中的Content底下的Images資料夾,將裡面的檔案全部選擇,並按下Add加入現在的專案中。
完成後您的專案應該長這樣。
這些檔案影響了行動版網頁的版面配置以及圖示。
接著我們要將行動版的 .js檔import近來。
在Mvc4Internet中的Scripts資料夾底下,插入現有檔案。
找到Mvc4M obile中的Scripts資料夾中含有mobile字樣的 .js檔,選取後按下Add按鈕加入目前專案。
這兩個檔案影響了我們頁面以及圖案的連結,並且寫入了滑鼠和觸控時的對應動作。
少了mobile的 .js檔,我們的行動版網頁會變成這樣。
下面我們要處理的是網頁頁面的部分。
若您也是使用新建的專案,在Mvc4Internet以及Mvc4M obile底下的Views中,都會含有Account、Home、Shared等三個資料夾,而其底下的 .cshtml檔案,就是我們的頁面。
將所有Mvc4M obile中Views下的 .cshtml檔案備份後改名,命名原則為在 .cshtml前加上 .mobile,例如原Index.cshtml改名後為Index.mobile.cshtml,並將改名後的檔案import到Mvc4Internet中的相對位置,如原本Index.cshtml是在Home底下,import過來依然要放在Home中。
之後您的Mvc4Internet專案的Views資料夾應該類似上圖所示。
注意 _ViewStart.cshtml這個檔案不需要去動它,此檔案決定了當你開啟網頁時要讀取哪個Layout檔,而由於我們可以自動判讀,因此可以不用管它,若有特殊需要也可以在每個頁面另外指定要讀取的Layout檔案。
接著讓我們開啟
_Layout.mobile.cshtml檔案,由於是直接從另一個專案copy過來的,勢必要做一些調整。
針對圖中紅圈處,將其由原本的
~/Content/css改為
~/MobileContent/css,也就是我們剛剛新建立的,用來放行動版檔案的資料夾,這裡意思是讓它把MobileContent底下的 .css檔全部包起來。
最後讓我們來修改一下Global.asax.cs這個檔案,檔案拉到最下面,將原本的BundleTable.Bundles.RegisterTemplateBundles();
給註解掉,並新加入一行BundleTable.Bundles.EnableDefaultBundles();
。
到這基本的搬移與修改都完成了,讓我們來測試一下吧。
首先點選專案名稱→右鍵→Rebuild,將專案重新建置。
開啟Firefox,點選工具,確認目前的瀏覽器選擇為預設的Default User Agent,也就是說,它就是你安裝的Firefox版本。
執行我們的Mvc4Internet專案,會顯示出PC版的網頁如上圖。
再來讓我們試試看Firefox的模擬功能。
選擇工具,並在選單內選擇一種行動裝置,這裡我們選擇模擬iPhone 3.0。
選好之後重新整理,恭喜您,若沒有設定錯誤,您看到的將會是行動版本的畫面。
這期間我們並沒有重新執行專案,只是在切換瀏覽器狀態後重新整理一次,畫面即由PC版本跳至行動版本,可見我們的自動轉換確實的完成了實做!
ASP.NET MVC 4 Display Modes 實作 PC / Mobile 轉換 (二)建立專案
都安裝好以後就可以開始建置我們的專案了。
首先開起您的Visual
Studio,並選擇建立新專案。
專案精靈跑出來之後,在右上角搜尋處輸入:mvc 4。
若安裝正確,此時會跑出兩個結果,我們選擇Visual C#這個。
下方專案名稱以及儲存位置隨您選擇,我們使用Mvc4Internet來表示這是一個PC版的網頁專案。
設定好以後按下右下角的OK按鈕進入下一步。
在這裡由於要建立PC版網頁專案,所以我們選擇Internet Application。
其他部分使用預設值即可,設定完後我們按下右下角OK按鈕建立專案。
若一切正常,您的新專案應該長這樣。
再來讓我們建立一個行動版網頁專案。
依樣畫葫蘆,另外建立一個新的專案,由於是要給行動版的,我們命名為Mvc4M obile來跟PC版做區隔。
設定完按下右下角的OK按鈕進入下一步。
這裡我們改選Mobile
Application樣板,其他部分一樣使用預設,完成後按OK按鈕建立專案。
您的行動版專案建立好以後應該長這樣。
再來讓我們對行動版專案做一些設定。
首先對您的專案名稱按下右鍵,在選單中找到Manage Nuget Packages…,這就是我們將要使用的小工具。
開啟Manage Nuget
Packages之後,在右上角輸入jquery
mobile,中間結果中的jQuery
Mobile即是我們要安裝的東西,他會幫我們自動建立許多行動版該有的物件。
按下Install按鈕開始安裝。
看到這個小視窗跑出來表示正在安裝中。
安裝完成後會在jQuery
Mobile的右上角看到一個綠色的勾勾,表示正確安裝完成,按下右下角的Close按鈕關閉式窗。
這時候基本的專案已經建立完成了。
讓我們分別來看看專案的樣板模式長什麼樣子。
在Mvc4Internet這個專案中按下F5(預設為Debug),您的PC版專案應該長得像上面這樣子,由於我們什麼都沒編輯,可以看得出來這是MVC 4內建的樣板。
接下來在Mvc4M obile專案中按下F5,您的行動版專案應該長得像上面這樣。
OK!接下來就讓我們開始實做,讓裝置來決定您的網頁該長什麼樣子。
ASP.NET MVC 4 Display Modes 實作 PC / Mobile 轉換 (一)事前準備
本篇要來分享的就是:如何使用微軟的ASP.NET MVC 4中的 Disolay Modes功能,來實作讓您的網頁在一般PC以及行動裝置上呈現不同的面貌。
雖然網路上有不少類似的教學,但是很多都沒有詳細的步驟,不是缺這裡就是缺那裏,故而分享此篇從頭動手做,希望能對有需要的人有更多的幫助。
本次DEMO為在一般PC版網頁專案下加入行動版的網頁,若您已經有完整的PC版以及行動版專案,可以直接從實作部分開始看。
事前準備:
首先最最重要的,我們的工具要先準備好。
您可以在microsoft的網站找到Visual Studio,依據您的需要選擇版本。
再來至ASP.NET的網站下載並安裝ASP.NET MVC 4。
為了之後測試需要,我們還要安裝Firefox外掛套件。
至以下網址下載 .xml檔案並儲存。
下載完以後,還要進行import的動作。
開啟Firefox,點選工具→Default User Agent→Edit User Agents…。
點選左下角的Import…,並找到剛剛下載的 .xml檔案的位置,該檔案名稱為useragentswitcher.xml,選擇並開啟檔案。
這時在您的User Agents欄位中的選項應該有出現類似上面這些項目(或著更多),按下確定按鈕結束,之後我們就可以使用Firefox來模擬各種裝置了。
訂閱:
文章 (Atom)