目录
题目描述:
示例1
代码实现:
【华为OD】B\C卷真题 100%通过:字符串统计 C/C++实现
题目描述:
给定两个字符集合,一个为全量字符集,一个为已占用字符集。已占用的字符集中的字符不能再使用,要求输出剩余可用字符集。
输入描述
1、输入为一个字符串,一定包含@符号。@前的为全量字符集,@后的字为已占用字符集。
2、已占用字符集中的字符一定是全量字符集中的字符。字符集中的字符跟字符之间使用英文逗号分隔。
3、每个字符都表示为字符加数字的形式,用英文冒号分隔,比如a:1,表示1个a字符。
4、字符只考虑英文字母,区分大小写,数字只考虑正整形,数量不超过100。
5、如果一个字符都没被占用,@标识仍然存在,例如a:3,b:5,c:2@
输出描述
输出可用字符集,不同的输出字符集之间回车换行。
注意,输出的字符顺序要跟输入一致。不能输出b:3,a:2,c:2
如果某个字符已全被占用,不需要再输出。
示例1
输入输出示例仅供调试,后台判题数据一般不包含示例
输入
a:3,b:5,c:2@a:1,b:2
输出
a:2,b:3,c:2
说明
全量字符集为3个a,5个b,2个c。
已占用字符集为1个a,2个b。
由于已占用字符不能再使用,因此,剩余可用字符为2个a,3个b,2个c。
因此输出a:2,b:3,c:2
代码实现:
#include <string>
#include <map>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>using namespace std;class SData {
public:char k;int cnt;int size;bool operator<(const SData &other) const {return size < other.size;}SData(char key = 0, int cnt = 0, int len = 0) : k(key), cnt(cnt), size(len) {}
};class Solution {public:Solution(const string &s) {int idx = s.find('@');if (idx == string::npos) {dealData(s, false);}else {dealData(s.substr(0, idx), false);dealData(s.substr(idx + 1), true);}vector<SData> tmp(m_data.size());m_vsd = tmp;for (auto &item : m_data) {m_vsd.push_back(item.second);}calc();}string out() const {return m_res;}
private:void calc() {sort(m_vsd.begin(), m_vsd.end());for (auto &e : m_vsd) {if (e.cnt > 0) {m_res.push_back(e.k);m_res.append(":").append(to_string(e.cnt)).append(",");}}m_res.pop_back();}void dealData(const string &s, bool fg) {if (s.empty()) {return;}istringstream ss(s);int size = 0, cnt;char k;while (ss >> k >> cnt) {if (fg) {m_data[k].cnt -= cnt;}else {m_data[k] = { k, cnt, size++ };}}}vector<SData> m_vsd;string m_res;map<char, SData> m_data;
};int main() {string lineStr;getline(cin, lineStr);replace_if(lineStr.begin(), lineStr.end(), [](char c) { return c == ':' || c == ','; }, ' ');Solution so(lineStr);cout << so.out() << endl;return 0;
}