接觸C#語言只有短短幾天時間,想要寫出什麼高大上的深入性研究文章,估計也是滿篇的猜想和一些沒有邏輯的推論。截至目前而言,從語言入門知識(大多數程式設計師的入門儀式——輸出「Hello,world!」)、資料和資料類型、資料運算、程式功能實現流程和循環、陣列和集合這些分塊的小知識到將所學知識串連應用,並沒有承受太大的困難, 像是在用描述的語言來解應用題,再透過程式碼將這些描述的語句表達出來。
記得開班時做了三道趣味題。第一題是主人運送草、羊和狼過河,狼吃羊,羊吃草,主人看管情況不會發生任何事,一次只能運送一樣過河,這道題給我的感覺是用來引導學員思維方式,順便觀察學員是否有一個清晰的思路來分析和解答問題,找到關鍵點就是羊隻能單獨存在或隨主人一起,這樣就能很好的解決問題。第二題是三個和尚和三個怪物過河,只有一隻空船,船一次可以運兩人,每當出現怪物數量大於和尚數量,遊戲就結束了,這道題也是考驗思考問題的方式,但是也要注意怪物和和尚運輸流程的正確性,必須保證和尚安全的先全部到達對岸,圍繞這個中心來解決問題。第三題印像比較深刻,做完後,旁邊的同學說可以27s,然後我就進行了反覆的嘗試(只能是29s)。要求是利用一盞只能亮30s的燈引導5人過橋,一次只能兩人持燈通過,5人所需時間分別為1s、3s、6s、8s、12s當然,這題要抓住重點,就是盡量將1s小孩用來反方向運燈,而且必須將12s的老人和8s的胖子一趟完成通過,在多次嘗試中,我發現只要保證1s的小孩返回兩趟,3s小孩返回一趟,耗時最長的兩位一次通過,不管其餘怎樣排序設置,都不會影響到最後的結果。
回顧這個有意義的開課儀式,再回到C#的世界中,其實兩者有很多的共同之處,現在就寫一下不同代碼的同樣實現效果這一回事!
先舉一個簡單的例子,在求水仙花數時,需要將一個百位數的每一位的數值進行求解,答案中給出的程式碼是這樣的:
int i = 100;while (i < 1000) { int a = i / 100 % 10; int b = i / 10 % 10; int c = i % 10; if (a * a * a + b * b * b + c * c * c == i) { Console.WriteLine(i); } i++; }
而我在解答時使用了兩個不同的方法,第一種是:
int i = 100;while (i < 1000)
{ int a = i /100; int b = i % 10 / 10; int c = i % 10; if (a * a * a + b * b * b + c * c * c == i)
{
Console.WriteLine(i);
}
i++;
}
###################################### ##### 第二種方法是:##################
int i = 100;while (i < 1000) { int a = i / 100; int b = (i - a * 100) / 10; int c = i -a * 100 - b * 10; if (a * a * a + b * b * b + c * c * c == i) { Console.WriteLine(i); } i++; }###### 以上皆是正確的、可實現的程式碼,程式碼之所以存在差異,就是在運算時,對問題分析和思考的角度不同。第一種是將所求位數後面的內容拋棄,再將剩餘的數對10取餘,因為切除後剩餘的數的個位總是對應所求位數的值。第二種也是將這個數拆分,將這個數對所求位數的10的倍數求餘,將所求位數之前的數全部拋棄,得到的是的第一位總是所求位數的值,再用除法就能得到想要的值。第三種就是個死辦法,多餘的全減再除就可以了。總而言之,不同的思路、不同的解題方法,並不會影響程式碼的實現,但是選擇簡短、優雅的程式碼,能夠提高整個程式碼的美感,這一點還是需要注意。就自己感悟而言,肯定是優先選擇自己能夠理解的代碼,這樣用起來才會得心應手,同時可要擴大自己的見識,多想想不同的思路的實現方式。 ############ ######### 但是,說到這裡,也許有人會有質疑,上面就是一道數學題,和編碼的思路有什麼關係。那麼再來看我和其餘人不同的實現思路,這個問題是關於建立一個數組並賦值後,#######讓用戶輸入一個要查找的數字,判斷該數字在數組中是否存在。 ###############
int[] nums = { 4, 8, 12, 333, -9, 1 };bool isFind = false;for (int i = 0; i < nums.Length; i++) { if (nums[i] == n) { isFind = true; break; } }if (isFind) { Console.WriteLine("数组中存在该数"); }else{ Console.WriteLine("数组中不存在该数"); }### ############# 我思考的方法是:#########
int[] nums = { 4, 8, 12, 333, -9, 1 }; Console.Write("请输入需要查找的数字:");int input2 = int.Parse(Console.ReadLine());for (int i = 0; i < 5; i++) { if (nums[i] == input2) Console.WriteLine("在数组中查找到该数值,该数为数组中的第" + (i + 1) + "项!"); if(i==4&&nums[i]!=input2) Console.WriteLine("未在数组中找到对应项!"); }
第一种代码是通过定义一个bool类型数据isFind,如果找到,就改变isFind的数据,然后通过isFind的数据完成实现。而我在思考时,是想如果没有找到,那么循环完成后循环次数就会达到最大值,但是此时最后一位数与输入的数相同,两个输出对应条件都能满足,所以,排查到最后并且最后一位的值也不等,才能满足输出未找到结果。通过这样的分析,就写出了这两段代码。这就是不同思路采用不同代码来实现相同功能的方式。
关于不同代码实现相同功能,还有一个最经典的例子,是不能不提的,那就是数组和集合的排序,下面介绍三种思路:交换排序、冒泡排序和选择排序。
交换排序中心思想是从第一个数组项开始,固定nums[i],依次第i+1个后面的数据进行比较,如果有比num[i]小的值,就对其进行交换。
for( int i = 0; i < arrays.Length - 1; i++) { for(int j = i+1; j < arrays.Length; j++) { if(arrays[i]>arrays[j]) { int temp=arrays[i]; arrays[i]=arrays[j]; arrays[j]=temp; } } }
冒泡排序是将最大的数沉到底部,先将最后一个位置固定,再从第一个数开始比较,每遇到一个大的数,这个数就与后一位交换,就像气泡一样,这个变动的寻找中的值越滚越大,直到最后一位。这时,再确定倒数第二位,再次进行替换。(第二个for循环中,每次循环,nums[j]的值总是逐渐变大。)实现代码如下:
for(int i = nums.Length - 1; i > 0; i--) { for(int j = 0; j < i; j++) { if( nums[j] > nums[j+1] ) { int temp = nums[j]; nums[j] = nums[j+1]; nums[j+1] = temp; } } }
选择排序从第一个数开始,先假设第一个数为最小的数,将其与后面每一个数进行比较,如果遇到小的,就记录这个数的下标,循环完成后,记录的下标对应的数一定是数据组的最小值,此时替换最小值到第一位。后面依次循环,完成排序。
for(int i = 0; i < nums.Length - 1; i++) { int index = 1; for(int j = i+1; j < nums.Length; j++) { if(nums[j])<nums[index]) { index=j; } } int temp = nums[i]; nums[i] = nums[index]; nums[index] = temp; }
有上面三种排序方法可以看出,只要能够实现功能,思路和代码并不重要。只要能找到解决问题的关键点,并围绕关键点弄懂解决问题的方法,根据方法确定流程,再完成代码的编写,这样想要达到功能的实现并不难。不过为了整个代码的便于查看和修改,在使用这些代码时,在能够理解代码书写的思路前提下,尽量使用结构优良,语句简洁的语句。当然,如果一些方法难以理解,最好还是使用自己理解的代码书写,便于自己完成查看和修改,如果必要,注释也是必不可少。
总而言之,多观察别人的思路,多看多想多开拓,总是没有坏处。毕竟是编程,难以理解或者使用不熟练,解决的方法还是多练多敲,没有其他的捷径。
以上是C#中關於程式功能實現以及對程式碼選擇的思考的詳細內容。更多資訊請關注PHP中文網其他相關文章!