按照降序打印数字及其频率

01 引言

在日常工作和生活中,我们经常需要对数据进行分析和处理,其中涉及到的数字及其频率是非常重要的指标之一。最常见的需求是按照数字出现的频率进行排序,并以降序方式将其打印出来。这不仅有助于我们更好地了解数据的分布情况,还能帮助我们更好地进行决策。

本文将介绍如何使用C++语言编写一个简单的程序,实现按照降序打印数字及其频率的功能。我们将从程序设计和实现的角度出发,逐步介绍实现过程中需要考虑的各个方面。

02 问题分析

2.1 需求概述

在分析需求之前,我们先来定义一下要完成的任务。假设有一个序列,其中包含若干个数字。现在需要按照降序打印这些数字及其出现的频率,即先将出现频率较高的数字打印出来,再依次打印出现频率较低的数字。

例如,对于以下序列:

5 6 6 6 5 4 3 3

按照降序打印输出的结果应该为:

6:3

5:2

3:2

4:1

其中,数字6出现了3次,数字5出现了2次,数字3出现了2次,数字4出现了1次。

2.2 设计思路

分析需求之后,我们需要确定如何实现这个功能。从程序的功能来看,需要完成以下几个步骤:

输入待排序的数字序列

对数字序列进行统计,得到每个数字出现的频率

将统计结果按照出现频率降序排序

将排序结果打印输出

从以上步骤我们可以看出一个大致的设计思路。我们需要设计一个类或者函数,包含以上四个功能,并逐一实现。

03 程序实现

3.1 数据结构

在实现统计和排序功能时,我们需要定义一些数据结构来存储数据。这里介绍两种常用的数据结构:

数组(Array)

映射(Map)

3.1.1 数组

数组是一种基础的数据结构,具有以下特点:

连续的内存空间,快速随机访问

线性结构,适用于存储有限个数的元素

对于读操作效率高,对于插入和删除操作效率较低

在实现统计功能时,可以定义一个数组,用来存储每个数字出现的频率。

3.1.2 映射

映射是一种将键映射到值的数据结构,也称为字典(Dictionary)或关联数组(Associative Array)。具有以下特点:

键值对存储,适用于存储任意数量的元素

对于读和写操作效率均较高

内存使用较高,适用于存储小规模的元素

映射的实现方式有很多,常见的有红黑树、散列表等。在C++ STL中提供了一个容器类std::map,用于实现映射功能。

3.2 统计功能的实现

对于输入的序列,我们可以使用数组或映射来实现统计功能。以下代码使用数组来实现:

void count(const std::vector& nums, std::vector& freq) {

for (auto x : nums) {

freq[x]++;

}

}

以上代码中的输入参数nums为待统计的数字序列,freq为用于存储统计结果的数组。函数中使用了C++11的range-based for语法,遍历整个数字序列,将每个数字出现的频率加1。

使用映射来实现统计功能的代码如下:

void count(const std::vector& nums, std::map& freq) {

for (auto x : nums) {

freq[x]++;

}

}

以上代码中的输入参数nums和输出参数freq与数组实现时相同。不同的是,这里使用了C++ STL提供的容器std::map,将每个数字及其出现的频率存储在映射中。

3.3 排序功能的实现

对于排序功能,可以使用C++ STL中的排序算法std::sort来实现。以下代码将使用映射来存储统计结果,将按照降序排序:

void sort(const std::map& freq, std::vector>& sorted) {

for (auto kvp : freq) {

sorted.push_back(kvp);

}

std::sort(sorted.begin(), sorted.end(), [](std::pair& a, std::pair& b) {

return a.second > b.second;

});

}

以上代码中的输入参数freq为统计结果,输出参数sorted为排序结果,使用了由键值对组成的向量std::vector>来存储。首先将统计结果中的每个键值对加入到向量中,然后使用std::sort对向量中的元素按照出现频率降序排序,排序函数中使用了一个lambda表达式,定义了如何比较两个键值对的顺序。

3.4 输出功能的实现

输出功能比较简单,只需要按照格式输出排序结果即可。以下代码使用了数组来存储统计结果,使用基本的for循环进行输出:

void print(const std::vector& freq) {

for (int i = N - 1; i >= 0; i--) {

if (freq[i] > 0) {

std::cout << i << ":" << freq[i] << std::endl;

}

}

}

以上代码中的输入参数freq为统计结果,输出数字和出现频率。从大到小遍历数组,输出不为0的数字及其出现频率。

如果使用映射来存储统计结果,则可以直接遍历映射进行输出。以下代码使用了映射来实现输出功能:

void print(const std::map& freq) {

for (auto kvp : freq) {

std::cout << kvp.first << ":" << kvp.second << std::endl;

}

}

以上代码中的输入参数freq为统计结果的映射,直接遍历映射中的键值对进行输出。

3.5 完整代码实现

将以上的统计、排序和输出功能组合在一起,即可得到完整的实现代码。以下代码使用数组来存储统计结果,以及进行输出:

#include <iostream>

#include <vector>

const int N = 1000000;

void count(const std::vector& nums, std::vector& freq) {

for (auto x : nums) {

freq[x]++;

}

}

void sort(const std::vector& freq, std::vector>& sorted) {

for (int i = N - 1; i >= 0; i--) {

if (freq[i] > 0) {

sorted.push_back({ i, freq[i] });

}

}

std::sort(sorted.begin(), sorted.end(), [](std::pair& a, std::pair& b) {

return a.second > b.second;

});

}

void print(const std::vector& freq) {

for (int i = N - 1; i >= 0; i--) {

if (freq[i] > 0) {

std::cout << i << ":" << freq[i] << std::endl;

}

}

}

int main() {

std::vector nums = { 5, 6, 6, 6, 5, 4, 3, 3 };

std::vector freq(N, 0);

count(nums, freq);

std::vector> sorted;

sort(freq, sorted);

print(freq);

return 0;

}

如果使用映射来存储统计结果,则完整代码如下:

#include <iostream>

#include <vector>

#include <map>

void count(const std::vector& nums, std::map& freq) {

for (auto x : nums) {

freq[x]++;

}

}

void sort(const std::map& freq, std::vector>& sorted) {

for (auto kvp : freq) {

sorted.push_back(kvp);

}

std::sort(sorted.begin(), sorted.end(), [](std::pair& a, std::pair& b) {

return a.second > b.second;

});

}

void print(const std::map& freq) {

for (auto kvp : freq) {

std::cout << kvp.first << ":" << kvp.second << std::endl;

}

}

int main() {

std::vector nums = { 5, 6, 6, 6, 5, 4, 3, 3 };

std::map freq;

count(nums, freq);

std::vector> sorted;

sort(freq, sorted);

print(freq);

return 0;

}

04 总结

本文介绍了如何使用C++语言实现按照降序打印数字及其频率的功能。分别从数据结构、统计、排序和输出四个方面逐一介绍,希望能够对读者有所帮助。

C++语言拥有强大的库函数和容器,使得程序的实现更加高效和简洁。在实际工作和学习中,可以灵活运用各种数据结构和算法,这有助于提升开发效率和代码的可维护性。

后端开发标签