Пример 2
Разработанная ранее программа, в которой вводится интервал значений и шаг аргумента и вычисляются значения следующей функции
y = a02 + a12 / x + a22 / x2 + a32 / x3 +...+ an2 / xn,
может быть модифицирована с использованием вектора вместо массива. В этом случае величина n может не вводиться из файла, так как вводимые значения элементов можно добавлять в вектор с помощью push_back(). Таким образом, необходимый текстовый файл будет иметь следующее содержимое:
1 2 1
Строка - это коэффициенты a0, a1 и a2 соответственно.
В заголовочном файле модуля UnitFunction перечислены те же функции, что и в ранее созданной программе, за исключением deleteA():
#ifndef UnitFunction_h
#define UnitFunction_h
bool getA(char *fileName);
double y(double x);
bool writeTable(double left, double right, double step, char *fileName);
#endif
Наибольшие изменения должны коснуться файла UnitFunction.cpp:
#include <fstream>
#include <vector>
#include "UnitFunction.h"
namespace
{
std::vector <double> a;
}
bool getA(char *fileName)
{
std::ifstream in(fileName);
if (!in)
return false;
double x;
while (in >> x)
a.push_back(x);
return true;
}
double y(double x)
{
double result = 0;
double z = 1;
for (unsigned int i = 0; i < a.size(); i++)
{
result += a[i] * a[i] / z;
z *= x;
}
return result;
}
// Без изменений:
bool writeTable(double left, double right, double step, char *fileName)
{
std::ofstream out(fileName);
if (!out)
return false;
for (double x = left; x < right + step; x += step)
out << x << "\t" << y(x) << "\n";
return true;
}
Переменные внутреннего использования (a и n) целесообразно поместить в безымянное пространство имен. Как видно из примера, объекты-потоки можно сравнивать с целыми (булевыми) значениями. Если входной поток дает 0 после чтения, данные из файла не прочитаны, что означает ошибку.
В основном модуле удаляется вызов deleteA():
#include <iostream>
#include "UnitFunction.h"
using namespace std;
int main(int argc, char* argv[])
{
if (getA("input.txt") && writeTable(2, 3, 0.1, "results.txt"))
cout << "OK";
else
cout << "Error!";
return 0;
}
Пример 3
Необходимо изменить предыдущую программу, чтобы она позволила вычислять функцию следующего вида:
y = (f0(x) - y0)(f1(x) - y1) ... (fn - 1(x) - yn - 1)
fi(x) = (x - x0)(x - x1) ... (x - xi - 1)(x - xi + 1) ... (x - xn - 1)
Значения элементов xi и yi вводятся из заранее подготовленного файла. Файл с именем points.txt может содержать следующие пары xi и yi:
0 1
1 2
3 3
Создаем новое консольное приложение. Добавляем в него модуль с именем, например, UnitMath. Заголовочный файл будет аналогичен файлу из предыдущего примера:
#ifndef UnitMath_h
#define UnitMath_h
bool getXY(char *fileName);
double y(double x);
bool writeTable(double left, double right, double step, char *fileName);
#endif
В файл UnitMath.cpp помещаем следующий код:
#include <fstream>
#include <vector>
#include "UnitMath.h"
namespace
{
std::vector <double> vx;
std::vector <double> vy;
}
bool getXY(char *fileName)
{
std::ifstream in(fileName);
if (!in)
return false;
double x, y;
while (in >> x >> y)
{
vx.push_back(x);
vy.push_back(y);
}
return true;
}
double y(double x)
{
double result = 1;
for (unsigned int i = 0; i < vy.size(); i++)
{
double f = 1;
for (unsigned int j = 0; j < vx.size(); j++)
if (i != j)
f *= x - vx[j];
result *= f - vy[i];
}
return result;
}
bool writeTable(double left, double right, double step, char *fileName)
{
std::ofstream out(fileName);
if (!out)
return false;
for (double x = left; x < right + step; x += step)
out << x << "\t" << y(x) << "\n";
return true;
}
Основной модуль программы будет выглядеть так:
#include <iostream>
#include "UnitMath.h"
using namespace std;
int main(int argc, char* argv[])
{
if (getXY("points.txt") && writeTable(0, 2, 0.5, "results.txt"))
cout << "OK";
else
cout << "Error!";
return 0;
}
