题目
给定一个乱序的数组,删除所有重复元素,使得每个元素只出现一次,并且按照出现的次数从高到低进行排序
相同出现次数按照第一次出现顺序进行先后排序,数组大小不超过100
,数组元素值不超过100
输入
一个数组
输出
去重排序后的数组
示例一
输入
1,3,3,3,2,4,4,4,5
输出
3,4,1,2,5
思路
解题思路:
-
读取输入 :首先通过
fgets
函数读取用户输入的一行整数,以逗号为分隔符。然后使用strtok
函数将这行字符串分割成一个个整数,并将它们存入一个临时数组nums
中。 -
统计频率 :创建一个大小为100的数组
frequency
来记录每个数字在nums
数组中的出现次数。遍历nums
数组,对每个元素对应的索引在frequency
数组中进行计数。 -
构建结构体数组 :定义一个名为
Elements
的结构体,包含三个字段:num
(存储元素值)、frequency
(存储元素出现次数)和first
(存储元素首次出现的位置)。创建一个大小为100的elem
结构体数组,遍历frequency
数组,将非零频率的元素信息填充到elem
数组中。【注:由于qsort快速排序是不稳定的排序,排序之后直接输出的话可能满足不了"相同出现次数按照第一次出现顺序进行先后排序",所以需要标记元素首次出现的位置】
-
填充首次出现位置 :再次遍历原始的
nums
数组与elem
结构体数组,找到并记录每个元素在nums
数组中的首次出现位置。 -
排序结构体数组 :自定义一个比较函数
cmp
,根据元素出现频率从高到低进行排序,频率相同时按照首次出现顺序排序。利用qsort
函数对elem
结构体数组进行排序。 -
输出结果 :遍历排序后的
elem
结构体数组,输出其中的num
字段,即为去重且按要求排序后的数组元素,之间用逗号分隔。
代码
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义一个结构体,用于存储数组元素的值、出现频率和第一次出现的位置
typedef struct {
int num; // 数组元素的值
int frequency; // 元素在原数组中的出现次数
int first; // 元素在原数组中第一次出现的位置
} Elements;
// 自定义比较函数,用于对排序所需的结构体数组进行排序
int cmp(const void *a, const void *b) {
Elements *e1 = (Elements *)a;
Elements *e2 = (Elements *)b;
// 按照出现频率从高到低排序
if (e1->frequency != e2->frequency) {
return e2->frequency - e1->frequency;
}
// 相同频率时按照首次出现顺序排序
else {
return e1->first - e2->first;
}
}
int main() {
char input[101]; // 读取一行输入作为字符串
fgets(input, 101, stdin);
input[strcspn(input, "\n")] = '\0'; // 去掉末尾换行符
int nums[100]; // 存储原始整数数组
int count = 0;
char *token = strtok(input, ","); // 使用strtok函数分割输入字符串
while (token != NULL) {
nums[count++] = atoi(token); // 将分割出的字符串转换为整数并存入数组
token = strtok(NULL, ",");
}
int frequency[100] = {0}; // 初始化一个数组用于记录每个数字的出现频率
for (int i = 0; i < count; i++) {
frequency[nums[i]]++; // 统计各元素出现次数
}
Elements elem[100]; // 创建结构体数组用于存储元素信息
int elem_len = 0;
// 遍历频率数组,将非零频率的元素信息存入结构体数组
for (int i = 0; i < 100; i++) {
if (frequency[i] != 0) {
elem[elem_len].num = i;
elem[elem_len].frequency = frequency[i];
elem_len++;
}
}
// 遍历原始数组nums与结构体数组elem,填充每个元素的首次出现位置
for (int i = 0; i < elem_len; i++) {
for (int j = 0; j < count; j++) {
if (elem[i].num == nums[j]) {
elem[i].first = j;
break; // 跳出内部循环
}
}
}
// 使用qsort函数对结构体数组按照cmp函数定义的规则进行排序
qsort(elem, elem_len, sizeof(Elements), cmp);
// 输出排序后的去重数组
for (int i = 0; i < elem_len; i++) {
printf("%d", elem[i].num);
if (i != elem_len - 1) {
printf(",");
}
}
return 0;
}