Advertisement
Guest User

Untitled

a guest
Feb 19th, 2019
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.05 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <malloc.h>
  3. #include <string.h>
  4. #include <conio.h>
  5. #include <locale.h>
  6.  
  7.  
  8. //Функция считает биномиальный коэффициент, используя треугольник паскаля
  9. long long binom(int n, int k){
  10.     if(k > n) return 0;
  11. //нам незачем хранить весь треугольник, т.к. для подсчета одного уровня,
  12. //нам необходимо знать только значение предыдущего, поэтому, чтобы не тратить
  13. //попусту память, мы заводим только два массива под текущий и предыдущий уровень треугольника:
  14.     long long** pascals_triangle_lines = (long long**)malloc(sizeof(long long*)*2);
  15.     pascals_triangle_lines[0] = (long long*)malloc(sizeof(long long)*1);
  16.     pascals_triangle_lines[0][0] = 1;
  17.     pascals_triangle_lines[1] = (long long*)malloc(sizeof(long long)*2);
  18.     pascals_triangle_lines[1][0] = pascals_triangle_lines[1][1] = 1;
  19.    
  20. //индекс принимает значение 0 или 1 в зависимости от того, какой массив из двух считается текущим, а какой - предыдущим
  21.     int index = 1;
  22.    
  23. //доходим до нужного нам уровня по треугольнику:
  24.     for(int i = 2; i <= n; ++i){
  25.         index = 1-index;
  26.         free(pascals_triangle_lines[index]);
  27.         pascals_triangle_lines[index] = (long long*)malloc(sizeof(long long)*(i+1));
  28.         pascals_triangle_lines[index][0] = pascals_triangle_lines[index][i] = 1;
  29.         for(int l = 1; l < i; ++l)
  30.             pascals_triangle_lines[index][l] = pascals_triangle_lines[1-index][l] + pascals_triangle_lines[1-index][l-1];
  31.     }
  32.    
  33. //очищаем память
  34.     long long ans = pascals_triangle_lines[index][k];
  35.     free(pascals_triangle_lines[0]);
  36.     free(pascals_triangle_lines[1]);
  37.     free(pascals_triangle_lines);
  38. //возвращаем результат
  39.     return ans;
  40. }
  41.  
  42. //тривиальная функция, считающая факториал числа
  43. long long factorial(int n){
  44.     long long answer = 1;
  45.     for(int i = 1; i <= n; ++i)
  46.         answer *= i;
  47.     return answer;
  48. }
  49.  
  50. //функция считает конечную разность n-го порядка, принимая на вход массив точек
  51. double finite_difference(int n, double* points){
  52.     double answer = 0;
  53.     int sign = 1;
  54.     for(int i = 0; i <= n; ++i){
  55.         answer += sign*(points[n-i]*binom(n,i));
  56.         sign *= -1;
  57.     }
  58.     return answer;
  59. }
  60.  
  61. //функция считает значение полинома в заданной точке:
  62. double solve_interpolation(double* factors, int n, double q){
  63.     double answer = factors[0];
  64.     for(int i = 1; i < n; ++i){
  65.         double arg = 1;
  66.         for(int j = 0; j < i; ++j)
  67.             arg *= q-j;
  68.         answer += factors[i]*arg;
  69.     }
  70.     return answer;
  71. }
  72.  
  73. //функция печатает таблицу конечных разностей:
  74. void print_difference_table(int n, double* points, double x0, double h){
  75.     printf("Таблица конечных разностей:\n");
  76.     printf("X\tY\t");
  77.     for(int i = 0; i < n; ++i)
  78.         printf("d%dy\t", i+1);
  79.     printf("\n");
  80.     for(int i = 0; i <= n; ++i){
  81.         printf("%.4f\t%.4f\t", x0+i*h, points[i]);
  82.         for(int j = 0; j < n-i; ++j)
  83.             printf("%.4f\t", finite_difference(j+1, points+i));
  84.         printf("\n");
  85.     }
  86. }
  87.  
  88. int main(){
  89.     setlocale(0,"russian");
  90.     int n;
  91.     double x0, h;
  92.     double* points = NULL;
  93.     int correct_input;
  94.    
  95.     do{
  96.         printf("Введите степень интерполяционного полинома: ");
  97.         scanf("%d", &n);
  98.        
  99.         printf("Введите x_0: ");
  100.         scanf("%lf", &x0);
  101.        
  102.         printf("Введите шаг интерполяции: ");
  103.         scanf("%lf", &h);
  104.        
  105.         if(points) free(points);
  106.         points = (double*)malloc(sizeof(double)*(n+1));
  107.        
  108.         printf("Последовательно введите %d значений y_i:\n", n+1);
  109.         for(int i = 0; i <= n; ++i)
  110.             scanf("%lf", points + i);
  111.        
  112.         printf("Строим интерполяционный полином степени %d на следующих точках:\n", n);
  113.         for(int i = 0; i <= n; ++i)
  114.             printf("%.3lf ", points[i]);
  115.         printf("\nНа интервале [%.3lf,%.3lf] с шагом %.3lf\n", x0, x0+n*h, h);
  116.         printf("Подтвердите корректность введенных данных. Введите 0 для продолжения или 1 для ввода данных повторно: ");
  117.         scanf("%d", &correct_input);
  118.        
  119.     }while(correct_input);
  120.  
  121.     double* factors = (double*)malloc(sizeof(double)*(n+1));
  122.    
  123.     print_difference_table(n, points, x0, h);
  124.     printf("Интерполяционный полином степени %d на точках:\n", n);
  125.     for(int i = 0; i <= n; ++i)
  126.         printf("%.3lf ", points[i]);
  127.     printf("\nНа интервале [%.3lf,%.3lf] с шагом %.3lf выглядит следующим образом:\nP_%d(x) = %.3lf ", x0, x0+n*h, h, n, points[0]);
  128.    
  129.     factors[0] = points[0];
  130.     for(int i = 1; i <= n; ++i){
  131.         char str[64];
  132.         strcpy(str, "q");
  133.         for(int j = 1; j < i; ++j){
  134.             char buf[10];
  135.             sprintf(buf, "(q-%d)", j);
  136.             strcat(str, buf);
  137.         }
  138.         factors[i] = finite_difference(i, points)/factorial(i);
  139.         printf("+ %.5lf%s ", factors[i], str);
  140.     }
  141.     printf("\nгде для удобства представления мы ввели новую переменную q = (x-%.3lf)/%.3lf\n", x0, h);
  142.    
  143.     int check = 0;
  144.     do{
  145.         printf("Желаете проверить результат интерполяции? (1 - да, 0 - нет): ");
  146.         scanf("%d", &check);
  147.         if(!check) break;
  148.         double point;
  149.         printf("Введите точку, в какой вы хотите вычислить значение полинома: ");
  150.         scanf("%lf", &point);
  151.         printf("Значение полинома в точке %.3lf равно %.3lf\n", point, solve_interpolation(factors, n+1, (point - x0)/h));
  152.     }while(true);
  153.    
  154.     printf("Для выхода нажмите любую клавишу...");
  155.     free(points);
  156.     free(factors);
  157.     getch();
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement