【华为OD-E卷 - 找出两个整数数组中同时出现的整数 100分(python、java、c++、js、c)】
题目
现有两个整数数组,需要你找出两个数组中同时出现的整数,并按照如下要求输出:
有同时出现的整数时,先按照同时出现次数(整数在两个数组中都出现并目出现次数较少的那个)进行归类,然后按照出现次数从小到大依次按行输出。 没有同时出现的整数时,输出NULL
输入描述
- 第一行为第一个整数数组,第二行为第二个整数数组,每行数中整数与整数之间以英文号分,整数的取值范用为[-200, 200],数组长度的范用为[1, 10000]之间的整数
输出描述
- 按照出现次数从小到大依次按行输出,每行输出的格式为:
出现次数:该出现次数下的整数升序排序的结果
格式中的":"为英文冒号,整数间以英文逗号分隔
用例
用例一:
输入:
5,3,6,-8,0,11
2,8,8,8,-1,15
输出:
NULL
用例二:
输入:
5,8,11,3,6,8,8,-1,11,2,11,11
11,2,11,8,6,8,8,-1,8,15,3,-9,11
输出:
1:-1,2,3,6
3:8,11
说明 两整数数组中同时出现的整数为-12、3、6、8、11,其中同时出现次数为1的整数为-1,2,3,6(升序排序),同时出现次数为3的整数为8,11(升序排序),先升序输出出现次数为1的整数,再升序输出出现次数为3的整数
python解法
- 解题思路:
- 本题目是通过两组整数的输入来计算它们的公共元素和各自的频率,并输出每个频率下的公共元素。具体来说,我们需要完成以下几步:
输入处理:
用户输入两行整数序列,每个整数序列是由逗号分隔的。
统计频率:
对每个序列中的整数,统计它们的出现次数。
寻找公共元素及其频率:
找出两个序列中共同出现的元素,并记录它们在每个序列中出现的次数。对于每个公共元素,记录它们在两个序列中出现的最小次数。
输出结果:
根据每个公共元素的最小次数,按从小到大的顺序输出这些元素
# 将输入字符串解析为整数列表
def parse(input_str):
return list(map(int, input_str.split(',')))
# 计算列表中每个元素出现的频率
def count_freq(arr):
freq = {} # 用字典存储频率
for n in arr:
if n in freq:
freq[n] += 1 # 如果元素已经存在,增加计数
else:
freq[n] = 1 # 如果元素不存在,初始化为1
return freq
# 找出两个频率字典中的共同元素,并记录最小出现次数
def find_common(m1, m2):
result = {} # 存储公共元素和它们的最小出现次数
for n, count in m1.items(): # 遍历第一个频率字典
if n in m2: # 如果元素在第二个频率字典中也有
min_count = min(count, m2[n]) # 取两个字典中最小的出现次数
if min_count in result:
result[min_count].add(n) # 如果该次数已经存在,添加元素
else:
result[min_count] = {n} # 否则初始化为一个集合
return result
# 打印结果,按出现次数排序
def print_result(res_map):
if not res_map: # 如果没有公共元素
print("NULL")
else:
for count, nums in sorted(res_map.items()): # 按出现次数排序
print(f"{count}:{','.join(map(str, sorted(nums)))}") # 按元素大小排序输出
# 主函数
def main():
l1 = input() # 输入第一个整数序列
l2 = input() # 输入第二个整数序列
a1 = parse(l1) # 将第一个输入解析为整数列表
a2 = parse(l2) # 将第二个输入解析为整数列表
m1 = count_freq(a1) # 统计第一个列表的频率
m2 = count_freq(a2) # 统计第二个列表的频率
res_map = find_common(m1, m2) # 查找两个频率字典中的公共元素
print_result(res_map) # 输出结果
if __name__ == "__main__":
main() # 执行主函数
java解法
- 解题思路
更新中
C++解法
- 解题思路
- 本题目要求从两组由逗号分隔的整数列表中找出它们的公共元素,并按照每个公共元素在两个列表中出现的最小次数进行排序输出。具体思路如下:
输入处理:
用户输入两行包含逗号分隔的整数序列。
统计频率:
对每个序列中的整数,统计它们的出现次数。
查找公共元素:
找出两个序列中共同出现的元素,并记录它们在每个序列中出现的次数。对于每个公共元素,记录它们在两个序列中出现的最小次数。
输出结果:
根据每个公共元素的最小次数,按从小到大的顺序输出这些元素。
#include <iostream>
#include <vector>
#include <sstream>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
// 解析输入的逗号分隔的字符串并返回整数数组
vector<int> parse(const string& in) {
vector<int> res;
stringstream ss(in); // 将字符串流化,便于逐个读取数字
string itm;
while (getline(ss, itm, ',')) { // 按逗号分割字符串
res.push_back(stoi(itm)); // 将每个分割的部分转为整数并加入结果数组
}
return res;
}
// 统计数组中元素的出现次数
map<int, int> countFreq(const vector<int>& arr) {
map<int, int> freq;
for (int n : arr) {
freq[n]++; // 将每个元素出现的次数存入频率字典
}
return freq;
}
// 生成两数组的共同元素及其最小出现次数的映射
map<int, set<int>> findCommon(const map<int, int>& m1, const map<int, int>& m2) {
map<int, set<int>> res;
for (const auto& it : m1) { // 遍历第一个数组的频率字典
int n = it.first; // 获取元素
if (m2.count(n)) { // 如果该元素在第二个数组中也出现
int cnt = min(it.second, m2.at(n)); // 取该元素在两个数组中出现的最小次数
res[cnt].insert(n); // 将该元素和最小次数插入到结果字典中
}
}
return res;
}
// 打印结果
void printResult(const map<int, set<int>>& resMap) {
if (resMap.empty()) { // 如果结果为空,表示没有公共元素
cout << "NULL" << endl;
}
else {
// 遍历结果字典,按次数升序输出
for (const auto& it : resMap) {
cout << it.first << ":"; // 输出出现次数
bool fst = true; // 用于控制元素之间的分隔符
for (int n : it.second) { // 输出每个最小次数对应的公共元素
if (!fst) cout << ",";
cout << n;
fst = false;
}
cout << endl; // 每个结果后换行
}
}
}
// 主函数
int main() {
string l1, l2;
getline(cin, l1); // 读取第一行输入
getline(cin, l2); // 读取第二行输入
vector<int> a1 = parse(l1); // 将第一行输入解析为整数数组
vector<int> a2 = parse(l2); // 将第二行输入解析为整数数组
map<int, int> m1 = countFreq(a1); // 统计第一个数组中每个元素的频率
map<int, int> m2 = countFreq(a2); // 统计第二个数组中每个元素的频率
map<int, set<int>> resMap = findCommon(m1, m2); // 查找两个数组中的共同元素及其最小出现次数
printResult(resMap); // 打印结果
return 0; // 程序执行完毕,返回
}
C解法
输入处理:
用户输入两行包含逗号分隔的整数序列,分别转换为两个整数数组。
统计频率:
对每个序列中的整数,统计它们的出现次数。
查找公共元素:
找出两个序列中共同出现的元素,并记录它们的最小出现次数。
排序并输出结果:
根据每个公共元素的最小出现次数,按从小到大的顺序输出这些元素
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 1000
// 解析输入的逗号分隔的字符串并返回整数数组,返回数组的长度
int parse(const char* str, int* arr) {
int count = 0;
// 使用strdup复制字符串并按逗号分割
char* token = strtok(strdup(str), ",");
while (token != NULL) {
arr[count++] = atoi(token); // 将分割出的数字字符串转为整数并存入数组
token = strtok(NULL, ",");
}
return count; // 返回数组长度
}
// 统计数组中每个元素出现的频率,频率存储在freq数组中
void count_freq(int* arr, int n, int* freq, int* count) {
for (int i = 0; i < n; i++) {
int found = 0;
// 遍历freq数组,查找当前元素是否已经出现过
for (int j = 0; j < *count; j++) {
if (freq[2 * j] == arr[i]) { // 如果该元素已经存在
freq[2 * j + 1]++; // 频率加一
found = 1;
break;
}
}
if (!found) { // 如果当前元素是新元素
freq[2 * (*count)] = arr[i]; // 存储元素值
freq[2 * (*count) + 1] = 1; // 初始化频率为1
(*count)++; // 更新频率数组的元素数量
}
}
}
// 查找两个数组中公共元素及其最小频率,结果存储在result数组中
void find_common(int* freq1, int count1, int* freq2, int count2, int* result, int* result_count) {
for (int i = 0; i < count1; i++) {
for (int j = 0; j < count2; j++) {
// 如果两个频率数组中的元素相同
if (freq1[2 * i] == freq2[2 * j]) {
int min_count = freq1[2 * i + 1] < freq2[2 * j + 1] ? freq1[2 * i + 1] : freq2[2 * j + 1];
result[2 * (*result_count)] = min_count; // 存储最小出现次数
result[2 * (*result_count) + 1] = freq1[2 * i]; // 存储元素值
(*result_count)++; // 更新结果数组中的元素数量
break;
}
}
}
}
// 打印结果,按照频率升序,并且按元素升序输出
void print_result(int* result, int result_count) {
if (result_count == 0) { // 如果没有公共元素
printf("NULL\n");
}
else {
// 对结果进行排序,首先按出现次数排序,然后按元素值排序
for (int i = 0; i < result_count - 1; i++) {
for (int j = i + 1; j < result_count; j++) {
if (result[2 * i] > result[2 * j] || // 如果次数较大则交换
(result[2 * i] == result[2 * j] && result[2 * i + 1] > result[2 * j + 1])) {
int temp1 = result[2 * i];
int temp2 = result[2 * i + 1];
result[2 * i] = result[2 * j];
result[2 * i + 1] = result[2 * j + 1];
result[2 * j] = temp1;
result[2 * j + 1] = temp2;
}
}
}
// 按照排序后的结果输出
for (int i = 0; i < result_count; i++) {
// 按照次数分组,每个次数对应的元素放在一起
if (i == 0 || result[2 * i] != result[2 * (i - 1)]) {
if (i > 0) {
printf("\n");
}
printf("%d:", result[2 * i]); // 输出出现次数
}
printf("%d", result[2 * i + 1]); // 输出对应的元素
if (i != result_count - 1 && result[2 * (i + 1)] == result[2 * i]) {
printf(","); // 如果下一个元素属于同一组,则打印逗号
}
}
printf("\n");
}
}
// 主函数
int main() {
char line1[MAX_SIZE], line2[MAX_SIZE];
fgets(line1, MAX_SIZE, stdin); // 读取第一行输入
fgets(line2, MAX_SIZE, stdin); // 读取第二行输入
int arr1[MAX_SIZE], arr2[MAX_SIZE];
int n1 = parse(line1, arr1); // 解析第一个输入数组
int n2 = parse(line2, arr2); // 解析第二个输入数组
int freq1[2 * MAX_SIZE], freq2[2 * MAX_SIZE]; // 存储频率信息的数组
int count1 = 0, count2 = 0;
count_freq(arr1, n1, freq1, &count1); // 统计第一个数组中每个元素的频率
count_freq(arr2, n2, freq2, &count2); // 统计第二个数组中每个元素的频率
int result[2 * MAX_SIZE]; // 存储公共元素及其最小出现次数
int result_count = 0;
find_common(freq1, count1, freq2, count2, result, &result_count); // 查找公共元素及其最小出现次数
print_result(result, result_count); // 打印结果
return 0;
}
JS解法
更新中
注意:
如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏