同題:UVa 10260 – Soundex
Soundex 編碼根據拼寫將聽起來相似的單詞組合在一起。
例如:「can」和「khawn」,「con」和「gone」。
Soundex 編碼將每個單詞轉換為一組數字,其中每個數字代表一個字母。
以下為Soundex編碼表:
- 1:B、F、P、V
- 2:C、G、J、K、Q、S、X、Z
- 3:D、T
- 4:L
- 5:M、N
- 6:R
Soundex 編碼中未表示字母「A、E、I、O、U、H、W、Y」。
具有相同編碼字母如果相鄰的重複出現僅以一個數字表示。
具有相同編碼的單詞視為相同單字。
範例測資
範例輸入 | 範例輸出 |
---|---|
EOF 輸入,輸入的每一行都包含一個單詞,全部為大寫字母。 單詞長度小於 20 個字母。 | 對於每行,輸出此單詞的 Soundex Code。 |
KHAWN PFISTER BOBBY | 25 1236 11 |
解題思路
使用 Map 來紀錄每一個字元對應的 Soundex Code,並且用字元的方式來紀錄,這樣子可以把答案使用字串的方式加起來。Soundex Code 中沒有的字元就不需要宣告,這些字元在宣告 Map 時會自動預設為 0。
對收到字串的每一個字元做判斷,如果目前字元的 Soundex Code 不為 0,則要判斷這個字元是否為第一個 Soundex Code,可以在迴圈外面宣告一個布林值來確認,如果為第一個 Soundex Code,則將在迴圈外面宣告的字串 ans 變數 (預設為 “”) += Map[目前字元],並且還要在迴圈的外面宣告一個字元 last 代表上一個 Soundex Code,將 last 設為 Map[目前字元]。如果不是第一個 Soundex Code 則要判斷目前的 Soundex Code 是否與 last 一致,如果不一致的話就要將 ans += Map[目前字元],並且要將 last 設為新的 Map[目前字元]。
如果 Soundex Code 為 0,代表之後的要重新做判斷,所以要將 last 設為 ‘0’。
範例程式碼-ZeroJudge E641: Soundex
#include <iostream>
#include <map>
using namespace std;
int main() {
cin.sync_with_stdio(0);
cin.tie(0);
map<char, char>MAP;
MAP['B'] = '1';
MAP['F'] = '1';
MAP['P'] = '1';
MAP['V'] = '1';
MAP['C'] = '2';
MAP['G'] = '2';
MAP['J'] = '2';
MAP['K'] = '2';
MAP['Q'] = '2';
MAP['S'] = '2';
MAP['X'] = '2';
MAP['Z'] = '2';
MAP['D'] = '3';
MAP['T'] = '3';
MAP['L'] = '4';
MAP['M'] = '5';
MAP['N'] = '5';
MAP['R'] = '6';
string str;
while (cin >> str) {
bool first = true;
string ans = "";
char last;
for (int i = 0; i<str.length(); i++) {
const char ch = str[i];
if (MAP[ch] != 0) {
if (first) {
first = false;
ans += MAP[ch];
last = MAP[ch];
}
else {
if (MAP[ch] != last) {
ans += MAP[ch];
last = MAP[ch];
}
}
}
else last = '0';
}
cout << ans << "\n";
}
}
//ZeroJudge E641
//Dr. SeanXD