1. C# / Говнокод #25527

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    static class MathParser
    {
        static double getFunc(char op, double a, double b)
        {
            switch (op)
            {
                case '+': return a + b;   case '-': return a - b;
                case '*': return a * b;   case '/': return a / b;   case '%': return a % b;
                case '^': return Pow(a, b);   default: return double.NaN;
            }       
        }
        static char[][] ops = { new char[] { '+', '-' }, new char[] { '*', '/', '%' }, new char[] { '^' } };
        public static double Eval(string str) => Eval(ref str, 0, str.Length);
        private static double Eval(ref string str, int z, int l, int i = 0)
        {
            for (; i < 3; i++)
                for (int v = l - 1; v >= z; v--)
                    for (int j = ops[i].Length - 1; j >= 0; j--)
                        if (str[v] == ops[i][j])
                            return getFunc(str[v], 
                                Eval(ref str, z, v, i),
                                Eval(ref str, v + 1, l, i + 1));
            return double.Parse(str.Substring(z, l - z));
        }
    }

    Какой-то укуренный калькулятор получился...
    MathParser.Eval("3,1346") => 3.1346
    MathParser.Eval("3+2*5") => 13
    MathParser.Eval("2^5-1") => 31
    MathParser.Eval("1/2^3") => 0.125
    MathParser.Eval("2^2^2^2") => 256
    MathParser.Eval("7,2%3") => 1.2

    Запостил: groser, 09 Апреля 2019

    Комментарии (39) RSS

    • 6546
      Ответить
    • PZX54(P^)
      Ответить
    • В чём смысл стринги по ссылке передавать?
      Ответить
      • Чтобы можно было её испортить из функции.
        Ответить
        • Так он её только читает.
          Ответить
          • А это уже деталь конкретной реализации. Сегодня читает, а завтра насрёт. Я бы не стал на это полагаться.
            Ответить
            • Вдруг мы решим добавить в калькулятор поддержку самомодифицирующегося кода.
              Ответить
        • А еще можно объекты портить, прямо внутри конструктора!
          Пользуйтесь константными констукторами.
          Ответить
      • В сисярпе стринги тоже иммутабельные? Какой онскилл )))
        Ответить
        • Проще сказать где они мутабельны - а хуй его знает, где.
          Везде идёт подмена блока.
          Ответить
          • Именно поэтому я за «C».
            Ответить
          • QString же. Там можно вызвать data() и срать в память.
            Ответить
            • Но буфер при этом скопируется и кроме тебя никто эти изменения не увидит. Там же cow.
              Ответить
              • Корова не нужна.
                Ответить
              • Ну, естественно. Изменения увидит только тот объект класса QString, от которого мы вызвали data. Если у нас void foo(QString arg), то с arg мы можем делать что угодно.
                Ответить
            • Про std::string даже не вспомнили?
              Ответить
              • А зачем про это говно вспоминать?
                Ответить
                • Чем QString лучше?
                  Ответить
                  • Чем std::string Удобный API, в котором есть все основные операции, а также низкоуровневые функции типа создания из указателя. Форматирование. Поддержка unicode. Thread-safe implicit sharing with copy-on-write.
                    Ответить
                  • Как массив байтиков std::string нормально себя показывает. Но класс строки, в котором нет даже ёбанных toLower()/toUpper() — это какой-то… багор.
                    Ответить
                    • Имхо, строка и должна быть просто контейнером символов. А все эти toLower(), join() и прочая поебень - внешними функциями.

                      Иначе строка превращается в какой-то ебучий god object.
                      Ответить
                      • Возможно, но всё равно же должен быть какой-то упрощённый интерфейс для часто используемых операций. Вот эти вот «std::transform(str.begin(), str.end(), [](unsigned char c) { return ::tolower(c); })» — это ж пиздец ёбанный!
                        Ответить
                        • И ещё я забыл указать выходной итератор, блядь.

                          >>> str = 'HeLLo'
                          >>> str.lower()
                          'hello'
                          Ответить
                        • Я себе это представляю как std::toLower(str).
                          Ответить
                          • Хотя бы так. Но Комитет, видимо, очень не любит функции, принимающие ссылки на контейнеры — слишком невербозно для крестов. Возможно, через десяток лет доведут до ума эти ваши концепты и ренджи, тогда-то и заживём!
                            Ответить
                        • > str.begin()
                          std::begin(str) же! Чтобы для массивов тоже работало.
                          Ответить
                    • Ты вроде сам кидал примеры, из-за которых нельзя сделать правильные toLower/toUpper
                      Ответить
                      • Это в крестах нельзя. В нормальных языках — можно.
                        Ответить
                        • В этих ваших ёбаных бустах и кутэ можно, а в стандарте нельзя.
                          Ответить
          • не знаю
            Ответить
          • Тип string в «Трубопаскакале» был мутабельным: заранее выделялось 256 байт (один под длину, 255 под символы) или сколько укажешь (если в квадратных скобочках указываешь максимальную длину).

            Поскольку длина ограничена, реаллокация не нужна.

            Правда, толку от таких коротеньких строк немного...
            Ответить
      • В делфях можно так: function lol(const s:string);

        Это будет означать передачу по указателю. Счётчик ссылок при этом не работает и память не выделяется. Короче, чисто для оптимизации.
        Ответить
        • Вообще для любых переменных var и const означают передачу по ссылке без копирования. «По ссылке» –— это такой синтаксический сахар: на самом деле передаётся указатель, но разыменовывать его не нужно. Разница между var и const в том, что в случае const компилятор проверяет, что в теле функции отсутствуют попытки изменить значение переменной.

          Для параметров без var и const вызывается «копирующий конструктор»: скалярные значения пушатся в стек (или передаются через регистры в случае fastcall), для структурированных же в стеке создаётся копия, а потом отправляется указатель на копию.

          С const всё ясно: поскольку запретили изменять, то и указатель не будет изменяться.

          Интереснее, что происходит со строками в случае var и в случае передачи по значению.
          Ответить
          • К сожалению, я не знаю, что происходит под капотом на уровне асма, но знаю, что при обращении к строке по значению (
            procedure lol(s:string)
            ), будет создана ее копия, с помощью неявно вызываемой UniqueString. Если же попытаться обратиться к этой строке по указателю, ее память легко можно изменять - и похуй, ссылка ли там, const или var. Компилятор полагает, раз программист юзает указатель - он знает, чтоон делает.
            Ответить
            • Совсем по-другому обстоят дела с литералами; линкер помещает их в область памяти, доступную только для чтения. Любые попытки изменить ее приведут к краху. Поэтому, UniqueString нужно вызывать уже явно.
              Ответить
    • Блять, как сложно... Именно поэтому я за алгоритм рекурсивного спуска.
      Ответить

    Добавить комментарий