نمایش نتایج 1 تا 9 از 9

نام تاپیک: ماشین حساب (آشنایی با Syntax Diagram)

  1. #1
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484

    ماشین حساب (آشنایی با Syntax Diagram)

    الگوریتم ماشین حسابی با تعریف زیر را بنویسید:
    • انجام چهار عمل اصلی با اولویت محاسباتی عملگرها طبق آنچه در زیر مشخص شده است:
      + -      عملگر یگانی (Unary)
      * /
      + - عملگر دودویی (Binary)
    • عبارات داخل پرانتز از اولویت بالاتری برخوردارند.
    • اعداد می‌توانند صحیح یا اعشاری باشند.
    • پایان هر عبارت با علامت سوال (=) مشخص می‌شود.
    • خروج از ماشین حساب با ورود حرف ایکس (X) مشخص می‌شود.
    مثال:
    2 * 3 + 4 * 5 =
    26

    2 * (3 + 4) * 5 =
    70

    2 * 3 + -4 * 5 =
    -14

    8.1 / -2.5 =
    -3.24

    X

    شرایط الگوریتم:
    • برای گرفتن عبارت مورد محاسبه از کاربر٬ تنها یک تابع به نام GetChar وجود دارد که در هر زمان تنها یک کاراکتر از کاربر گرفته و آن را برمی‌گرداند.
    • به جز آخرین کاراکتر وارد شده توسط کاربر٬ الگوریتم نباید کاراکترهای قبلی وارد شده توسط کاربر را در متغیری ذخیره کند.
    • الگوریتم ارائه شده باید بر روی هر ماشین٬ سیستم عامل و زبان برنامه‌نویسی قابل پیاده‌سازی باشد.

    ----------------------
    هدف از ارائه مسئله بالا٬ دستیابی به یک روش عمومی برای حل مسائل این چنینی است.

  2. #2
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    هیچکس حال نداره که یک راه حل ارائه بده؟ :(

  3. #3

    Re: ماشین حساب

    با عرض ادب:
    نقل قول نوشته شده توسط DelphiArea
    [*]به جز آخرین کاراکتر وارد شده توسط کاربر٬ الگوریتم نباید کاراکترهای قبلی وارد شده توسط کاربر را در متغیری ذخیره کند.
    در استفاده از از انواع دیگر متغیر ها چقدر آزادی وجود دارد؟
    آیا ماشین فرضی ما مواردی مانند رویه ها یا فراخوانی یک رویه در داخل رویه ای دیگر(+ملاحظات مربوط به استفاده از پشته و ...) را پشتیبانی می کند؟

    یه عشق برنامه نویسی خفن

  4. #4
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    سلام،

    استفاده از متغیرهای از نوع ساده به هر میزان آزاده (آرایه یا رشته حروف نوع ساده نیستند) و از هر نوع فراخوانی هم می‌شه استفاده کرد.

    از دو تا کلمه پشته و فراخوانی که بکار بردی پیداست که راه حل رو پیدا کردی. :wink:

  5. #5
    نقل قول نوشته شده توسط DelphiArea
    هیچکس حال نداره که یک راه حل ارائه بده؟ :(
    خوب این برنامه این قدر ها هم ساده نیست
    :!: که اگر قبلاٌ چنین برنامه ای ننوشته باشیم به توان به راحتی نوشت
    مثلاُ چندین سال پیش یکی ازدوستان من داشت یک برنامه می نوشت که چک کند آیا تعداد پرانتز ها درست است یا نه ؟
    من گفتم این که کاری ندارد: یک برنامه نوشتم که تعداد پرانتز ها را می شمرد آن هم اولین چیزی که وارد کرد یک چیزی شبیه این بود :cry:

    )))5+4(((


    /×××××××××××××××××××××××
    خوب به جز مسایل محاسباتی اگر کاربر دو تا جمع وارد کرد چی
    مثلاُ
    5++6=

    و خیلی چیز های دیگر ....

    خوب قراره بهترین الگوریتم نوشته بشه :wink:

  6. #6
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    نقل قول نوشته شده توسط ali11ali112000
    خوب این برنامه این قدر ها هم ساده نیست
    با دونستن تکنیکی که باید برای حل اینجور مسائل بکار برده بشه زیاد هم سخت نیست. :wink:

    نقل قول نوشته شده توسط ali11ali112000
    خوب به جز مسایل محاسباتی اگر کاربر دو تا جمع وارد کرد چی
    مثلاُ
    5++6=
    استثنا" این مثالی که زدی یک عبارت قابل قبوله چون طبق صورت مسئله هر دو علامت + و - به عنوان یک عملگر یگانی (تعیین علامت) تعریف شده‌اند. :)
    ولی خوب همونجور که گفتی پیچیدگی این مسئله بیشتر در تشخیص درست یا نادرست بودن عبارت هست تا خود محاسبه.

    نقل قول نوشته شده توسط ali11ali112000
    خوب قراره بهترین الگوریتم نوشته بشه :wink:
    حقیقتش نه! :oops:
    اگر اینجا مسائلی اینچنینی مطرح می‌شه اصلا" هدف این نیست که بهترین الگوریتم براش نوشته بشه. آن چیزی که اهمیت داره چگونگی تحلیل مسئله و روش حل اونه.

  7. #7
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    در مورد الگوریتم ماشین حساب ما استفاده از یک بافر برای گرفتن عبارت بطور کامل و سپس تجزیه کردن اجزای (Parse) آن از لحاظ فنی غیر ممکن نیست و تنها بدلیل صورت مسئله قادر به انجام آن نیستیم. اما تصور کنید که اگر قرار بود مرورگرهای وب (Web Browsers) ابتدا تمام محتوای یک صفحه را بخواندند و سپس آن را تجزیه کرده و نمایش دهند چه مقدار زمان کاربر و سرویس دهنده وب به هدر می‌رفت و ترافیک بیهوده‌ای برروی خطوط ارتباطی حاصل می‌شد (در اکثر موارد ما با دیدن تنها چند خط از یک صفحه به صفحه دیگری می‌رویم).

    در مورد ماشین حساب ورودی ما تنها یک عبارت ریاضی است که زیاد هم بزرگ نخواهد بود٬ اما متنی که توسط یک کامپایلر تجزیه تحلیل می‌شود می‌تواند به چندین میلیون خط هم برسد. در این حالت اگر کامپایلر نیاز داشت که تمام خطوط را در حافظه قرار دهد به چه میزان حافظه نیاز داشت تا تنها به این نکته پی ببرد که آیا خطایی در متن برنامه وجود دارد یا نه؟

    در مواردی که ورودی ما از الگوی خاصی (Syntax) تبعیت می‌کند٬ به منظور یافتن الگوریتم مناسب برای تجزیه اجزا (Parse) و تفسیر معنای (Semantics) هر جزء از Syntax Diagram استفاده می‌شود.

    همانند فلوچارت که می‌تواند برای نوشتن یک الگوریتم بکار ‌رود٬ Syntax Diagram هم روشی دیگر برای نوشتن یک الگوریتم است.

    حال به یافتن الگوریتم ماشین حساب می‌پردازیم تا در این مثال به چگونگی استفاده از Syntax Diagram آشنا شوید.

    برای ساده کردن عبارات از دوران ابتدایی آموخته‌ایم که:
    1. هر عبارت داخل پرانتز خود می‌تواند به عنوان عبارتی مستقل محاسبه شده و در نهایت بصورت یک عدد در عبارت اولیه جایگزین شود.
    2. علامتهای مثبت و منفی همواره پیش از یک عدد یا یک پرانتز قرار دارند (عملگرهای یگانی).
    3. حاصل ضرب و تقسیم تمام اعدادی که با عملگرهای ضرب و تقسیم به هم مرتبط هستند بدون نیاز به اولویت‌بندی قابل محاسبه بوده و حاصل می‌تواند در عبارت اولیه جایگزین گردد (عملگرهای ضرب و تقسیم).
    4. حاصل جمع و تفریق تمام اعدادی که مابین عملگرهای جمع و تفریق قرار دارند بدون نیاز به اولویت‌بندی قابل محاسبه هستند و حاصل می‌تواند در عبارت اولیه جایگزین گردد (عملگرهای جمع و تفریق دودویی).
    با این معلومات و با شروع از کلیات تا رسیدن به جزئیات (Top-Down Design) اقدام به طراحی الگوریتم می‌کنیم.


    ماشین حساب:

    ورودی می‌تواند حرف X باشد که در این صورت خارج می‌شویم یا یک عبارت و به دنبال آن علامت تساوی (=) که در این صورت دوباره از اول کار شروع می‌کنیم.


    عبارت:

    یک عبارت تشکیل شده است از یک جمله یا حاصل جمع یا تفریق دو یا چند جمله.


    جمله:

    یک جمله تشکیل شده است از یک ضریب یا حاصل ضرب یا تقسیم دو یا چند ضریب.


    ضریب:

    یک ضریب می‌تواند در ابتدا یکی از علامتهای مثبت یا منفی باشد و سپس، یا یک عدد یا یک عبارت داخل پرانتز (عبارت تعریفی است بازگشتی).


    عدد:

    یک عدد تشکیل شده است از یک نقطه (.) و سپس یک یا چند رقم، یا تنها یک یا چند رقم٬ یا یک یا چند رقم و سپس یک نقطه (.) و پس از آن یک یا چند رقم.


    رقم:

    یک رقم یکی از حروف 0 تا 9 است.



    خوب الگوریتم ما به همین سادگی نوشته شد. در هر مرحله٬ هرگاه ورودی با آنچه که در Syntax Diagram مربوطه انتظارش را داریم نخواند به معنی این است که عبارت مورد محاسبه نادرست وارد شده است.

    در بالا برای ساده کردن Syntax Diagram ها فاصله‌ها را ندید گرفته‌ام ولی همانجور که پیداست به غیر از داخل یک عدد٬ در بقیه موارد لازم است که فاصله‌ها را ندید بگیریم. برای ایم منظور با استفاده از تابع GetChar که در صورت مسئله عنوان شده است٬ تابع دیگری می‌نویسیم که در آن بر حسب پارامتر تابع بتوانیم فاصله‌ها را رد کنیم. جدا از آن این تابع آخرین حرف خوانده شده را در داخل یک متغیر که توسط همه توابع قابل دسترسی است ذخیره می‌کند.

    var
    C: Char;

    const
    BlankChars = [' ', #9, #10, #13];

    procedure FetchNextChar(SkipBlanks: Boolean);
    begin
    repeat
    C := GetChar;
    until not (SkipBlanks and (C in BlankChars));
    end;

    و بدنبال توابع مربوط به هر Syntax Diagram نوشته شده است. هر تابع در صورت برخورد با خطا مقدار False را برمی‌گرداند٬ والا مقدار برگشتی True است.


    ماشین حساب:

    procedure Calculator;
    var
    Value: Double;
    begin
    Writeln('Enter an expression or X to exit:');
    FetchNextChar(True);
    while C <> 'X' do
    begin
    if GetExpression(Value) and (C = '=') then
    Writeln(Value)
    else
    begin
    Writeln('Illegal expression!');
    while C <> '=' do { ignores the rest of the illegal expression }
    FetchNextChar(True);
    end;
    Writeln;
    Writeln('Enter an expression or X to exit:');
    FetchNextChar(True);
    end;
    end;


    عبارت:

    function GetExpression(var Expr: Double): Boolean;
    var
    NextTerm: Double;
    Op: Char;
    begin
    Result := False;
    if GetTerm(Expr) then
    begin
    Result := True;
    while Result and (C in ['+', '-']) do
    begin
    Op := C;
    FetchNextChar(True);
    Result := False;
    if GetTerm(NextTerm) then
    begin
    case Op of
    '+': Expr := Expr + NextTerm;
    '-': Expr := Expr - NextTerm;
    end;
    Result := True;
    end;
    end;
    end;
    end;


    جمله:

    function GetTerm(var Term: Double): Boolean;
    var
    NextFactor: Double;
    Op: Char;
    begin
    Result := False;
    if GetFactor(Term) then
    begin
    Result := True;
    while Result and (C in ['*', '/']) do
    begin
    Op := C;
    FetchNextChar(True);
    Result := False;
    if GetFactor(NextFactor) then
    begin
    if Op = '*' then
    begin
    Term := Term * NextFactor;
    Result := True;
    end
    else if NextFactor <> 0 then
    begin
    Term := Term / NextFactor;
    Result := True;
    end;
    end;
    end;
    end;
    end;


    ضریب:

    function GetFactor(var Factor: Double): Boolean;
    var
    Negate: Boolean;
    begin
    Result := False;
    Negate := False;
    if C in ['+', '-'] then
    begin
    if C = '-' then
    Negate := True;
    FetchNextChar(True);
    end;
    if C = '(' then
    begin
    FetchNextChar(True);
    if GetExpression(Factor) and (C = ')') then
    begin
    FetchNextChar(True);
    Result := True;
    end;
    end
    else if GetNumber(Factor) then
    Result := True;
    if Negate then
    Factor := -Factor;
    end;


    عدد:

    function GetNumber(var Number: Double): Boolean;
    var
    Digit: Integer;
    Fraction: Double;
    PointPos, P: Integer;
    begin
    Result := False;
    Number := 0;
    while GetDigit(Digit) do
    begin
    Number := Number * 10 + Digit;
    FetchNextChar(False);
    Result := True;
    end;
    if C = '.' then
    begin
    FetchNextChar(False);
    PointPos := 0;
    while GetDigit(Digit) do
    begin
    Fraction := Digit;
    Inc(PointPos);
    for P := 1 to PointPos do
    Fraction := Fraction / 10;
    Number := Number + Fraction;
    FetchNextChar(False);
    Result := True;
    end;
    end;
    if C in BlankChars then
    FetchNextChar(True);
    end;


    رقم:

    function GetDigit(var Digit: Integer): Boolean;
    begin
    Result := False;
    if C in ['0'..'9'] then
    begin
    Digit := Ord(C) - Ord('0');
    Result := True;
    end;
    end;


    برای تمرین سعی کنید با استفاده از Syntax Diagram عملگری برای به توان رساندن و چند تابع ریاضی (مثل Sin و Cos و ...) به ماشین حساب اضافه کنید.

  8. #8

    سلام

    بحث جالبیه
    حیف که دیر رسیدم.

    من دو سال پیش یه برنامه نوشته بودم که معادله تابع رو میگیره و نمودار تابع رو رسم میکنه.
    روش محاسباتی این برنامه بسیار شبیه به الگوریتم ماشین حساب است با این تفاوت که x را به عنوان متغییر در نظر میگیره و از توابع دیگه هم میشه توی معادله استفاده کرد.

    توابعی که میشه داخل معادله استفاده کرد عبارتند از :
    sin - cos - tan - cot - abs - sqrt - ln - arctan - e - int - pi

    عملگرهای قابل استفاده عبارتند از : + ، - ، * ، / ، ^

    از پرانتز هم میشه در معادله استفاده کرد.

    ترتیب عملگرها مشابه ترتیب اونها در برنامه نویسی است.

    فایلهای مربوط به برنامه رو attach کردم.
    ولی پیشنهاد میکنم سورسش رو دانلود نکنید.
    چون من خیلی قاتی پاتی برنامه نویسی میکنم فکر نمیکنم بفهمین چیکار کردم. :lol:

    روش استفاده از برنامه به این صورته که معادله مورد نظر رو در قسمت بالای برنامه مینویسید و enter میزنید و نمودار تابع رسم میشود. به همین سادگی ...

    برای مثال یکی از معادله های زیر رو امتحان کنید :<span dir=ltr>
    sin(x)
    x^2+3*x
    sin(x)*cos(x)
    abs(sin(x))
    sin(x^2)
    </span>
    در ضمن می تونید روی صفحه حرکت کنید و زوم کنید و نشانگر موس هم مختصات شما را نشان میدهد.

    با تشکر،
    علی فرهادی

  9. #9

    نقل قول: سلام

    سلام.
    برنامه کاملی رو می خوام که نمودار sin x +ln x رو رسم کنه. می شه کمکم کنین؟؟
    ممنون. shahparsan@gmail.com

تاپیک های مشابه

  1. اشکال syntax ای
    نوشته شده توسط fatemeh rahimi در بخش ASP.NET Web Forms
    پاسخ: 2
    آخرین پست: یک شنبه 04 آذر 1386, 12:14 عصر
  2. syntax
    نوشته شده توسط prince-of-persia در بخش VB.NET
    پاسخ: 1
    آخرین پست: یک شنبه 07 مرداد 1386, 13:03 عصر
  3. راهنمایی syntax در vba ؟
    نوشته شده توسط majid325 در بخش Access
    پاسخ: 11
    آخرین پست: پنج شنبه 30 فروردین 1386, 14:38 عصر
  4. پیام خطا در SQL syntax
    نوشته شده توسط ParvanehDesigner در بخش PHP
    پاسخ: 0
    آخرین پست: سه شنبه 05 اردیبهشت 1385, 23:08 عصر
  5. Sql Syntax فوری.
    نوشته شده توسط najeeb در بخش SQL Server
    پاسخ: 8
    آخرین پست: چهارشنبه 08 مهر 1383, 10:45 صبح

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •