題目敘述
每筆測資第一行有一個正整數N,接下來會有N行,每行有一個包含空格字元的字串。要求由大到小輸出每一個字元出現的字數 (只需要紀錄英文字母的出現次數即可)。大小寫的字母視為同一個字元,輸出時輸出大寫的字母。如果有出現次數同樣的情況,優先輸出字母排序較為前面的字元,如A和B同樣次數,則會先輸出A再輸出B。
範例輸入 #1
3
This is a test.
Count me 1 2 3 4 5.
Wow!!!! Is this question easy?
範例輸出 #1
S 7
T 6
I 5
E 4
O 3
A 2
H 2
N 2
U 2
W 2
C 1
M 1
Q 1
Y 1
解題思路
先使用一個Map來存取每一個字元出現的次數,可以使用isalpha來判斷目前字元是否為英文字母,並使用toupper來將英文字母轉換成大寫的型態做Map的Key。再來使用Auto跑Map的For迴圈,並且再宣告一個新的Map (Key: int|Value: Vector<char>),這個新的Map是存有哪些字元出現在同一個次數上。因為題目要求要由大排到小,所以將次數乘以-1並將其字元Push_Back到新的Map中。輸出時也是用Auto跑新Map的迴圈,先將新的Map的Vector進行排序,然後再跑一個新的Map中Vector的For迴圈,將裡面的字元和目前Key乘以-1 (剛剛乘以-1現在要復原) 進行輸出。
解題程式碼如下 (僅供參考):
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
pair<int, char> rtn (int a, char b)
{
pair<int, char>tmp;
tmp.first = a;
tmp.second = b;
return tmp;
}
int main() {
cin.sync_with_stdio(0);
cin.tie(0);
int N;
cin >> N;
string a;
getline(cin, a);
map<char, int>MAP;
for (int i = 0; i<N; i++)
{
string str;
getline(cin, str);
for (int j = 0; j<str.length(); j++)
{
if (isalpha(str[j])) MAP[toupper(str[j])]++;
}
}
map<int, vector<char>>ans;
for (auto it:MAP)
{
ans[it.second * -1].push_back(it.first);
}
for (auto it:ans)
{
vector<char>result = it.second;
int num = it.first * -1;
sort(result.begin(), result.end());
for (int i = 0; i<result.size(); i++)
{
cout << result[i] << " " << num << "\n";
}
}
}
留言
張貼留言