[英]How can I change the value of the elements in a 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;
}
您可以像數組一樣簡單地訪問它,即v[i] = v[i] - some_num;
好吧,你總是可以對矢量運行變換:
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循環...但這有點無聊。
您可以像訪問任何其他數組一樣訪問向量中的值。
for (int i = 0; i < v.size(); i++)
{
v[i] -= 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;
您可能需要考慮使用某些算法:
// 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));
你的代碼運行正常。 當我運行它時,我得到了輸出:
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();
}
由於這里和其他地方討論的一些原因,這是更好的,但這有兩個主要原因:
iterator
概念。 並非每個容器都提供隨機訪問(例如,索引訪問)。 第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表達式可以更簡單:
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;
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.