В коде, который вызывал ваши ошибки, было что-то не так. Несоответствия типов, но, что более важно, вы никогда не создавали массив для хранения значений. Вы рассматривали простой дубль как массив, и вам повезло, что ваша программа никогда не зависала на вас.
Ниже приведена рабочая версия вашего кода, проверенная с помощью набора данных и Excel. Я оставил там как можно больше вашего кода, просто закомментировал, когда это уместно. Если я закомментировал это, я не вносил в него никаких изменений, поэтому все еще могут быть ошибки.
В этом случае массив векторов. Вы не знаете размер заранее (во время компиляции), а векторы проще, чем динамические массивы c. У вас также никогда не было массива. Векторы также знают, насколько они велики, поэтому вам не нужно передавать размер.
Несоответствия типов. Ваши функции продолжают ожидать массив значений типа double, но ваша сумма была int, среди многих других несоответствий. Вы также передавали простой дубль, как будто это был массив, записывая в память, что вы не могли так измениться.
Лучшие практики, которые нужно начинать сейчас. Стоп с using namespace std;
. Просто уточните ваши имена, когда это необходимо, или укажите более точно c с такими строками, как using std::cout;
в верхней части функции. Ваше имя было повсюду. Выберите схему именования и придерживайтесь ее. Имена, начинающиеся с заглавной буквы, обычно зарезервированы для классов или типов.
#include <iomanip>
#include <iostream>
// #include <array> // You never actually declared a std::array
#include <vector> // You don't know the size ahead of time, vectors are the
// right tool for that job.
// Use what's available
#include <algorithm> // std::sort()
#include <cmath> // std::sqrt()
#include <numeric> // std::accumulate()
// function declarations
// Commented out redundant functions, and changed arguments to match
void get_data(std::vector<double>& vals);
// void Sort(double vals[], int& valCount);
void print(const std::vector<double>& vals);
double variance(const std::vector<double>& vals);
double standard_dev(const std::vector<double>& vals);
// double SqRoot(double value); //use for StandardDev function
// function definitions
int main() {
int valCount = 0; // number of values to be processed
// ask user how many values
std::cout << "Enter the number of values (0 - 100) to be processed: ";
std::cin >> valCount;
std::vector<double> vals(valCount, 0);
// Was just a double, but you pass it around like it's an array. That's
// really bad. Either allocate the array on the heap, or use a vector.
// Moved to after getting the count so I could declare the vector with
// that size up front instead of reserving later; personal preference.
// process and store input values
get_data(vals);
// sort values
// Sort(&vals, valCount);
std::sort(vals.begin(), vals.end(), std::less<double>());
// The third argument can be omitted as it's the default behavior, but
// I prefer being explicit. If compiling with C++17, the <double> can
// also be omitted due to a feature called CTAD
// print sort
std::cout << "\nValues in Sorted Order: " << '\n';
print(vals);
// print variance
std::cout << "\nThe variance for the input value list is: " << variance(vals);
// print standard deviation
std::cout << "\nThe standard deviation for the input list is: "
<< standard_dev(vals) << '\n';
return 0;
}
// prompt user to get data
void get_data(std::vector<double>& vals) {
for (unsigned int i = 0; i < vals.size(); i++) {
std::cout << "Enter a value: ";
std::cin >> vals[i];
}
}
// //bubble sort values
// void Sort(double vals[], int& valCount)
// {
// for (int i=(valCount-1); i>0; i--)
// for (int j=0; j<i; j++)
// if (vals[j] > vals[j+1])
// swap (vals[j], vals[j+1]);
// }
// print sorted values
void print(const std::vector<double>& vals) {
for (auto i : vals) {
std::cout << i << ' ';
}
std::cout << '\n';
}
// compute variance
double variance(const std::vector<double>& vals) {
// was int, but your now vector is of type double
double sum = std::accumulate(vals.begin(), vals.end(), 0);
double mean = sum / static_cast<double>(vals.size());
// variance
double squaredDifference = 0;
for (unsigned int i = 0; i < vals.size(); i++)
squaredDifference += std::pow(vals[i] - mean, 2);
// Might be possible to get this with std::accumulate, but my first go didn't
// work.
return squaredDifference / static_cast<double>(vals.size());
}
// compute standard deviation
double standard_dev(const std::vector<double>& vals) {
return std::sqrt(variance(vals));
}
// //compute square root
// double SqRoot(double value)
// {
// double n = 0.00001;
// double s = value;
// while ((s - value / s) > n)
// {
// s = (s + value / s) / 2;
// }
// return s;
// }
РЕДАКТИРОВАТЬ : Я выяснил разницу с аккумулятором. Это требует знания лямбд (анонимные функции, функторы). Я скомпилировал в стандарт C ++ 14, который некоторое время был по умолчанию для основных компиляторов.
double variance(const std::vector<double>& vals) {
auto meanOp = [valSize = vals.size()](double accumulator, double val) {
return accumulator += (val / static_cast<double>(valSize));
};
double mean = std::accumulate(vals.begin(), vals.end(), 0.0, meanOp);
auto varianceOp = [mean, valSize = vals.size()](double accumulator,
double val) {
return accumulator +=
(std::pow(val - mean, 2) / static_cast<double>(valSize));
};
return std::accumulate(vals.begin(), vals.end(), 0.0, varianceOp);
}