Akhilesh Chauhan Ответов: 2

Строка ввода математических и решение


предположим, мне придется примите математическое выражение в строковый формат от пользователя, как, например, 2*5 или 9/5+9 или 91-10+82/3 и так далее. Оно может быть любой длины. Это работает, если у меня есть операнд одной длины, например 3+9-5*4/2 по некоторым изменениям в моем приведенном ниже коде он работает нормально. но терпит неудачу, если я даю ему более одного операнда длины, например 38+12/2-7+69 или 325-69+584 и так далее на C#.

Что я уже пробовал:

Below code works fine for single length operand.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApplicationExpressionFirstDay
    {
    class Program
    {
        static void Main(string[] args)
        {
            char[] arrOne = new char[100];
            int[] arrTwo = new int[2];
            string opr="+";
            string input;
            int j = 0;
            int i = 0;
            input = Console.ReadLine();
            arrOne = input.ToCharArray();
            for (i = 0; i < arrOne.Length; i++)
            {
                
                    if (arrOne[i] >= 48 && arrOne[i] <= 57)
                    {
                            arrTwo[j] = Convert.ToInt32(char.ConvertFromUtf32(arrOne[i]));
                            j++;

                    }
                    else
                    {
                        opr =char.ConvertFromUtf32(arrOne[i]);
                    }

                if (j == 2){
                    switch (opr)
                    {
                        case "+":
                            arrTwo[0] = arrTwo[0] + arrTwo[1];
                            j = 1;
                            break;
                        case "-":
                            arrTwo[0] = arrTwo[0] - arrTwo[1];
                            j = 1;
                            break;
                        case "*":
                            arrTwo[0] = arrTwo[0] * arrTwo[1];
                            j = 1;
                            break;
                        case "/":
                            arrTwo[0] = arrTwo[0] / arrTwo[1];
                            j = 1;
                            break;
                        default:
                            j = 0;
                            break;
                    }
                }
            }
            Console.WriteLine("Result : " + arrTwo[0]);
            Console.ReadLine();

        }
    }
    }


But this code fails for more than one length operands

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApplicationExpressionFirstDay
    {
    class Program
    {
        static void Main(string[] args)
        {
            char[] arrOne = new char[100];
            int[] arrTwo = new int[2];
            string opr="+";
            string input;
            int j = 0;<pre lang="c#">int concat = 0;
            int i = 0;
            input = Console.ReadLine();
            arrOne = input.ToCharArray();
            for (i = 0; i < arrOne.Length; i++)
            {
                
                    if (arrOne[i] >= 48 && arrOne[i] <= 57)
                    {
                        if (concat == 0)
                        {
                            arrTwo[j] = Convert.ToInt32(char.ConvertFromUtf32(arrOne[i]));
                            j++;
                            concat++;
                        }
                        else
                        {
                            j = 1;
                            arrTwo[j] = Convert.ToInt32(Convert.ToString(arrTwo[1])+char.ConvertFromUtf32(arrOne[i]));
                            j++;
                            concat = 0;
                        }

                    }
                    else
                    {
                        opr =char.ConvertFromUtf32(arrOne[i]);
                        concat = 0;
                    }

                if (j == 2&&concat==0){
                    switch (opr)
                    {
                        case "+":
                            arrTwo[0] = arrTwo[0] + arrTwo[1];
                            j = 1;
                            break;
                        case "-":
                            arrTwo[0] = arrTwo[0] - arrTwo[1];
                            j = 1;
                            break;
                        case "*":
                            arrTwo[0] = arrTwo[0] * arrTwo[1];
                            j = 1;
                            break;
                        case "/":
                            arrTwo[0] = arrTwo[0] / arrTwo[1];
                            j = 1;
                            break;
                        default:
                            j = 0;
                            break;
                    }
                }
            }
            Console.WriteLine("Result : " + arrTwo[0]);
            Console.ReadLine();

        }
    }
    }

Karthik_Mahalingam

проверить это
http://www.codeproject.com/Articles/17853/Implementing-an-Excel-like-formula-engine

Richard MacCutchan

Вы не объяснили, где в вашем коде возникает проблема. Вам нужно обрабатывать каждую пару чисел по очереди, в зависимости от приоритета оператора.

Akhilesh Chauhan

Я просто хочу оценить свое выражение с первого элемента, не нуждаясь в приоритете. спасибо

Richard MacCutchan

Это не меняет того, что вам нужно делать.

Richard MacCutchan

Ваш входной синтаксический анализ выглядит не очень хорошо. Вам нужно извлечь каждое число и каждый операнд в отдельные строки, прежде чем преобразовывать их в целые числа. Как только вы это сделаете, вы сможете выполнить фактические вычисления.

Akhilesh Chauhan

У меня есть одна переменная для извлечения оператора " opr "и массив" arrTwo " из двух пакетов для хранения двух разных операндов для каждого времени.

Richard MacCutchan

Но ваш синтаксический анализ не является гибким. При извлечении чисел было бы лучше скопировать из входной строки в отдельную строку все цифры, пока вы не достигнете оператора (или конца ввода) . Сделайте то же самое для второго номера. Только тогда вы должны преобразовать эти подстроки в целые числа и вычислить общую сумму на основе оператора.

Richard MacCutchan

Смотреть также https://en.wikipedia.org/wiki/Reverse_Polish_notation.

Philippe Mori

Использует отладчик, чтобы понять, почему ваша программа не работает. Как только вы поймете это, тогда разработайте программу,которая может работать.

Кстати, было бы неплохо начать с написания класса, который будет использоваться для синтаксического анализа и сможет читать токены один за другим. Например, если у вас есть 3 последовательных цифры, они должны обрабатываться как одно число.

Другая более важная проблема с вашим кодом заключается в том, что он не уважает приоритет оператора. Умножение должно быть сделано до сложения.

Как было предложено в решении 1, вам лучше найти информацию в интернете... Создание собственного парсера с использованием только кода C#, который вы пишете сами, не имеет большого смысла, так как это много работ, в то время как лексер и парсер уже сделаны .

2 Ответов

Рейтинг:
14

OriginalGriff

Гугл - ваш друг: будьте добры и часто навещайте его. Он может ответить на вопросы гораздо быстрее, чем разместить их здесь...

Очень быстрый поиск нашел бы вам множество примеров. c# evaluate expression - поиск в Google[^] дает вам 88 000 примеров ...

Вот хороший пример: Оценка современного уровня экспрессии[^]

В будущем, пожалуйста, постарайтесь сами провести хотя бы фундаментальные исследования, а не тратить впустую свое и наше время.


Рейтинг:
12

Akhilesh Chauhan

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplicationExpressionUsingWhileLoop
{
class Program
{
    static void Main(string[] args)
    {
        char[] arrOne = new char[100];
        int[] arrTwo = new int[2];
        string opr = " ";
        string input;
        int j = 0;
        int i = 0;
        input = Console.ReadLine();
        arrOne = input.ToCharArray();
        for (i = 0; i < arrOne.Length; i++)
        {

            while(arrOne[i] >= 48 && arrOne[i] <= 57)
            {
                arrTwo[j] = Convert.ToInt32(Convert.ToString(arrTwo[j]) + char.ConvertFromUtf32(arrOne[i]));
                if (i == (arrOne.Length)-1)
                {
                    break;
                }
                else
                {
                    i++;
                }
            }
                j++;
                if (j == 2)
                {
                    switch (opr)
                    {
                        case "+":
                            arrTwo[0] = arrTwo[0] + arrTwo[1];
                            j = 1;
                            arrTwo[1] = 0;
                            break;
                        case "-":
                            arrTwo[0] = arrTwo[0] - arrTwo[1];
                            j = 1;
                            arrTwo[1] = 0;
                            break;
                        case "*":
                            arrTwo[0] = arrTwo[0] * arrTwo[1];
                            j = 1;
                            arrTwo[1] = 0;
                            break;
                        case "/":
                            arrTwo[0] = arrTwo[0] / arrTwo[1];
                            j = 1;
                            arrTwo[1] = 0;
                            break;
                        default:
                            j = 0;
                            break;
                    }
                }
                opr = char.ConvertFromUtf32(arrOne[i]);
        }
        Console.WriteLine("Result : " + arrTwo[0]);
        Console.ReadLine();

    }
}
}


Philippe Mori

Вместо этого обновите свой вопрос...