經過這周學校的綜合實驗,本身寫的程序終於從之前的黑框框變成了一個真正能讓人看的程序。因爲有必定的基礎,因此並不會感到很是的難,如下是我遇到的一些相對比較棘手的問題。算法
計算器四則運算優先級老師要用棧去實現,就去翻了翻數據結構書,思路大概以下:
所包含的運算符有‘+’,‘-’,‘*’,‘/’, 表達式爲字符串。數組
(1)創建兩個棧,一個用來存儲操做數,另外一個用來存儲運算符, 開始時在運算符棧中先壓入‘/0’,表達式的結束符。數據結構
(2)而後從左至右依次讀取表達式中的各個符號(操做數或者運算符);工具
(3)若是讀到的是操做數直接存入操做數棧;google
(4)若是讀到的是運算符,則做進一步判斷:spa
若讀到的運算符的優先級等於或小於以前的運算符的優先級,則從操做數中退出2個,從運算符中退出一個進行運算,將運算結果存入操做數棧;再把以前讀到的運算符與目前的運算符棧頂比較,重複步驟(4)(即如今不讀下一個元素);code
若讀到的是‘/0’結束符,並且此時運算符棧的棧頂元素也是‘/0’結束符,則運算結束,輸出操做數棧中的元素即爲最後結果。orm
// 進行運算 private double Calculate(string operators, string numbers) { // 將數字和操做符字符串存到數組當中 string[] numberarray = Regex.Split(numbers, " "); string[] operatorarray = Regex.Split(operators, " "); Stack numberStack = new Stack();// 數字棧 Stack operatorStack = new Stack();// 操做符棧 // 先將前兩個數字和一個操做符push到棧中 numberStack.Push(Convert.ToDouble(numberarray[0])); numberStack.Push(Convert.ToDouble(numberarray[1])); operatorStack.Push(operatorarray[0]); // 當遍歷完操做符數組且棧中操做符爲空時跳出循環 for (int i = 1; i < operatorarray.Length || !operatorStack.IsEmpty();) { // 當操做符棧爲空時,push一個數字和一個操做符 if (operatorStack.IsEmpty()) { numberStack.Push(Convert.ToDouble(numberarray[i + 1])); operatorStack.Push(operatorarray[i]); i++;continue; } // 當棧頂操做符爲+或者-時 if (operatorStack.getTop().Equals("+") || operatorStack.getTop().Equals("-")) { if (i < operatorarray.Length) { // 當下一個操做符不是最後一個操做符時 // 若是下一個操做符爲*或者/,則push一個數字和操做符 if (operatorarray[i].Equals("*") || operatorarray[i].Equals("/")) { numberStack.Push(Convert.ToDouble(numberarray[i + 1])); operatorStack.Push(operatorarray[i]); i++; } else {// 不然,棧內進行加減運算,將結果push到棧頂,下同 double after = Convert.ToDouble(numberStack.Pop()); double pre = Convert.ToDouble(numberStack.Pop()); string op = operatorStack.Pop().ToString(); switch (op) { case "+": { numberStack.Push(pre + after); continue; } case "-": { numberStack.Push(pre - after); continue; } default: continue; } } } else {// 若是沒有下一個操做符,則棧內進行加減運算 double after = Convert.ToDouble(numberStack.Pop()); double pre = Convert.ToDouble(numberStack.Pop()); string op = operatorStack.Pop().ToString(); switch (op) { case "+": { numberStack.Push(pre + after); continue; } case "-": { numberStack.Push(pre - after); continue; } default: continue; } } } else {// 若是棧頂操做符爲*或者/,則棧內直接進行乘除運算 double after = Convert.ToDouble(numberStack.Pop()); double pre = Convert.ToDouble(numberStack.Pop()); string op = operatorStack.Pop().ToString(); switch (op) { case "*": { numberStack.Push(pre * after); continue; } case "/": { numberStack.Push(pre / after); continue; } default: continue; } } } // 取出棧頂元素做爲結果返回 object result = numberStack.Pop(); return Convert.ToDouble(result); }
編輯功能一開始沒什麼太好的方法,就用了一個比較「猥瑣」的方式:ip
而編輯窗口本質就是一個自帶默認數據的增長窗口。資源
// 點擊編輯按鈕 private void EditButton_Click(object sender, EventArgs e) { // 若是有被選中的項 if (listView1.SelectedItems.Count != 0) { // 將選中行的信息封裝到person中 Person editPerson = new Person { Id = listView1.SelectedItems[0].SubItems[0].Text, Name = listView1.SelectedItems[0].SubItems[1].Text, Sex = listView1.SelectedItems[0].SubItems[2].Text, WorkPlace = listView1.SelectedItems[0].SubItems[3].Text, Phone = listView1.SelectedItems[0].SubItems[4].Text, Email = listView1.SelectedItems[0].SubItems[5].Text }; // 打開編輯窗口,將person傳入 editForm = new Edit(editPerson); editForm.Show(); // 刪除選中行的信息 DeleteSelectCol(); // 從新加載數據 Display(); } }
而接下來就出現問題了,以下圖,編輯窗口的任務並無結束,但表格已經把選中的信息給刪了。
後來我去google,簡單的瞭解到這是因爲我啓動編輯窗口時以show()的方式啓動,而show是非模態顯示,另外一個和它功能相近的方法是showDialog()模態顯示,兩者區別是:
模態顯示後:
非模態顯示後:
因此當我用show()顯示編輯時,下面的DeleteSelectCol()方法會當即執行。
因此,最後我改用showDialog()來顯示編輯窗口,當點擊保存時,窗口狀態返回OK,而且將DeleteSelectCol()的條件改成窗口返回狀態。
最後改寫的代碼以下: