如何用c ++计算某些东西?

时间:2016-07-03 20:01:18

标签: c++

我是C ++和数据结构的新手。所以我正在学习,任何建议表示赞赏。我试图在记事本中提取一个类似于以下内容的csv文件。

Sig1的,SIG2,SIG3,SIG4,SIG5,Sig6的,SIG7,SIG8 45,200,45,200,45,200,45,200 45,200,45,200,45,200,45,200 45,200,45,200,45,200,45,200 45,200,45,200,45,200,45,200 45,200,45,200,45,200,45,200 45,200,45,200,45,200,45,200 45,200,45,200,45,200,45,200 45,200,45,200,45,200,45,200

我想计算每列的移动平均值并打印出每列的结果。我知道如何按行读取和打印整个csv文件,我也知道如何计算移动平均值。但我发现很难把这两件事放在一起,因为我想通过"列"来计算结果。而不是rows.I想使用vector(queue(string))来读取文件。

我的想法:假设我想读取行的第一个单元格并将其放入queue1,队列2中的下一个单元格,依此类推,然后我转到第二行并重复该过程。所以第一列是queue1的向量,然后第二列是queue2的向量,依此类推。然后我为队列(或列)的每个向量执行移动平均值。

这听起来像是一个可行的想法吗?检查下面的代码。 我使用此链接的最后一个代码来了解如何从csv文件中提取表: How to read-write into/from text file with comma separated values

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <queue>

using namespace std;

void readCSV(istream &input, std::vector< std::queue<std::string> > &output)
{
//fstream file("c://data//test_data.csv", ios::in);
string csvLine;

// read every line from the stream
while( getline(input, csvLine) )
    {
    istringstream csvStream(csvLine);
    queue<string> csvColumn;
    string csvElement;
            // read every element from the line that is seperated by commas
            // and put it into the vector or strings
    while( getline(csvStream, csvElement, ',') )
            {
            csvColumn.push(csvElement);
            }
output.push_back(csvColumn);
    }

}

int main()
{
    ofstream myfile;
    string sig;
    fstream file("c://data//test_data.csv", ios::in);
    if(!file.is_open())
    {
           cout << "File not found!\n";
            return 1;
    }
    // typedef to save typing for the following object
    typedef queue<string> Q;
    typedef vector<Q> csvVector;
    csvVector csvData;
    const int Number_Size = 8;
    int n =8;
    double sum1 = 0.0;
    double movingAverage = 0.0;

readCSV(file, csvData);
// Read data and perform moving average for each column
for(csvVector::iterator i = csvData.begin(); i != csvData.end(); ++i)
{
    for(vector<Q>::iterator j = i ->begin(); j !=i ->end(); ++j)
    {
        for (int i = 0; i <= (Number_Size - n); i++)
        { 
        sum1 = 0.0;

            for( int i=0; int j = i; j < i + n; j++)
            {
            sum1 += sig[j];
            movingAverage = sum1/n; 
            cout << movingAverage << endl;
            }

        }
 }

 }

myfile.close();
system("pause");

}

1 个答案:

答案 0 :(得分:0)

您的方法的问题在于您解析csv文件并存储它的方式。您的代码创建一个包含每行的字符串的队列,并在向量中添加所有创建的队列。当您现在想要遍历列时,这会成为问题。
尝试为第一行中找到的每个元素创建一个向量。处理除第一行之外的任何其他行时,访问已存在的向量并添加字符串。如果您遵循这种方法,您将最终得到包含列内容的向量而不是现在的行。以下是一些示例代码:

    void readCSV(istream &input, vector<vector<string>>& vOutput)
    {
        int iRowCnt = 0;    
        string csvLine;

        // read every line from the stream
        while( getline(input, csvLine) )
        {
            int iColCnt = 0;
            istringstream inpStreamLine(csvLine);        
            string strElement;

            // read every element from the line that is separated by commas        
            while( getline(inpStreamLine, strElement, ',') )
            {
                // if first line, create vector for each column
                if (iRowCnt == 0)           
                {
                    vector<string> vColumn;
                    vOutput.push_back(vColumn);
                }
                // access the vector with index iColCnt and add sub string
                vOutput.at(iColCnt).push_back(strElement);
                iColCnt++;
            }        
            iRowCnt++;
        }
    }

    void getNumericValues(vector<vector<string>> &vColumns, vector<vector<int>>& vOutput)
    {   
        // iterate across rows (signals)
        for (vector< vector<string> >::iterator iterCol = vColumns.begin() ; iterCol != vColumns.end() ; ++iterCol) 
        {
            vector<int> vColumn;
            vector<string> *vCol = &(*iterCol);
            // iterate across columns (signal values) while skipping first line 
            // convert strings to integer values and add them to vNumValues 
            for (vector<string>::iterator iterRow = vCol->begin()+1; iterRow < vCol->end(); ++iterRow)
            {
                string strElem = *iterRow;
                string::size_type sz;   
                vColumn.push_back(stoi(strElem, &sz));
            }
            vOutput.push_back(vColumn);
        }
    }

    void getMovingAveragesColumn(vector<int> &vNumValues, int iWndSize, vector<int>& vOutput)
    {   
        if (vNumValues.size()<iWndSize)        // check if we have enough values 
            return;                 

        for (vector<int>::iterator iter = vNumValues.begin() ; iter < vNumValues.end()-iWndSize ; ++iter) 
        {
            int iMovAvg = 0;
            for (int ii=0; ii<iWndSize; ii++)
            {
                iMovAvg+= *(iter+ii);
            }
            iMovAvg /= iWndSize;
            vOutput.push_back(iMovAvg);
        }   
    }

    void getMovingAveragesMatrix(vector<vector<int>> &vNumValues, int iWndSize, vector<vector<int>>& vOutput)
    {   
        for (vector<vector<int>>::iterator iterCol = vNumValues.begin() ; iterCol < vNumValues.end() ; ++iterCol) 
        {
            vector<int> *vCol = &(*iterCol);
            vector<int> vMovAvg;
            getMovingAveragesColumn(*vCol, iWndSize, vMovAvg);
            vOutput.push_back(vMovAvg);
        }
    }


    int _tmain(int argc, _TCHAR* argv[])
    {
        ofstream myfile;
        fstream file("c://tmp//test_data.csv", ios::in);
        if(!file.is_open())
        {
            cout << "File not found!\n";
            return 1;
        }
        // vector of vectors for storing strings in matrix form 
        vector<vector<string>> vData;
        readCSV(file, vData);

        // convert to integers 
        vector<vector<int>> vNumValues;
        getNumericValues(vData, vNumValues);    

        // get moving average values
        vector<vector<int>> vMovAverages;
        getMovingAveragesMatrix(vNumValues, 3, vMovAverages);

            // print the moving average values     
        for (vector<vector<int>>::iterator iterCol = vMovAverages.begin() ; iterCol < vMovAverages.end() ; ++iterCol) 
        {
            vector<int> *vCol = &(*iterCol);
            for (vector<int>::iterator iterRow= vCol->begin() ; iterRow < vCol->end() ; ++iterRow) 
            {
                cout<< *iterRow << " ";
            }
            cout<<"\n";
        }

        myfile.close();
        system("pause");
    }