如何更改向量中元素的值?

时间:2011-01-26 17:25:01

标签: c++ vector

我有这个代码,它从文件中读取输入并将其存储在向量中。到目前为止,我已经得到它给我矢量中的值的总和,并使用总和给出值的平均值。

我现在要做的是学习如何再次访问向量并从向量的每个元素中减去一个值,然后再将其打印出来。例如,一旦计算了总和和平均值,我希望能够重新打印终端中的每个值减去平均值。有什么建议/例子吗?

#include <iostream>
#include <vector>
#include <fstream>
#include <cmath>

using namespace std;

int main()
{
    fstream input;
    input.open("input.txt");
    double d;
    vector<double> v;
    cout << "The values in the file input.txt are: " << endl;
    while (input >> d)
    {
        cout << d << endl;
        v.push_back(d);
    }

double total = 0.0;
double mean = 0.0;
double sub = 0.0;
for (int i = 0; i < v.size(); i++)
{
    total += v[i];
    mean = total / v.size();
    sub = v[i] -= mean;
}
cout << "The sum of the values is: " << total << endl;
cout << "The mean value is: " << mean << endl;
cout << sub << endl;
}

7 个答案:

答案 0 :(得分:12)

您可以像数组v[i] = v[i] - some_num;

一样轻松访问它

答案 1 :(得分:6)

好吧,你总是可以在矢量上运行变换:

std::transform(v.begin(), v.end(), v.begin(), [mean](int i) -> int { return i - mean; });

您总是可以设计一个迭代器适配器,该适配器在取消引用时返回应用于其组件迭代器的解除引用的操作的结果。然后你可以将矢量复制到输出流:

std::copy(adapter(v.begin(), [mean](int i) -> { return i - mean; }), v.end(), std::ostream_iterator<int>(cout, "\n"));

或者,你可以使用for循环......但这有点无聊。

答案 2 :(得分:2)

您可以像访问任何其他数组一样访问向量中的值。

for (int i = 0; i < v.size(); i++)
{         
  v[i] -= 1;         
} 

答案 3 :(得分:1)

只需使用:

for (int i = 0; i < v.size(); i++)
{
    v[i] -= valueToSubstract;
}

或它的等价物(更具可读性?):

for (int i = 0; i < v.size(); i++)
    v[i] = v[i] - valueToSubstract;

答案 4 :(得分:1)

您可能需要考虑使用某些算法:

// read in the data:
std::copy(std::istream_iterator<double>(input), 
          std::istream_iterator<double>(),
          std::back_inserter(v));

sum = std::accumulate(v.begin(), v.end(), 0);
average = sum / v.size();

您可以使用std::transform修改值,但在我们获得lambda表达式(C ++ 0x)之前,它可能比它的价值更麻烦:

class difference { 
    double base;
public:
    difference(double b) : base(b) {}
    double operator()(double v) { return v-base; }
};

std::transform(v.begin(), v.end(), v.begin(), difference(average));

答案 5 :(得分:1)

您的代码运行正常。当我运行它时,我得到了输出:

The values in the file input.txt are:
1
2
3
4
5
6
7
8
9
10
The sum of the values is: 55
The mean value is: 5.5

但它仍然可以改进。

您正在使用索引迭代向量。这不是“STL方式” - 您应该使用迭代器,即:

typedef vector<double> doubles;
for( doubles::const_iterator it = v.begin(), it_end = v.end(); it != it_end; ++it )
{
    total += *it;
    mean = total / v.size();
}

由于here及其他地方讨论的多种原因,情况会更好,但这主要有两个原因:

  1. 每个容器都提供iterator概念。并非每个容器都提供随机访问(例如,索引访问)。
  2. 您可以概括您的迭代代码。
  3. 第2点提供了另一种改进代码的方法。关于你的代码不是很STL-ish的另一件事是使用手写循环。 <algorithm>是为此目的而设计的,最好的代码是你从未写过的代码。您可以使用循环来计算向量的总和和平均值,方法是使用累加器:

    #include <numeric>
    #include <functional>
    struct my_totals : public std::binary_function<my_totals, double, my_totals>
    {
        my_totals() : total_(0), count_(0) {};
        my_totals operator+(double v) const
        {
            my_totals ret = *this;
            ret.total_ += v;
            ++ret.count_;
            return ret;
        }
        double mean() const { return total_/count_; }
        double total_;
        unsigned count_;
    };
    

    ......然后:

    my_totals ttls = std::accumulate(v.begin(), v.end(), my_totals());
    cout << "The sum of the values is: " << ttls.total_ << endl;
    cout << "The mean value is: " << ttls.mean() << endl;
    

    编辑:

    如果您拥有符合C ++ 0x的编译器的优势,那么使用std::for_each#include <algorithm>}和lambda expression内的{{3}}可以更简单地实现这一点:

    double total = 0;
    for_each( v.begin(), v.end(), [&total](double  v) { total += v; });
    cout << "The sum of the values is: " << total << endl;
    cout << "The mean value is: " << total/v.size() << endl;
    

答案 6 :(得分:1)

int main() {
  using namespace std;

  fstream input ("input.txt");
  if (!input) return 1;

  vector<double> v;
  for (double d; input >> d;) {
    v.push_back(d);
  }
  if (v.empty()) return 1;

  double total = std::accumulate(v.begin(), v.end(), 0.0);
  double mean = total / v.size();

  cout << "The values in the file input.txt are:\n";
  for (vector<double>::const_iterator x = v.begin(); x != v.end(); ++x) {
    cout << *x << '\n';
  }
  cout << "The sum of the values is: " << total << '\n';
  cout << "The mean value is: " << mean << '\n';
  cout << "After subtracting the mean, The values are:\n";
  for (vector<double>::const_iterator x = v.begin(); x != v.end(); ++x) {
    cout << *x - mean << '\n';  // outputs without changing
    *x -= mean;  // changes the values in the vector
  }

  return 0;
}