具有相似索引的值的总和

时间:2013-08-06 15:39:14

标签: c++ c++11 io

假设我在一个文本文件中有一组1000个统计数据。其第一列表示索引的数量,第二列表示该值的值。索引可以重复,相应的值可以不同。我想计算索引的出现次数和每个索引的值的总和。

我编写了一个代码,它给出了索引出现的结果,但它没有给出相应的值总和。

示例

假设我的文本文件有一组这样的数据 -

#index   value
  4      0.51
  5      0.13
  5      0.53
  5      0.25
  6      0.16
  6      0.16
  7      0.38
  4      0.11
  3      0.101
  4      0.32
  4      0.2 ... and more

所以在这种情况下 -

指数4 发生 4次,相应的值=(0.51 + 0.11 + 0.32 + 0.2)= 1.14

类似地

指数5 发生 2次,值=(0.13 + 0.53)= 0.66等。

我的代码

这是我的代码 -

#include <iostream>
#include <map>
#include <fstream>

using namespace std;


int main()
{
    map<double,double>   index;
    double  number,value;
    double total;


    ifstream theFile ("a1.txt");
    while(theFile >> number >> value)
    {
        ++index[number];
        total +=value;
    }
    cout<<"index\t occurs\t total"<<endl;


    for(auto loop = index.begin(); loop != index.end();++loop)
    {
         cout << loop->first << "\t  " << loop->second << "\t \t "<< total<<endl;
    }
    return 0;
}

此代码生成结果 -

index  occurs  total
3       1     2.851
4       4     2.851
5       3     2.851
6       2     2.851
7       1     2.851

虽然发生的次数是正确的但是

  

总计+ =值;

不会生成我正在寻找的输出。如何获得每个索引的总和?

3 个答案:

答案 0 :(得分:7)

  1. 每个索引需要total
  2. 每个索引需要count
  3. 对此的简单解决方案是使用以下结构:

    struct per_index
    {
       int count;
       double total;
       per_index(): total(0), count(0) {}
    };
    
    std::map<int, per_index> index;
    
    ...
    
    index[number].count++;
    index[number].total += value;
    

    请注意,我不相信您所阅读的number应该(或需要)成为double,这会让生活更加复杂,因为double有困难比较平等。所以我选择number成为int - 您需要更改代码中的声明。

答案 1 :(得分:2)

您的总数目前仅计算整个文件中的总数,而不是每个索引的总数。以类似于累积“发生”列的方式,您可能希望累积“总计”列。请参阅下面修改的代码:

#include <iostream>
#include <map>
#include <fstream>

using namespace std;

int main()
{
    map<double, double> index;
    double number, value;
    map<double, double> total;

    ifstream theFile ("a1.txt");
    while(theFile >> number >> value)
    {
        ++index[number];
        total[number] += value;
    }

    cout << "index\t occurs\t total" << endl;
    for(auto loop = index.begin(); loop != index.end();++loop)
    {
        cout << loop->first << "\t  " << loop->second << "\t \t "<< total[loop->first] << endl;
    }
    return 0;
}

我将每个列存储在自己的总映射中,就像将索引存储在自己的映射中一样。

答案 2 :(得分:0)

您为每个索引添加valuetotal,而每个索引需要单独的total

与其匹配的向量的索引映射最简单,因此您可以在单独的步骤中为每个索引执行求和。

阅读循环的主体可以是

index[ number ].push_back( value );

然后循环索引中的所有条目,生成其关联向量中元素的总和。 (提示 - accumulate是这个的通用名称....)

编辑:哦,计数显然是每个向量中的元素数。