Last active
August 29, 2015 14:08
-
-
Save amoshyc/5f6a417cc41ed3a15cbb to your computer and use it in GitHub Desktop.
uva10008tutor_2.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
在這題裡我們得計錄各個英文字母出現的次數,要實作這個想法有很多寫法,但一般都用陣列就可以了。(因為英文字母在編碼上是連續的) | |
還記得之前統計數字出現次數的程式吧,現在要做的跟那個類似。 | |
只是陣列的使用上不太一樣。 | |
在進入教學之前你得先有個認知:在 C 中,本質上 char 跟 int 是一樣的,因為每個 char 都有個編碼(ascii) | |
所以我們才能寫出:*/ | |
printf("%c\n", 'a'+1); | |
/* 並得到 'b'。C 會自動幫你處理 char 跟 int 之間的轉換。 | |
另外,ascii 中 | |
'A' ~ 'Z' 的編碼是 65 ~ 90。 | |
'a' ~ 'z' 的編碼是 97 ~ 122。 | |
教學一:小寫轉大寫 | |
現在已經有一個字串存在 input 裡,我們希望把 input 裡的所有小寫英文字母都轉大寫。 | |
首先,我們得先判斷該字元是不是小寫英文字母,而不是 '#', '!', '1', etc。 | |
之後,我們就就該字元加上某個數字讓,'a' -> 'A', 'b' -> 'B', ... | |
很明顯的,這個數字是 32,但實作上,我個人是偏好下面這個寫法,這樣我就不用去記 32 這個數字。可讀性也比較高。 | |
*/ | |
for (i=0; i<strlen(input); i++) | |
if ('a' <= input[i] && input[i] <= 'z') | |
input[i] = input[i] - 'a' + 'A'; /*你當然可以寫 input[i] = input[i] - 32;*/ | |
/*善用標準函式庫,在 ctype.h 中有 islower, toupper 兩個函式。所以你可以寫:*/ | |
#include <ctype.h> | |
... | |
for (i=0; i<strlen(input); i++) | |
if (islower(input[i])) /*事實上是寫 if(islower(input[i]) != 0)*/ | |
input[i] = toupper(input[i]); | |
/* | |
教學二:英文字母陣列 | |
因為 'A'~'Z' 的 ascii 是 65~90,所以沒辦法像之前統計數字那樣寫:*/ | |
int cnt[10]; /*分別對應到數字 0 ~ 9,cnt[0] 代表 0 的出現資數;cnt[1] 代表 1 的出現次數……*/ | |
... | |
while (n != 0) { | |
... | |
cnt[digit]++; | |
} | |
/* cnt 陣列是要用來統計各個字母出現次數的陣列。*/ | |
/*你當然可以這樣寫:*/ | |
int cnt[90+1]; | |
/* | |
然後不使用 cnt[0] ~ cnt[64],只用 cnt[65] ~ cnt[90]; | |
但這樣很浪費,一般的寫法是這樣:*/ | |
int cnt[26]; /*26 個英文字母*/ | |
/*然後存取時,用*/ | |
cnt[(c - 'A')] | |
/*c 是正在處理的字元。 | |
如果是 c = 'A',那麼你就變成在存取 cnt[0]。 | |
如果是 c = 'B',那麼你就變成在存取 cnt[1]。 | |
... | |
如果是 c = 'Z',那麼你就變成在存取 cnt[25]。 | |
於是整個程式片斷就是:*/ | |
int cnt[26]; | |
memset(cnt, 0, sizeof(cnt)); /* 這是 string.h 中的函式,相當於將 cnt 的每一項都設為 0。 */ | |
/*至於為什麼要用這個,是因為有些 online judge 用的編輯器版本不支援這種寫法 int cnt[26] = {0}; 。你也可以寫一個 for 來賦值。*/ | |
for (i=0; i<strlen(input); i++) | |
if ('A' <= input[i] && input[i] <= 'Z') /* 也可使用 ctype.h 中的 isalpha,因為我們已經將所有的小寫字母轉大寫了 */ | |
cnt[(input[i] - 'A')]++; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment