问题描述 给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出。 输入格式 输入的第一行包含一个整数n,表示给定数字的个数。 输出格式 输出多行,每行包含两个整数,分别表示一个给定的整数和它出现的次数。按出现次数递减的顺序输出。如果两个整数出现的次数一样多,则先输出值较小的,然后输出值较大的。 样例输入 12 样例输出 3 4 评测用例规模与约定 1 ≤ n ≤ 1000,给出的数都是不超过1000的非负整数。 |
#include <stdio.h>
int main() {
int n; // 输入的整数个数
int i, j, k = 1, d, temp;
int a[1000]; // 存储输入的整数
int b[1000], c[1000]; // b[i] 表示整数 c[i] 出现的次数
scanf("%d", &n); // 读入整数个数
for (i = 1; i <= n; i++) {
scanf("%d", &a[i]); // 读入整数
b[i] = 0;
c[i] = 0;
}
// 对整数进行排序
for (i = 1; i <= n; i++) {
for (j = i + 1; j <= n; j++)
if (a[i] > a[j]) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
// 统计每个整数出现的次数
for (i = 1; i <= n;) {
for (j = i; j <= n; j++) {
if (a[i] == a[j]) {
c[k] = a[i];
b[k]++;
}
if (a[i] != a[j]) {
i = j;
k++;
}
}
}
// 按照出现次数递减的顺序排序
for (i = 1; i <= k; i++) {
for (j = i + 1; j <= k; j++)
if (b[i] < b[j]) {
temp = c[i];
c[i] = c[j];
c[j] = temp;
temp = b[i];
b[i] = b[j];
b[j] = temp;
} else if (b[i] == b[j] && c[i] > c[j]) { // 如果出现次数相同,则按照值的大小排序
temp = c[i];
c[i] = c[j];
c[j] = temp;
}
}
// 输出结果
for (i = 1; i < k; i++) {
printf("%d %d\n", c[i], b[i]);
}
}
结果报错运行超时
改进优化
#include <stdio.h>
#include <stdlib.h>
#define MAXN 1000 // 定义数组的最大长度
int a[MAXN + 1]; // 存储输入的整数
int b[MAXN + 1];
int c[MAXN + 1]; // 存储不同的整数
int cnt[MAXN + 1]; // cnt[i] 表示整数 i 出现的次数
// 比较函数,用于快速排序
int cmp(const void *a, const void *b) {
int x = *(int *)a;
int y = *(int *)b;
if (cnt[x] != cnt[y]) { // 如果出现次数不同,则按照出现次数排序
return cnt[y] - cnt[x];
} else { // 如果出现次数相同,则按照值的大小排序
return x - y;
}
}
int main() {
int n; // 输入的整数个数
scanf("%d", &n); // 读入整数个数
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]); // 读入整数
cnt[a[i]]++; // 统计每个整数出现的次数
}
int k = 0; // 不同整数的个数
for (int i = 1; i <= MAXN; i++) {
if (cnt[i] > 0) { // 如果整数 i 出现过
c[++k] = i; // 将其存入数组 c 中
}
}
qsort(c + 1, k, sizeof(int), cmp); // 使用快速排序对数组 c 进行排序
for (int i = 1; i <= k; i++) { // 输出结果
printf("%d %d\n", c[i], cnt[c[i]]);
}
}
快速排序(QuickSort)是一种基于分治策略的排序算法。它通过选择一个基准元素(pivot),然后将给定数组中的其他元素分成两个子数组,根据它们是否小于或大于基准元素来进行划分。快速排序的关键过程是划分(partition)。划分的目标是将基准元素放在其在已排序数组中的正确位置,并将所有小于基准元素的元素放在基准元素的左边,所有大于基准元素的元素放在基准元素的右边。划分过程会递归地在基准元素两侧的子数组上进行,最终完成整个数组的排序 ¹。
哈希表(Hash Table)也称为哈希映射(Hash Map),是一种实现关联数组或字典的数据结构。它是一种抽象数据类型,用于将键映射到值。哈希表使用哈希函数来计算索引,也称为哈希码,然后根据索引在桶或槽的数组中查找所需的值。在查找时,键被哈希,生成的哈希值指示存储相应值的位置。理想情况下,哈希函数会将每个键分配到唯一的桶中,但大多数哈希表设计都采用不完美的哈希函数,这可能导致哈希冲突,即哈希函数为多个键生成相同的索引。这些冲突通常以某种方式进行处理。在设计良好的哈希表中,每次查找的平均时间复杂度与存储在表中的元素数量无关 ⁵。
快速排序和哈希表都可以用来优化算法。例如,在上面给出的代码中,我们使用快速排序来对整数进行排序,并使用哈希表来统计每个整数出现的次数。这样可以大大提高算法的效率。