PDA

View Full Version : 'گرفتن تابع ازکاربر و اعمال روش وتری بر روی آن تابع



loknatesabz
جمعه 29 اردیبهشت 1391, 09:07 صبح
با سلام
من میخوام برنامه ای بنویسم که از کاربر تابعی رو بگیره و روی اون روش وتری رو پیاده سازی کنه...
با پیاده سازی روش وتری مشکلی ندارم اما نمیدونم که چه جوری از کاربر تابع رو بگیرم و این روش رو بر روی اون اعمال کنم..ممنون میشم که کمکم کنید...

loknatesabz
یک شنبه 31 اردیبهشت 1391, 17:30 عصر
تورو خدا یعنی کسی نیست که به ما کمک کنه...:ناراحت:

Ananas
دوشنبه 01 خرداد 1391, 01:00 صبح
سلام.
منظورت از روش وتری و تابع و اینچیزا تو ریاضیات هست دیگه نه؟ یعنی یک تابع ریاضی ای رو می خوای از کاربر بگیری مثلا کاربر بگه (y = sin(x + 2 منظورت اینه؟
یکمی سخته. من فکر میکنم بهتره که یک حالت های ثابت و ساده ای رو تو برنامه داشته باشی مثل عمل جمع، تفریق و یا sin و یا log ، بعد کاربر بتونه از ترکیب اینها فرمول مورد نظر خودش رو بسازه.
و برای بهتر شدنش می تونی تابعی بنویسی که متن فرمول رو از کاربر به شکل string بگیره و اون رو تجزیه و تحلیل کنه تا برسه به همون حالت های خاصی که بالا گفتم بعد راحت تر میشه محاسبش کرد. در واقع شما یک چیزی می خوای که یه جورایی مثل کامپایلر عمل کنه با این تفاوت که محدود باشه به عبارات ریاضی. و یا میتونی برای ساختن فقط نمونه، کاربر توابع اولیه رو بتونه بنویسه و برای بقیه توابع که از ترکیب اینها درست میشن برنامه پیغام خطا "ناشناخته بودن برای برنامه" رو بده و خیال خودت رو راحت کنی. توابعی که میپذیره مثل توابع sin و exp و + - * / و x^2 و ازین قبیل. پیاده سازی این باید ساده تر باشه.

loknatesabz
دوشنبه 01 خرداد 1391, 10:07 صبح
خیلی خیلی ممنون از راهنماییتون
اینی که گفتید رو خودم پیاده سازی کردم اما استاد قبول نمیکنه...استاد میگه باید من فرمولمو بنویسم برنامه ات اونو بگیره و بعدش روش وتری رو روی اون تابع پیاده سازی کنه!!!...
من یک حالت، واقعا کلی میخوام...در واقع کار سختیه و میدونم کار با رشته ها و اشاره گرهاست...اما واقعا تو پیاده سازیش به مشکل برخوردم...
ممنون میشم بیشتر راهنماییم کنید...

Ananas
سه شنبه 02 خرداد 1391, 00:44 صبح
ببینی من به نظرم میاد که شما توابعی رو کاربر میتونه ازشون استفاده کنه یعنی همون جمع و تفریق تا سینوس و لگاریتم و توان و این چیزا رو با استفاده از یک لیستی از ثوابت نامگذاری کنی و بعد تو string بیای اول پرانتز ها رو جدا کنی و از داخلی ترین پرانتز شروع کنی (چون داری با c++builder کار میکنی خیلی راحت میتونی از توابع UnicodeString استفاده کنی) وقتی مثلا میرسی به عبارت sin تو string بیای تابع سینوس رو با توجه به ورودی که میشه اولین پرانتز بعد از عبارت سینوس رو برسی کنی. و یا وقتی میرسی به "+" تابع جمع رو انجام بدی. به نظرم اولین کار اینه که برسی کنی نوشته کاربر درسته یا خطا داره و اولم از پرانتز شروع کن ببین پرانتزای باز شده درست بسته شده یا نه و عبارات اشتباه نداشته باشه مثل sinx که باید بنویسه (sin(x و اگه تو این قسمت خطا داشت با پیغام گزارش میکنی و اگه درست بود اون موقع باید همون طور که عرض کردم پرانتز ها و عبارات را تفکیک کنی به عبارات کوچکتر تا جایی که برسی به توابعی که اسمشون ت لیست هست همون لیست توابع مجاز که کاربر میتونه ازشون استفاده کنه. اینطوری بعدا هم میتونی توابع جدید به لیستت اضافه کنی. اگه بخوای برنامه رو ویژوال بسازی میتونی دکمه هایی رو برای هر تابعه تو لیست، بگذاری تا با زدن مرحله به مرحله این دکمه ها کم کم فرمول کامل بشه یعنی کاربر بیاد فقط دکمه بزنه و دکمه ها پرانتز ها رو تو کد بنویسن و کاربر اصلا نتونه بنویسه و متن رو تغییر بده اینجوری نمیتونه متن اشتباه بنویسه و شما هم با استفاده از دکمه ها میتونی تابع ها و پرانتز ها رو از کاربر بگیری و به متن کار نداری و فقط متن رو برای نمایش به کاربر مینویسی. حتی اعداد رو هم مینونه با دکمه ها وارد کنه. بعدا که این برنامه رو نوشتی و درست کار کرد اونوقت بیای یه تابعی هم برای این منظور که کاربر دستی متن تابع رو بنویسه تعریف کنی که فقط تابع بیاد متن رو تجزیه تحلیل کنه و بده به مرحله بعد که اونم قبلا نوشتی.
یعنی در واقع شما سه مرحله کار باید انجام بدی :
1 - تبدیل متن به لیستی از توابعی که به برنامه شناسوندی و براش تعریف کردی با کلمات رزرو شده مثل sin.
2 - استفاده از لیست توابع و ورودی هایی که از کاربر گرفتی و به ترتیب پرانتز هاشون تنظیم شده برای بدست آوردن y مورد نظر به ازای x دلخواه.
3 - اجرای روش وتری (که من نمیدونم چیه، حدس میزنم مربوط به انتگرال باشه) برای این تابع که کاربر نوشته.

BORHAN TEC
سه شنبه 02 خرداد 1391, 01:19 صبح
آیا حق استفاده از کامپوننتها و SDK های آماده رو داری؟

loknatesabz
سه شنبه 02 خرداد 1391, 10:02 صبح
آیا حق استفاده از کامپوننتها و SDK های آماده رو داری؟

نه متاسفانه...اجازه استفاده از اونها رو ندارم...
در ادامه و در پاسخ به دوستمون باید عرض کنم که روش وتری یه متد برای پیدا کردن ریشه توابع در ریاضیات هست مثل روش نیوتن-رافسون همه این روش ها در کتاب محاسبات عددی هستند...
روش وتری رو در پایین میذارم:
87341
f(x تابعیه که از کاربر و همچنین مقادیر اولیه x0,x1 رو در شروع برنامه میگیریم...

Ananas
سه شنبه 02 خرداد 1391, 16:29 عصر
خوب همونطور که گفتید با روش وتری مشکلی ندارید و از فرمول هم پیداست که شما میخوای تابعی داشته باشی که متن کاربر رو بگیره و به ازای هر x ورودی یک y خروجی بده و بعد برنامه بیاد این تابع رو بگذاره تو فرمول بالا و جواب رو بدست بیاره.
اونوقت این تابع میتونه دو مرحله ای باشه. یک مرحله رشته متنی رو تجزیه و تحلیل کنه و تبدیل کنه به یک کلاس که شما باید اون رو تعریف کنید. مرحله دوم اینکه کلاس که ساخته شد متدی داشته باشه که یک x ورودی دریافت کنه و y خروجی بده. یعنی این نمونه از کلاس درواقع همون تابع کاربر هست که وارد کرده. یعنی شما ماشینی می خوای که یک ورودی بگیره و یک خروجی بده. حالا ماشینت رو به شکل یک کلاس باید تعریف کنی. و این کلاس رو هم در ابتدا با استفاده از رشته متنی که کاربر وارد میکنه بسازی. بعد روش وتری رو و یا هر چیز دیگه مثل رسم نمودار و یا هر چیزی رو روش اعمال کنی.
حالا از این همه چرت و پرتی که نوشتم چیزیم دستگیرت شد؟ من وقتشو ندارم وگرنه خیلی دوست دارم این برنامه رو بنویسم و حتما وقتم آزاد بشه این کار رو انجام میدم.

loknatesabz
چهارشنبه 03 خرداد 1391, 11:58 صبح
خیلی ممنونم از توضیحاتتون ...
من دارم روش کار میکنم اگه شمام روش کار کردید و به نتیجه رسیدید بذاریدش تو همین تاپیک...
بازم ممنون

Ananas
چهارشنبه 03 خرداد 1391, 16:04 عصر
آره ویری انداختی تو کلمون که نمیتونم بهش فکر نکنم. منم یواش یواش روش کار میکنم. کدی که ففعلا نوشتم :

#ifndef MATH_SCRIPT_DEFINED
#define MATH_SCRIPT_DEFINED

#include <stdio.h>
using namespace std;
#include <math.h>

enum MATH_FUNCTIONS
{
MFN_ABS ,
MFN_NEG ,
MFN_FLOOR ,
MFN_ADD ,
MFN_SUBTRACT ,
MFN_MULTIPLY ,
MFN_DIVIDE ,
MFN_SIN ,
MFN_COS ,
MFN_TAN ,
MFN_COT ,
MFN_EXP ,
MFN_LN ,
MFN_EXP2 ,
MFN_LN2 ,
MFN____FORCE_32BIT = 0x07ffffff
};

typedef long double MATHNUMBER, TMathNumber;


typedef class MATH_GENERATOR
{
public :
void *Parent;// formula object
virtual TMathNumber Fx();
} *PMATH_GENERATOR;

typedef class MATH_CONSTANT : public MATH_GENERATOR
{
TMathNumber ConstValue;
TMathNumber Fx();
} *PMATH_CONSTANT;

typedef class MATH_FN : public MATH_GENERATOR
{
MATH_FUNCTIONS fn;
MATH_GENERATOR *A, *B;
TMathNumber Fx();
} *PMATH_ADD;
TMathNumber MATH_FN::Fx()
{
switch (fn) {
case MFN_ABS:
return fabsl(A->Fx());
break;
case MFN_NEG:
return -A->Fx();
break;
case MFN_FLOOR:
return floorl(A->Fx());
break;
case MFN_ADD:
return A->Fx() + B->Fx();
break;
case MFN_SUBTRACT:
return A->Fx() - B->Fx();
break;
case MFN_MULTIPLY:
return A->Fx() * B->Fx();
break;
case MFN_DIVIDE:
{
TMathNumber x = B->Fx();
if (x == 0)
{
return 1.0L / 0.0L;
}
return A->Fx() / x;
}
break;
case MFN_SIN:
return sinl(A->Fx());
break;
case MFN_COS:
return cosl(A->Fx());
break;
case MFN_TAN:
return tanl(A->Fx());
break;
case MFN_COT:
{
TMathNumber x = tanl(A->Fx());
if (x == 0)
{
return 1.0L / 0.0L;
}
return 1.0L / x;
}
break;
case MFN_EXP:
return expl(A->Fx());
break;
case MFN_LN:
return logl(A->Fx());
break;
case MFN_EXP2:
return expl(B->Fx() * logl(A->Fx()));
break;
case MFN_LN2:
return logl(A->Fx()) / logl(B->Fx());
break;
default:
return 0.0L;
;
}
}

#endif

شما هم اگه چیزی نوشتید خوشحال میشیم ببینیم.