#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
double Lagrange(int N, vector<double>& x, vector<double>& y, double X)//拉格朗日插值法
{
double result = 0;
for (int k = 0; k < N; k++)
{
double t = y[k];
for (int i = 0; i < N; i++)
{
if (i != k) {
t *= (X - x[i]);
t /= (x[k] - x[i]);
}
}
result += t;
}
return result;
}
double Quotient(int N, vector<double>& x, vector<double>& y)//差商
{
double f = 0;
double t = 0;
for (int i = 0; i <= N; i++)
{
t = y[i];
for (int j = 0; j <= N; j++)
{
if (i != j) t /= (x[i] - x[j]);
}
f += t;
}
return f;
}
double Newton(int N, vector<double>& x, vector<double>& y, double X)//牛顿插值法
{
double result = 0;
for (int i = 0; i < N; i++)
{
double t = 1;
double f = Quotient(i, x, y);
for (int j = 0; j < i; j++)
{
t = t * (X - x[j]);
}
result += f * t;
}
return result;
}
double lineLag(int N, vector<double>& x, vector<double>& y, double X)//分段线性插值法
{
double m1, m2, t1, t2;
vector<double>temp(N);
int n = 0;
m1 = X;
for (int i = 0; i < N - 1; i++)//冒泡排序法
{
for (int j = 0; j < N - 1 - i; j++)
{
if (x[j] > x[j + 1]) {
t1 = x[j];//x进行升序排序
x[j] = x[j + 1];
x[j + 1] = t1;
t2 = y[j];//对应的y值跟着变位置
y[j] = y[j + 1];
y[j + 1] = t2;
}
}
}
//找最近点
for (int i = 0; i < N; i++)
{
if (x[i] < X)//先找到区间左值
{
m1 = x[i];
n = i + 1;
}
}
if (X == m1 + 1) m2 = m1 + 2;//右值
else m2 = m1 + 1;
double result = y[n - 1] * ((X - m2) / (m1 - m2)) + y[n] * ((X - m1) / (m2 - m1));
return result;
}
int main(void)
{
int N;
double x;
double result;
ifstream infile;
infile.open("数据.txt", iostream::in);
if (!infile.is_open())//文件不存在
{
cout << "Open file failure!" << endl;
}
infile >> N;//先读取第一行
vector<double>X(N);
vector<double>Y(N);
for (int i = 0; i < N; i++)
{
infile >> X[i] >> Y[i];
}
cout << "输入需要计算的x值:";
cin >> x;
cout << "拉格朗日插值法计算结果为:" << Lagrange(N, X, Y, x) << endl;
cout << "牛顿插值法计算结果为:" << Newton(N, X, Y, x) << endl;
cout << "分段线性插值法计算结果为:" << lineLag(N, X, Y, x) << endl;
infile.close();
return 0;
}