Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.02.2012, 15:37   #1
relax92
 
Регистрация: 16.02.2012
Сообщений: 4
Восклицание Интерполяционный многочлен Лагранжа

В университете с предмета "Численные методы" дали задание - написать интерполяционный многочлен Лагранжа для n+1 элемента на C++, набросок сделал, выдает ошибку про неверную инициализацию массивов, помогите пожалуйста исправить ошибку.

Вот исходник:

Код:
#include <iostream.h>
int main ()
{
        int n;
        float X[3];
        float Y[3];
        int x,y;
        float Lagr=0;
        float p;
for (y=0; y<=n; y++)
 {
 cout<<"Введите n: "<<y<<endl;
 }
 for (int i=0; i<=n; i++)
  {
  for (int j=0 ;j<=n; j++)
   {
    if (i!=j)
    {cout<<"Введите  X: "<<X[i]<<endl;
     cout<<"Введите Y: "<<X[j]<<endl;
    p=(x-X[i])/(X[i]-X[j]);}
    else
    {cout<<"Не правильно введены данные!";}
   Lagr=y*p;
   }
cin>>Lagr;
  }
return 0;
}

Последний раз редактировалось ACE Valery; 18.02.2012 в 17:00.
relax92 вне форума Ответить с цитированием
Старый 18.02.2012, 22:11   #2
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

1) Вы n не инициализировали. Да и x (маленькое) тоже.
2) В этой строке:
Код:
    #include <iostream.h>
Не нужен .h
Код:
    #include <iostream>
3) Ещё нужно написать:
Код:
using namespace std;
4) Точки (x0, y0) (x1, y1) ... (xn, yn) лучше задать в файле, чем вводить каждый раз вручную.
5) Полиномы (вики) L(x) и li(x) лучше реализовать в виде функций.
6) В коде расставлять отступы, чтобы вам и нам было удобнее читать код.

Ваш код без изменения (только отступы расставил). А вы исправляйте ошибки:
Код:
#include <iostream>
using namespace std;

int main ()
{
    int n;
    float X[3];
    float Y[3];
    int x, y;
    float Lagr = 0;
    float p;

    for (y = 0; y <= n; y++) {
        cout << "Введите n: " << y <<endl;
    }
    for (int i = 0; i <= n; i++) {
        for (int j = 0 ; j <= n; j++) {
            if (i != j) {
                cout << "Введите  X: " << X[i] << endl;
                cout << "Введите Y: " << X[j] << endl;
                p = (x - X[i]) / (X[i] - X[j]);
            }
            else {
                cout << "Не правильно введены данные!";
            }
            Lagr = y * p;
        }
        cin >> Lagr;
    }
    return 0;
}

Последний раз редактировалось 8Observer8; 18.02.2012 в 22:23.
8Observer8 вне форума Ответить с цитированием
Старый 19.02.2012, 00:29   #3
relax92
 
Регистрация: 16.02.2012
Сообщений: 4
По умолчанию

Цитата:
1) Вы n не инициализировали. Да и x (маленькое) тоже.
Та вроде инициализировал
Цитата:
int n;
либо Я вас не понял. А вот X и Y - это должны быть массивы, в которых присутствуют действительные числа, но с ними у меня проблема, на них выдает ошибку.
Цитата:
4) Точки (x0, y0) (x1, y1) ... (xn, yn) лучше задать в файле, чем вводить каждый раз вручную.
В этом получается подвох, потому-что преподаватель сказал, чтоб ввод был именно с клавиатуры.
Цитата:
5) Полиномы (вики) L(x) и li(x) лучше реализовать в виде функций.
Я не знаю как это прописать, Я только первый курс, не освоил еще.

Если возможно, пожалуйста, помогите исправить ошибки в коде, просто Я их не могу найти, сделал что смог

Код:
#include <iostream>
using namespace std;

int main ()
{
    int n;
    float X[];
    float Y[];
    int x, y;
    float Lagr = 0;
    float p;

    for (y = 0; y <= n; y++) 
    {
        cout << "Введите n: " << y <<endl;
    }
    for (int i = 0; i <= n; i++) 
      {
        for (int j = 0 ; j <= n; j++) 
         {
            if (i != j) 
             {
                cout << "Введите  X: " << X[i] << endl;
                cout << "Введите Y: " << X[j] << endl;
                p = (x - X[i]) / (X[i] - X[j]);
             }
            else 
              {
                cout << "Не правильно введены данные!";
              }
            Lagr = y * p;
         }
        cin >> Lagr;
      }
    return 0;
}
relax92 вне форума Ответить с цитированием
Старый 19.02.2012, 01:37   #4
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию

недавно делал задачу, как бонус, для получения автоматом зачета по числовых методах.. чегото там (дальше не помню название предмета), задача интерполяционого полинома лагранжа. суть ее работы(в моем случае) была такова: сначало вводится количество точек извесных, потом иксы(x) каждой точки, потом игрики(хз почему не сделал, чтобы по одной точке вводить. наверное потому, что у меня x и y в разных маисвах... вобщем неважно. захочешь думаю сможешь переделать). а потом делается подстановка неких чисел. далее соотвественно идет проверка функцией sin(z)(по заданиб было проверить именно синусом) от этого числа. у нас была суть задачи проверить разницу эти значений. ну и на сколько точным является результат найденый полиномом лагранжа. вобщем смотри, может этот код будет для тебя чем то полезным. сори что код без коментов, надеюсь ты както поймешь \=
Код:
#include <stdio.h>

double *new_xk(int n);
double *new_yk(int n);
double *new_zk(int zn);
double ilp_lix(int n,double xk[],double yk[],double x);
double ilp_pi_n(int n,double xk[],int index,double x);
double ilp_ci(int n,double xk[],int index);
void free(double m[]);

int main(){
  int n = -1;
  printf("Enter number points:");
  scanf("%d",&n);
  double *xk = new_xk(n);
  double *yk = new_yk(n);
  printf("Enter number of z[i]:");
  int zn = -1;
  scanf("%d",&zn);
  double *zk = new_zk(zn);
  for(int i = 0; i < zn; i++)
  printf("f(%0*.*f) = %lf\n",3,2,zk[i],ilp_lix(n,xk,yk,zk[i]));
  scanf("%d",&zn);
  free(xk);
  free(yk);
  free(zk);
  return 0;
}

double ilp_lix(int n,double xk[],double yk[],double x){
  double lix = 0;
  for(int i = 0; i < n; i++)
    lix += ilp_pi_n(n,xk,i,x) / ilp_ci(n,xk,i) * yk[i];
  return lix;
}

double ilp_pi_n(int n,double xk[],int index,double x){
  double pi = 1;
  for(int i = 0; i < n; i++)
    if (index != i)
      pi *= x - xk[i];
  return pi;
}

double ilp_ci(int n,double xk[],int index){
  double ci = 1;
  for(int i = 0; i < n; i++)
    if (index != i)
      ci *= xk[index] - xk[i];
  return ci;
}

double *new_xk(int n){
  double *xk = new double[n];
  for(int i = 0; i < n; i++){
    printf("Enter x[%d]:",i);
    scanf("%lf",&xk[i]);
  }
  return xk;
}

double *new_yk(int n){
  double *yk = new double[n];
  for(int i = 0; i < n; i++){
    printf("Enter y[%d]:",i);
    scanf("%lf",&yk[i]);
  }
  return yk;
}

double *new_zk(zn){
  double *zk = new double[zn];
  for(int i = 0; i < zn; i++){
    printf("Enter z[%d]:",i);
    scanf("%lf",&zk[i]);
  }
  return zk;
}

void free(double m[]){
  delete []m;
}

Последний раз редактировалось lowercase; 19.02.2012 в 01:41.
lowercase вне форума Ответить с цитированием
Старый 19.02.2012, 02:01   #5
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию

как говорится, хорошая мысля приходит опосля... опосля 3х нидель после того, как сделал. функции new_zk, new_yk, new_xk можно было слепить в одно единое и просто передавать значение сообщения перед вводом, отдельной строкой. так сказать оптимизация (хоть и для даной задачи мелочь, но зато приятно) если будет желание, то думаю разберешься. я просто уже сплю походу набора текста. если начну обяснять, то вырублюсь к чертям
удачи. пробуй, разбирайся.. обязательно научишься чемуто

Последний раз редактировалось lowercase; 19.02.2012 в 02:04.
lowercase вне форума Ответить с цитированием
Старый 19.02.2012, 07:22   #6
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Цитата:
Сообщение от relax92 Посмотреть сообщение
Та вроде инициализировал
Инициализировать переменную - это значит присвоить ей значение перед первым актом использования этой переменной. Чему у вас равены n и x? Если локальные переменные не инициализировать, то они гарантированно будут содержать мусор.

Вам очень здорово помог lowercase. Не упустите возможность и разберитесь в программе. Это вас точно многому научит. Наверняка, когда разберётесь, то сможете адаптировать её под себя. Выкладывайте переработанный код - обсудим. И если есть вопросы - не стесняйтесь, задавайте.

Над кодом lowercase надо ещё поработать. Окончательно перевести на Си либо С++ (т.е. попытаться пришмурыгать ООП )
8Observer8 вне форума Ответить с цитированием
Старый 19.02.2012, 11:57   #7
relax92
 
Регистрация: 16.02.2012
Сообщений: 4
По умолчанию

Хорошо, буду пробивать разобраться, всем большое спасибо, потом если что спрошу что-то, еще раз спасибо
relax92 вне форума Ответить с цитированием
Старый 19.02.2012, 21:10   #8
relax92
 
Регистрация: 16.02.2012
Сообщений: 4
По умолчанию

Не люблю эту библиотеку:
Код:
#include <stdio.h>
Я ее еще не использовал, всегда пользуюсь вот этой:
Код:
<iostream>
Так что мне тяжело тут разобраться
relax92 вне форума Ответить с цитированием
Старый 20.02.2012, 17:48   #9
lowercase
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 88
По умолчанию

я раньше тоже иострим использовал для ввода и вывода. но после того как прочитал этот пост то понял что там ничего сложного нету. развечто есть нюансы.. я не знаю почему так, но мне больше нравится printf() и scanf()
lowercase вне форума Ответить с цитированием
Старый 20.02.2012, 18:28   #10
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Задачи программиста следующие:
1) Получить информацию от пользователя
2) Обработать информацию, полученную от пользователя
3) Вывести результат обработки данных, полученных от пользователя

Примечание - Пользователь - это может быть, к примеру, программа или устройство (с программным интерфейсом), не обязательно человек.

Рассмотрим, как получить информацию от пользователя.

Получить данные от пользователя можно следующими способами:
1) Через текстовою строку консоли (терминала)
2) Через графический интерфейс пользователя (GUI - graphical user interface)
3) Через файл

Примечание -
1) Выдать информацию можно:
- в консоль
- в элементы графического интерфейса пользователя
- в файл
2) Для ввода\вывода Можно комбинировать:
- консоль - файл
- GUI - файл

Теперь рассмотрим, как получить данные от пользователя, используя языки Си и С++.

Пока рассмотрим только, как получить данные от пользователя (на примере целого числа), через текстовою строку консоли (терминала)

Си:
Код:
#include <stdio.h> // текст файла stdio.h включается в текущий файл. И 
// содержит прототип функции scanf(), для проверки компилятором - правильно ли
// программист вызвал функцию. То есть, соответствуют ли число параметров и их
// типы прототипу из этого файла.

int main ()
{
    int a;

    scanf("%d", &a);

    return 0;
}
С++:
Код:
#include <iostream> // текст файла iostream включается в текущий файл. И
// содержит класс в котором описан метод cin
using namespace std;
int main ()
{
    int a;

    cin >> a;

    return 0;
}
Как обработать данные зависит от задачи. Это может быть сложный математический расчёт, как в вашем случае.

Или не очень сложный:

Код:
#include <stdio.h>

int main ()
{
    int a, b, c;

    // ввод данных
    scanf("%d", &a);
    scanf("%d", &b);

    // обработка данных
    c = a + b;

    return 0;
}
Давайте теперь поговорим о выводе данных через текстовою строку консоли (терминала):

Си:
Код:
#include <stdio.h>

int main ()
{
    int a, b, c;

    // ввод данных
    scanf("%d", &a);
    scanf("%d", &b);

    // обработка данных
    c = a + b;

    // вывод данных
    printf("%d\n", c);

    return 0;
}
С++:
Код:
#include <iostream>
using namespace std;

int main ()
{
    int a, b, c;

    // ввод данных
    cin >> a;
    cin >> b;

    // обработка данных
    c = a + b;

    // вывод данных
    cout << c << endl;

    return 0;
}
P.S. В Си примитивные типы данных. Стандартный набор для Си: int, float, double и char. Их называют базовыми типами. К int и char можно применить модификаторы: signed (знаковый), unsigned (беззнаковый), short (короткий) и long (длинный). К double можно применить long, получится: long double. Есть в Cи типы данных посложнее: указатели, массивы, структуры, объединения (union), перечислимый тип (enum), константы (const - не все компиляторы поддерживают; компилятор в Visul'e 2008 их не поддерживает). Константы можно определить через директиву #define, вот так:
Код:
#define BUFSIZE 100
С++ включает в себя все примитивные типы данных из Си. В С++ можно определить сложные (пользовательские) типы данных. В Си и С++ совершенно разный подход к структуре данных. Как следствие, операции над данными различны. Программируя на С++, нужно мыслить в терминах объектов, поэтому программирование на С++ называется "объектно-ориентированное программирование". Есть объекты и есть методы работы с этими объектами. Методы описываются внутри определения типа (или класса). В С++ для пользовательских типов данных можно определить операции, которые можно совершить над этими данными, например, сложить. "Философия" (или "мировоззрение") этих языков различна.
P.S.S. Мне кажется, нам легче будет общаться в терминах языка Си.

Последний раз редактировалось 8Observer8; 20.02.2012 в 18:36.
8Observer8 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
интерполяционный многочлен Лагранжа, Pascal Ladyia Помощь студентам 8 15.10.2013 15:24
Интерполирование функций, многочлен Лагранжа! IdiotDetected Помощь студентам 0 07.04.2011 21:50
Есть у кого код??(интерпритационный многочлен Лагранжа) ins1der Общие вопросы Delphi 2 21.05.2010 01:20
Интерполяционный многочлен лагранжа 3.14oner Паскаль, Turbo Pascal, PascalABC.NET 2 10.11.2008 17:30