#C7. 华为OD机试统一考试D卷C卷 - 全量和已占用字符集 、字符串统计
华为OD机试统一考试D卷C卷 - 全量和已占用字符集 、字符串统计
题目链接
华为OD机试统一考试D卷C卷 - 全量和已占用字符集 、字符串统计(C++ Java JavaScript Python)
https://blog.csdn.net/banxia_frontend/article/details/134430918
题目描述: 全量和已占用字符集 、字符串统计(分值100)
给定两个字符集合,一个是全量字符集,一个是已占用字符集,已占用字符集中的字符不能再使用。 要求输出剩余可用字符集。
输入描述
- 输入一个字符串 一定包含@,@前为全量字符集 @后的为已占用字符集
- 已占用字符集中的字符一定是全量字符集中的字符
- 字符集中的字符跟字符之间使用英文逗号隔开
- 每个字符都表示为字符+数字的形式用英文冒号分隔,比如a:1标识一个a字符
- 字符只考虑英文字母,区分大小写
- 数字只考虑正整型 不超过100
- 如果一个字符都没被占用 @标识仍存在,例如 a:3,b:5,c:2@
输出描述
- 输出可用字符集
- 不同的输出字符集之间用回车换行
- 注意 输出的字符顺序要跟输入的一致,如下面用例不能输出b:3,a:2,c:2
- 如果某个字符已全部占用 则不需要再输出
用例
输入
a:3,b:5,c:2@a:1,b:2
输出
a:2,b:3,c:2
说明
全量字符集为三个a,5个b,2个c 已占用字符集为1个a,2个b 由于已占用字符不能再使用 因此剩余可用字符为2个a,3个b,2个c 因此输出a:2,b:3,c:2
C++
#include <iostream>
#include <vector>
#include <unordered_map>
#include <sstream>
int main() {
std::string input;
std::getline(std::cin, input);
// 将输入字符串按照@符号分割为全量字符集和已占用字符集
std::string fullCharacterSet = input.substr(0, input.find("@"));
std::string occupiedCharacterSet = input.substr(input.find("@") + 1);
// 创建字符列表,用于存储全量字符集中的字符及其对应的数量
std::vector<std::pair<std::string, int>> characterList;
// 将全量字符集按照逗号分割为单个字符
std::stringstream fullCharacterSetStream(fullCharacterSet);
std::string character;
while (std::getline(fullCharacterSetStream, character, ',')) {
// 将字符按照冒号分割为字符和数量
std::string characterSplit = character.substr(0, character.find(":"));
int count = std::stoi(character.substr(character.find(":") + 1));
characterList.push_back(std::make_pair(characterSplit, count)); // 将字符和数量添加到字符列表中
}
// 如果已占用字符集为空,则输出全量字符集
if (occupiedCharacterSet.empty()) {
std::cout << fullCharacterSet << "@" << std::endl;
return 0;
}
// 创建已占用字符集的哈希表,用于存储已占用字符及其对应的数量
std::unordered_map<std::string, int> occupiedCharacters;
// 将已占用字符集按照逗号分割为单个字符
std::stringstream occupiedCharacterSetStream(occupiedCharacterSet);
while (std::getline(occupiedCharacterSetStream, character, ',')) {
// 将字符按照冒号分割为字符和数量
std::string characterSplit = character.substr(0, character.find(":"));
int count = std::stoi(character.substr(character.find(":") + 1));
occupiedCharacters[characterSplit] = count; // 将字符和数量添加到已占用字符集的哈希表中
}
// 遍历字符列表中的每个字符
for (int i = 0; i < characterList.size(); i++) {
std::string character = characterList[i].first;
int count = characterList[i].second;
// 如果已占用字符集中包含当前字符
if (occupiedCharacters.count(character) > 0) {
count -= occupiedCharacters[character]; // 计算剩余可用数量
if (count > 0) {
characterList[i].second = count; // 更新字符列表中的数量为剩余可用数量
} else {
characterList.erase(characterList.begin() + i); // 如果剩余可用数量为0,则移除当前字符
i--; // 由于移除了一个字符,需要将索引减1
}
}
}
// 构建输出字符串
std::stringstream result;
for (const auto& character : characterList) {
result << character.first << ":" << character.second << ","; // 将每个字符及其数量添加到输出字符串中
}
std::string output = result.str();
output = output.substr(0, output.length() - 1); // 删除最后一个逗号
std::cout << output << std::endl; // 输出结果
return 0;
}
JavaScript
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', (input) => {
// 将输入字符串按照@符号分割为全量字符集和已占用字符集
const splitInput = input.split("@");
const fullCharacterSet = splitInput[0]; // 全量字符集
const occupiedCharacterSet = splitInput[1]; // 已占用字符集
// 创建字符列表,用于存储全量字符集中的字符及其对应的数量
const characterList = [];
// 将全量字符集按照逗号分割为单个字符
const fullCharacterSetSplit = fullCharacterSet.split(",");
// 遍历全量字符集的每个字符
for (const character of fullCharacterSetSplit) {
// 将字符按照冒号分割为字符和数量
const characterSplit = character.split(":");
characterList.push(characterSplit); // 将字符和数量添加到字符列表中
}
// 如果已占用字符集为空,则输出全量字符集
if (occupiedCharacterSet === "") {
console.log(fullCharacterSet + "@");
process.exit(0);
}
// 创建已占用字符集的哈希表,用于存储已占用字符及其对应的数量
const occupiedCharacters = {};
// 将已占用字符集按照逗号分割为单个字符
const occupiedCharacterSetSplit = occupiedCharacterSet.split(",");
// 遍历已占用字符集的每个字符
for (const character of occupiedCharacterSetSplit) {
// 将字符按照冒号分割为字符和数量
const characterSplit = character.split(":");
occupiedCharacters[characterSplit[0]] = parseInt(characterSplit[1]); // 将字符和数量添加到已占用字符集的哈希表中
}
// 遍历字符列表中的每个字符
for (let i = 0; i < characterList.length; i++) {
const character = characterList[i];
// 如果已占用字符集中包含当前字符
if (character[0] in occupiedCharacters) {
const count = parseInt(character[1]) - occupiedCharacters[character[0]]; // 计算剩余可用数量
if (count > 0) {
character[1] = count.toString(); // 更新字符列表中的数量为剩余可用数量
} else {
characterList.splice(i, 1); // 如果剩余可用数量为0,则移除当前字符
i--; // 由于移除了一个字符,需要将索引减1
}
}
}
// 构建输出字符串
let result = "";
for (const character of characterList) {
result += character[0] + ":" + character[1] + ","; // 将每个字符及其数量添加到输出字符串中
}
result = result.slice(0, -1); // 删除最后一个逗号
console.log(result); // 输出结果
rl.close();
});
Java
import java.util.Scanner;
import java.util.ArrayList;
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取输入字符串
String input = scanner.nextLine();
// 将输入字符串按照@符号分割为全量字符集和已占用字符集
String[] splitInput = input.split("@");
String fullCharacterSet = splitInput[0]; // 全量字符集
String occupiedCharacterSet = splitInput[1]; // 已占用字符集
// 创建字符列表,用于存储全量字符集中的字符及其对应的数量
ArrayList<String[]> characterList = new ArrayList<>();
// 将全量字符集按照逗号分割为单个字符
String[] fullCharacterSetSplit = fullCharacterSet.split(",");
// 遍历全量字符集的每个字符
for (String character : fullCharacterSetSplit) {
// 将字符按照冒号分割为字符和数量
String[] characterSplit = character.split(":");
characterList.add(characterSplit); // 将字符和数量添加到字符列表中
}
// 如果已占用字符集为空,则输出全量字符集
if (occupiedCharacterSet.isEmpty()) {
System.out.println(fullCharacterSet + "@");
System.exit(0);
}
// 创建已占用字符集的哈希表,用于存储已占用字符及其对应的数量
HashMap<String, Integer> occupiedCharacters = new HashMap<>();
// 将已占用字符集按照逗号分割为单个字符
String[] occupiedCharacterSetSplit = occupiedCharacterSet.split(",");
// 遍历已占用字符集的每个字符
for (String character : occupiedCharacterSetSplit) {
// 将字符按照冒号分割为字符和数量
String[] characterSplit = character.split(":");
occupiedCharacters.put(characterSplit[0], Integer.parseInt(characterSplit[1])); // 将字符和数量添加到已占用字符集的哈希表中
}
// 遍历字符列表中的每个字符
for (int i = 0; i < characterList.size(); i++) {
String[] character = characterList.get(i);
// 如果已占用字符集中包含当前字符
if (occupiedCharacters.containsKey(character[0])) {
int count = Integer.parseInt(character[1]) - occupiedCharacters.get(character[0]); // 计算剩余可用数量
if (count > 0) {
character[1] = Integer.toString(count); // 更新字符列表中的数量为剩余可用数量
} else {
characterList.remove(i); // 如果剩余可用数量为0,则移除当前字符
i--; // 由于移除了一个字符,需要将索引减1
}
}
}
// 构建输出字符串
StringBuilder result = new StringBuilder();
for (String[] character : characterList) {
result.append(character[0]).append(":").append(character[1]).append(","); // 将每个字符及其数量添加到输出字符串中
}
result.deleteCharAt(result.length() - 1); // 删除最后一个逗号
System.out.println(result.toString()); // 输出结果
}
}
Python
import sys
# 读取输入字符串
input = sys.stdin.readline().strip()
# 将输入字符串按照@符号分割为全量字符集和已占用字符集
splitInput = input.split("@")
fullCharacterSet = splitInput[0] # 全量字符集
occupiedCharacterSet = splitInput[1] # 已占用字符集
# 创建字符列表,用于存储全量字符集中的字符及其对应的数量
characterList = []
# 将全量字符集按照逗号分割为单个字符
fullCharacterSetSplit = fullCharacterSet.split(",")
# 遍历全量字符集的每个字符
for character in fullCharacterSetSplit:
# 将字符按照冒号分割为字符和数量
characterSplit = character.split(":")
characterList.append(characterSplit) # 将字符和数量添加到字符列表中
# 如果已占用字符集为空,则输出全量字符集
if occupiedCharacterSet == "":
print(fullCharacterSet + "@")
sys.exit(0)
# 创建已占用字符集的哈希表,用于存储已占用字符及其对应的数量
occupiedCharacters = {}
# 将已占用字符集按照逗号分割为单个字符
occupiedCharacterSetSplit = occupiedCharacterSet.split(",")
# 遍历已占用字符集的每个字符
for character in occupiedCharacterSetSplit:
# 将字符按照冒号分割为字符和数量
characterSplit = character.split(":")
occupiedCharacters[characterSplit[0]] = int(characterSplit[1]) # 将字符和数量添加到已占用字符集的哈希表中
# 遍历字符列表中的每个字符
i = 0
while i < len(characterList):
character = characterList[i]
# 如果已占用字符集中包含当前字符
if character[0] in occupiedCharacters:
count = int(character[1]) - occupiedCharacters[character[0]] # 计算剩余可用数量
if count > 0:
character[1] = str(count) # 更新字符列表中的数量为剩余可用数量
else:
characterList.pop(i) # 如果剩余可用数量为0,则移除当前字符
i -= 1 # 由于移除了一个字符,需要将索引减1
i += 1
# 构建输出字符串
result = ""
for character in characterList:
result += character[0] + ":" + character[1] + "," # 将每个字符及其数量添加到输出字符串中
result = result[:-1] # 删除最后一个逗号
print(result) # 输出结果
C语言
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxsize 1000
// 定义字符和数量的结构体
typedef struct {
char ch[26]; // 存储字符
int count; // 存储该字符的数量
} CharStr;
int main() {
char input[maxsize]; // 用于存储输入的字符串
fgets(input, maxsize, stdin); // 从标准输入读取一行
// 分割全量字符集和已占用字符集
char* fullSet = strtok(input, "@"); // 分割出全量字符集
char* occSet = strtok(NULL, "\n"); // 分割出已占用字符集
// 定义两个字符数组,分别存储全量和已占用字符集的信息
CharStr fullList[maxsize]; // 存储全量字符集
int fullcnt = 0; // 全量字符集中的元素计数
CharStr occList[maxsize]; // 存储已占用字符集
int occcnt = 0; // 已占用字符集中的元素计数
// 解析全量字符集字符串
char* token = strtok(fullSet, ",");
while (token != NULL) {
sscanf(token, "%[^:]:%d", fullList[fullcnt].ch, &fullList[fullcnt].count); // 解析字符和数量
fullcnt++;
token = strtok(NULL, ",");
}
// 解析已占用字符集字符串
if (occSet != NULL) {
token = strtok(occSet, ",");
while (token != NULL) {
sscanf(token, "%[^:]:%d", occList[occcnt].ch, &occList[occcnt].count); // 解析字符和数量
occcnt++;
token = strtok(NULL, ",");
}
}
// 计算剩余字符集
for (int i = 0; i < fullcnt; i++) {
for (int j = 0; j < occcnt; j++) {
if (strcmp(fullList[i].ch, occList[j].ch) == 0) { // 比较字符是否相同
fullList[i].count -= occList[j].count; // 减去已占用的数量
break;
}
}
}
// 构建并输出最终的可用字符集
char temp[100]; // 临时存储每个字符及其剩余数量
char ans[100] = {0}; // 存储最终结果的字符串
for (int i = 0; i < fullcnt; i++) {
if (fullList[i].count > 0) {
sprintf(temp, "%s:%d,", fullList[i].ch, fullList[i].count); // 格式化字符串
strcat(ans, temp); // 连接到结果字符串
}
}
int len = strlen(ans);
if (len > 0) ans[len-1] = '\0'; // 去除最后一个逗号
printf("%s", ans); // 输出结果
return 0;
}
完整用例
用例1
a:3,b:5,c:2@a:1,b:2
用例2
a:1,b:2,c:3@a:1,b:2,c:3
用例3
x:10,y:20,z:30@x:5,y:10,z:15
用例4
m:7,n:8,o:9@m:2,n:4,o:6
用例5
x:1,y:2,z:3@x:1,y:1,z:3
用例6
a:10,b:20,c:30@a:1,b:2,c:3
用例7
a:3,b:5,c:2@a:1,b:2
用例8
a:3,b:5,c:2@a:0,b:0,c:0
用例9
l:1,t:3,u:5,v:7@l:1,t:2,u:3,v:4
用例10
d:5,e:5,f:5@d:2,e:3,f:4
@[TOC]