C++ 如何从最大值到最小值组织数组中的前10个频繁值?

C++ 如何从最大值到最小值组织数组中的前10个频繁值?,c++,arrays,C++,Arrays,我正在做一个家庭作业,叫做强力球号码的彩票统计。PowerBall编号被创建到一个文本文件中。在我解释我的问题之前,一个强力球有5个从1到69的数字,第六个数字是球,是从1到26的数字。我在程序中做的第一件事是创建一个数组来传递文件中的所有值,然后我将一个数组中的5个幂和另一个数组中的球分开。现在的问题是,我一直在试图找出如何在持有异能的数组和持有球的数组中找到前10个常用数字 为了解决这个问题,我使用了一个频率函数,并试图比较数组中每个值的频率,但最终得到了每个值以随机顺序出现的次数。我想使用

我正在做一个家庭作业,叫做强力球号码的彩票统计。PowerBall编号被创建到一个文本文件中。在我解释我的问题之前,一个强力球有5个从1到69的数字,第六个数字是球,是从1到26的数字。我在程序中做的第一件事是创建一个数组来传递文件中的所有值,然后我将一个数组中的5个幂和另一个数组中的球分开。现在的问题是,我一直在试图找出如何在持有异能的数组和持有球的数组中找到前10个常用数字

为了解决这个问题,我使用了一个频率函数,并试图比较数组中每个值的频率,但最终得到了每个值以随机顺序出现的次数。我想使用排序算法,但它不起作用,因为我试图显示数字及其频率,而排序算法只会帮助我显示频率,而不是按顺序显示数字和频率

作为参考,我使用的值为:

39  12  21  23  67  6
33  43  60  59  15  4
25  16  32  49  19  4
54  50  21  64  68  4
44  62  20  37  16  12
66  52  50  24  25  5
10  53  50  63  14  21
67  30  34  16  53  21
69  36  45  47  18  14
45  5   59  55  50  14
代码:

#包括
#包括
#包括
#包括
使用名称空间std;
//功能原型。
无效功率值(int[10][6]、int[10]、int[10][5];
int频率26(int[10],int);
int频率69(int[][5],int);
int main()
{
整数[10][6];
int powerBall26[10];
int powerBall69[10][5];;
//函数将文件中的值存储在相应的变量中。
功率值(num、powerBall26、powerBall69);
//试图找出最常见的数字,列出前10位常见的数字。
对于(int i=1;i频率69(powerBall69,1))
{

cout如果您仍在为如何获得彩票号码和powerball的前10个最常见号码而苦苦挣扎,那么从Sam的评论继续,您可以使用一个简单的
结构(或
,等等),将彩票号码1-69与其在输入中的出现频率进行协调(powerball也是如此)。你甚至可以使用一个每行2-
int
的2D数组,但是使用结构可能会提供更可读的实现,因为它允许你使用成员名(例如
num
count
),而不是索引
0
1

一个简单的
struct
就是处理每个数字的数字频率映射所需的全部,这种映射方式将允许您在以后进行排序,并保留频率与其关联的数字之间的关系,例如

struct freq {
    int num, count;     /* struct capturing number & count */
};
<>而不是使用数组的基本类型,考虑使用C++容器库,它将使容器成员为Reals>代码>函数,如开始和结束迭代器、交换等可用,并允许数组通过< <代码> > />代码>库,通过简单地传递<代码>egin()
.end()
迭代器以及比较表达式

无论如何,您声明一个包含69个元素的数组用于彩票号码频率跟踪,声明一个包含26个元素的数组用于powerball跟踪。使用容器库中的
数组可以执行以下操作:

#define NMAX 69   /* if you need a constant, #define one (or more) */
#define BMAX 26
...
    std::array<freq, NMAX> nfreq;   /* array of struct for number frequency */
    std::array<freq, BMAX> bfreq;   /* array of struct for ball frequency */
注意:如何将
.num
成员初始化为
i+1
,而不仅仅是
i
,以适应索引为0-68,而存储的数字为1-69的事实。)

现在从文件中读取所有数据。您不需要将其存储在任何位置(除非您有其他需要),您只需设置每个数字和powerball的频率。因此,您可以简单地在循环中读取,使用每行的前5个数字来增加彩票号码频率数组中的计数
nfreq
,并使用每行的最后一个数字来对powerball频率数组
bfreq
(球频率)执行相同的操作。例如:

    std::ifstream f (argv[1]);      /* open filename given by 1st argument */
    /* validations omitted */
    while (getline (f, s)) {        /* read each line/fill freq arrays */
        std::stringstream ss (s);   /* create stringstream from line */
        size_t i = 0;               /* initialize counter zero */
        int tmp;                    /* tmp value to hold int read */
        while (i < NVAL && ss >> tmp)       /* read up to NVAL numbers */
            nfreq[tmp - 1].count++, i++;    /* increment nfreq count */
        if (i < NVAL) {     /* validate all number values read */
            std::cerr << "error: less than " << NVAL << "values read.\n";
            return 1;
        }
        if (!(ss >> tmp)) { /* validate ball value read */
            std::cerr << "error: no powerball value read.\n";
            return 1;
        }
        bfreq[tmp - 1].count++;     /* increment ball freq count */
    }
然后,由于使用了容器库
数组
,将开始和结束迭代器与比较函数一起传递给
std::sort
,非常简单:

    std::sort (nfreq.begin(), nfreq.end(), compare);
(对
bfreq
执行相同操作)

然后只输出排序数组的前10个元素,就完成了。总之,您可以执行类似的操作:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <array>
#include <algorithm>

#define NVAL 5      /* if you need a constant, #define one (or more) */
#define NMAX 69
#define BMAX 26
#define NTOP 10

struct freq {
    int num, count;     /* struct capturing number & count */
};

/* compare freq by count and if equal by num (descending) */
bool compare (const freq &a, const freq &b)
{
    if (a.count != b.count)
        return a.count > b.count;
    else
        return a.num > b.num;
}

int main (int argc, char **argv) {

    if (argc < 2) { /* validate 1-argument available for filename */
        std::cerr << "error: insufficnent input\nusage: " << argv[0]
                << " filename\n";
        return 1;
    }

    std::string s;
    std::array<freq, NMAX> nfreq;   /* array of struct for number frequency */
    std::array<freq, BMAX> bfreq;   /* array of struct for ball frequency */

    for (int i = 0; i < NMAX; i++)  /* initialize number freq array */
        nfreq[i].num = i + 1, nfreq[i].count = 0;

    for (int i = 0; i < BMAX; i++)  /* initialize ball freq array */
        bfreq[i].num = i + 1, bfreq[i].count = 0;

    std::ifstream f (argv[1]);      /* open filename given by 1st argument */
    if (!f.good()) {    /* validate file open for reading */
        std::cerr << "error: file open failed '" << argv[1] << "'.\n";
        return 1;
    }

    while (getline (f, s)) {        /* read each line/fill freq arrays */
        std::stringstream ss (s);   /* create stringstream from line */
        size_t i = 0;               /* initialize counter zero */
        int tmp;                    /* tmp value to hold int read */
        while (i < NVAL && ss >> tmp)       /* read up to NVAL numbers */
            nfreq[tmp - 1].count++, i++;    /* increment nfreq count */
        if (i < NVAL) {     /* validate all number values read */
            std::cerr << "error: less than " << NVAL << "values read.\n";
            return 1;
        }
        if (!(ss >> tmp)) { /* validate ball value read */
            std::cerr << "error: no powerball value read.\n";
            return 1;
        }
        bfreq[tmp - 1].count++;     /* increment ball freq count */
    }

    /* sort number frequency array of struct by count descending */
    std::sort (nfreq.begin(), nfreq.end(), compare);
    for (int i = 0; i < NTOP && nfreq[i].count; i++)
        std::cout << std::setw(2) << nfreq[i].num << " : " 
                    << nfreq[i].count << '\n';
    std::cout << '\n';

    /* sort ball frequency array of struct by count descending */
    std::sort (bfreq.begin(), bfreq.end(), compare);
    for (int i = 0; i < NTOP && bfreq[i].count; i++)
        std::cout << std::setw(2) << bfreq[i].num << " : " 
                    << bfreq[i].count << '\n';
    std::cout << '\n';
}
仔细检查一下,如果您还有其他问题,请告诉我。如果您想在调用
std::sort
时使用lamda函数,而不是编写单独的
compare
函数,您可以执行以下操作:

    std::sort (nfreq.begin(), nfreq.end(), [](freq a, freq b) {
        if (a.count != b.count)
            return a.count > b.count;
        else
            return a.num > b.num;
    });

这与此完全相同。(就个人而言,在本例中,
compare
功能可能会节省几行代码)

如果您仍在为如何获得彩票号码和powerball的前10个最常见号码而苦苦挣扎,那么继续Sam的评论,您可以使用一个简单的
结构
(或
pair
等)将彩票号码1-69与其在输入中的出现频率相协调(powerball也是如此)。为此,您甚至可以使用每行2-
int
的2D数组,但使用结构可能会提供更具可读性的实现,因为它允许您使用成员名称(例如
num
count
)而不是索引
0
1

一个简单的
struct
就是处理每个数字的数字频率映射所需的全部,这种映射方式将允许您在以后进行排序,并保留频率与其关联的数字之间的关系,例如

struct freq {
    int num, count;     /* struct capturing number & count */
};
<>而不是使用数组的基本类型,考虑使用C++容器库,它将使容器成员为Reals>代码>函数,如开始和结束迭代器、交换等可用,并允许数组通过< <代码> > />代码>库,通过简单地传递<代码>E
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <array>
#include <algorithm>

#define NVAL 5      /* if you need a constant, #define one (or more) */
#define NMAX 69
#define BMAX 26
#define NTOP 10

struct freq {
    int num, count;     /* struct capturing number & count */
};

/* compare freq by count and if equal by num (descending) */
bool compare (const freq &a, const freq &b)
{
    if (a.count != b.count)
        return a.count > b.count;
    else
        return a.num > b.num;
}

int main (int argc, char **argv) {

    if (argc < 2) { /* validate 1-argument available for filename */
        std::cerr << "error: insufficnent input\nusage: " << argv[0]
                << " filename\n";
        return 1;
    }

    std::string s;
    std::array<freq, NMAX> nfreq;   /* array of struct for number frequency */
    std::array<freq, BMAX> bfreq;   /* array of struct for ball frequency */

    for (int i = 0; i < NMAX; i++)  /* initialize number freq array */
        nfreq[i].num = i + 1, nfreq[i].count = 0;

    for (int i = 0; i < BMAX; i++)  /* initialize ball freq array */
        bfreq[i].num = i + 1, bfreq[i].count = 0;

    std::ifstream f (argv[1]);      /* open filename given by 1st argument */
    if (!f.good()) {    /* validate file open for reading */
        std::cerr << "error: file open failed '" << argv[1] << "'.\n";
        return 1;
    }

    while (getline (f, s)) {        /* read each line/fill freq arrays */
        std::stringstream ss (s);   /* create stringstream from line */
        size_t i = 0;               /* initialize counter zero */
        int tmp;                    /* tmp value to hold int read */
        while (i < NVAL && ss >> tmp)       /* read up to NVAL numbers */
            nfreq[tmp - 1].count++, i++;    /* increment nfreq count */
        if (i < NVAL) {     /* validate all number values read */
            std::cerr << "error: less than " << NVAL << "values read.\n";
            return 1;
        }
        if (!(ss >> tmp)) { /* validate ball value read */
            std::cerr << "error: no powerball value read.\n";
            return 1;
        }
        bfreq[tmp - 1].count++;     /* increment ball freq count */
    }

    /* sort number frequency array of struct by count descending */
    std::sort (nfreq.begin(), nfreq.end(), compare);
    for (int i = 0; i < NTOP && nfreq[i].count; i++)
        std::cout << std::setw(2) << nfreq[i].num << " : " 
                    << nfreq[i].count << '\n';
    std::cout << '\n';

    /* sort ball frequency array of struct by count descending */
    std::sort (bfreq.begin(), bfreq.end(), compare);
    for (int i = 0; i < NTOP && bfreq[i].count; i++)
        std::cout << std::setw(2) << bfreq[i].num << " : " 
                    << bfreq[i].count << '\n';
    std::cout << '\n';
}
$ ./bin/pwrballnumfreq dat/pwrball.txt
50 : 4
16 : 3
67 : 2
59 : 2
53 : 2
45 : 2
25 : 2
21 : 2
69 : 1
68 : 1

 4 : 3
21 : 2
14 : 2
12 : 1
 6 : 1
 5 : 1
    std::sort (nfreq.begin(), nfreq.end(), [](freq a, freq b) {
        if (a.count != b.count)
            return a.count > b.count;
        else
            return a.num > b.num;
    });