Консультация № 167361
15.05.2009, 13:52
0.00 руб.
0 4 2
Помогите найти и устранить ошибку в программе.Нужно получить Xn, Yn, если
X1=X1 =1, Xi=Xi-1 + Yi-1/i*i , Yi=Yi-1+Xi-1/i , i=2,3….
Считает всё правильно, но выводит одно и тоже значение и для X и для Y



Приложение:
//Пусть X1=Y1=1, Xi=Xi-1 + Yi-1/i*i , Yi=Yi-1+Xi-1/i , i=2,3….
//Получить Xn, Yn


#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <ctype.h>
#include "locale.h"

double func(int n)
{ static int k=0;
static double a,b,c,d;
static double x0=1,x1=0,x2=0,y0=1,y1=0,y2=0;
static double X,Y;

if(k==n)
{
k=0;
a=0,x1=0,x2=0,y1=0,y2=0;
b=0,c=0,d=0;

}
else
{
if(k==0)
{
X=0;
Y=0;
a=x0;
b=y0;
X=a;
Y=b;
k++;
}
else
{
if(k==1)
{
x1=a+(b/(n*n));
y1=b+(a/n);
c=x1;
d=y1;
X=c;
Y=d;
++k;
}
else
{
x2=c+(d/(k*k));
y2=d+(c/k);
c=x2;
d=y2;
X=c;Y=d;
++k;
}
}
func(n);

}
return X,Y;
}

void main()
{ char ch;
setlocale(LC_ALL,"Russian");
int N;
double X,Y=0;


printf("\nВведите число N(в пределах от 1 до 100 ):");
scanf("%d",&N);
while((N<1)||(N>100))
{
printf("Введите N занаво\n");
scanf("%d", &N);
}
X=func(N);
Y=func(N);
printf("\nX=%lg", X);
printf("\nY=%lg", Y);
getch();
}

Обсуждение

давно
Академик
20764
1861
15.05.2009, 14:34
общий
это ответ
Здравствуйте, Biathlonfan!

return x,y означает что возвращается одно значение y - результат операции «,» (запятая), то есть правый операнд.
Вы можете определить подходящую структуру и вернуть её.


Приложение:
struct pair {
double x,y;
};

struct pair func(int n) {
...
{ struсt pair ret = {x, y}; return ret; }
}


Неизвестный
15.05.2009, 16:03
общий
это ответ
Здравствуйте, Biathlonfan!
Вам не кажется, что задача решается гораздо проще и логичнее, чем у Вас?
C++
Код:

// Компилировать с опцией /EHa
// Можно включить в Project\Properties->Configuration Properties\C/C++\Code Generation\Enable C++ Exceptions
// выбрать /EHa

#include <locale>
#include <iostream>
#include <exception>
#include <Windows.h>

using namespace std;

// Этот класс будем использовать для возврата результата
class xy
{
public:
xy(double x,double y);
double x() const;
double y() const;
private:
double _x,_y;
};

// Будем использовать для проверки переполнени стека
class stackoverflowexception:public exception
{};

// Рекурсивная функция для вычисления
xy calc(unsigned int N);

// Обработчик исключений
void __cdecl sehTranslator(unsigned int code,_EXCEPTION_POINTERS*);

// Здесь будем хранить указатель на предыдущий обработчик исключений
_se_translator_function prevTranslator=0;

int main()
{
setlocale(LC_ALL,"russian");
// Вводим N
cout<<"Введите N:";
int N=0;
cin>>N;
if(cin.fail())
{
cout<<"Ошибочный ввод"<<endl;
}
else
{
if(N>0)
{
// Не рекурсивное вычисление
double X=1,Y=1;
for(unsigned int i=2;i<=static_cast<unsigned int>(N);++i)
{
double newX=X+Y/i/i;
double newY=Y+X/i;
X=newX;
Y=newY;
}
cout<<"X("<<N<<")="<<X<<endl;
cout<<"Y("<<N<<")="<<Y<<endl;
// Рекурсивное вычисление
cout<<"Вычисление при помощи рекурсии:"<<endl;
// Установим собственный обработчик исключений, чтоб перехватить переполнение стека.
// Т.к. стандартный обработчик просто аварийно завершит программу
// Так же сохраним предыдуший обработчик в prevTranslator
prevTranslator=_set_se_translator(sehTranslator);
// Флаг сигнализирующий, что возникло переполнение стека и требуется его восстановление.
bool resetRequired=false;
// Блок обработки исключений
try
{
// Наш рекурсивный вызов
xy res=calc(N);
// Выводим результат
cout<<"X("<<N<<")="<<res.x()<<endl;
cout<<"Y("<<N<<")="<<res.y()<<endl;
}
catch(stackoverflowexception)
{
// Стек переполнился - установим флаг
resetRequired=true;
}
catch(exception e)
{
cout<<"Исключение:"<<e.what()<<endl;
}
catch(...)
{
cout<<"Неизвестное исключение"<<endl;
}
if(resetRequired)
{
cout<<"Возникло переполнение стека"<<endl;
if(!_resetstkoflw())exit(1);
}
// Вернем старый обработчик исключений. Можно и без этого.
_set_se_translator(prevTranslator);
}
else cout<<"Ожидается положительное число"<<endl;
}
system("PAUSE");
return 0;
}

// Рекурсивная функция
xy calc(unsigned int N)
{
if(N>1)
{
xy t=calc(N-1);
return xy(t.x()+t.y()/N/N,t.y()+t.x()/N);
}
else return xy(1,1);
}

xy::xy( double x,double y )
:_x(x)
,_y(y)
{}

inline double xy::x() const
{
return _x;
}

inline double xy::y() const
{
return _y;
}

// Наш обработчик исключений
void __cdecl sehTranslator(unsigned int code,_EXCEPTION_POINTERS* ep)
{
// Если переполнился стек то сгенерируем исключение stackoverflowexception
if(code==EXCEPTION_STACK_OVERFLOW)throw stackoverflowexception();
else
{
// Иначе передадим исключение старому обработчику. Пусть сам разбирается с ним:)
if(prevTranslator)prevTranslator(code,ep);
else throw exception("Unknown exception");
}
}

Пример работы:
Код:

Введите N:1000
X(1000)=2.41177
Y(1000)=14.0074
Вычисление при помощи рекурсии:
X(1000)=2.41177
Y(1000)=14.0074

Только не забывайте, что при использовании рекурсии возможно переполнение стека.
Если Вам нужно именно на C, то возьмите только алгоритм. Хотя Ваш компилятор Microsoft Visual C++ Compiler должен без проблем компилировать этот код.
Неизвестный
15.05.2009, 16:51
общий
Да, согласен. Но мне нужно решить эту задачу с помощью рекурсии.
Неизвестный
15.05.2009, 18:21
общий
Добавил при помощи рекурсии. Смотрите в ответе. Даже с рекурсией задача решается гораздо проще чем у Вас
Форма ответа