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

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

    • 6546
      Ответить
    • PZX54(P^)
      Ответить
    • В чём смысл стринги по ссылке передавать?
      Ответить
      • Чтобы можно было её испортить из функции.
        Ответить
        • Так он её только читает.
          Ответить
          • А это уже деталь конкретной реализации. Сегодня читает, а завтра насрёт. Я бы не стал на это полагаться.
            Ответить
            • Вдруг мы решим добавить в калькулятор поддержку самомодифицирующегося кода.
              Ответить
        • А еще можно объекты портить, прямо внутри конструктора!
          Пользуйтесь константными констукторами.
          Ответить
      • В сисярпе стринги тоже иммутабельные? Какой онскилл )))
        Ответить
        • Проще сказать где они мутабельны - а хуй его знает, где.
          Везде идёт подмена блока.
          Ответить
          • Именно поэтому я за «C».
            Ответить
            • в си литералы немууууууутабельны
              Ответить
              • Речь о строках. А они могут быть const и не-const, литералы всегда const.
                Ответить
              • В старых gcc можно было включить мутабельные литералы. Весь ужас в том, что иногда это реально юзали...
                Ответить
                • В Lazarus можно даже константы менять, не говоря уже о литералах.
                  Но ничего, с выходом бесплатной делфи этому уёбищё настал конец. Я верю в это.
                  Ответить
                  • В «Python» нет никаких «констант». Именно поэтому я за «Python».
                    Ответить
                  • Ору с очередного (шестой по счету обосрамс будет чи какой?) потуга броланда сделать freemium
                    Ответить
                    • Напоил тебя своей спермой, а то, что не влезло, размазал по твоему смазливому личику, проверь.
                      Ответить
                  • Lazarus –— это всего лишь IDE.
                    Ответить
                • И как это выглядело в коде?
                  Ответить
                  • В том говне, которое мне попадалось, тупо делали strtok() на литерале...
                    Ответить
          • 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
                      Ответить
                      • Это в крестах нельзя. В нормальных языках — можно.
                        Ответить
                        • В этих ваших ёбаных бустах и кутэ можно, а в стандарте нельзя.
                          Ответить
                      • во всем мире нижни регистр это lower case

                        и только в руби у нас
                        downcase
                        Ответить
                        • К слову “up” антоним “down”.
                          К слову “low” антоним “high”.

                          С точки зрения Руби всё правильно (принцип наименьшей неожиданности или как там).
                          Ответить
                          • Всё верно.
                            Руби очень сильно отличается от всех остальных языков.
                            Ответить
                          • А антоним к слову “upper” — “downer”?
                            Ответить
                            • Antonyms for upper
                              
                              low
                              unimportant
                              below
                              inferior
                              junior
                              lower
                              under


                              Какая неконсистентность (((
                              Ответить
          • не знаю
            Ответить
          • Тип string в «Трубопаскакале» был мутабельным: заранее выделялось 256 байт (один под длину, 255 под символы) или сколько укажешь (если в квадратных скобочках указываешь максимальную длину).

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

            Правда, толку от таких коротеньких строк немного...
            Ответить
            • А ещё они всегда ограничивались CRLF, и чтобы хранить многострочные строки использовали массивы строк. Именно поэтому я за array of char и pchar.
              Ответить
              • Схуяли? Броландстроки интересны тем, что они binary safe, никаких магических значений.
                Ответить
              • Не было такого. В борландовских строках можно было хранить произвольный массив байтиков, включая нулевые байты.

                Это при чтении из файловой переменной типа Text файл разбивался на строки по CRLF, но так и было задумано. Для произвольных файлов были типы file и file of byte.
                Ответить
                • P.S. Типичный пример строковой константы:
                  const stihi: string = 'Какой хардкор)))'#13#10'Какой багор)))';


                  #13#10 вне апострофов –— это и есть вставка CRLF.
                  Ответить
                • >включая нулевые байты.
                  потому что там в носу байт длины?
                  Ответить
                  • Именно так. Длина идёт отдельным полем, поэтому нам не нужны специальные значения символов.
                    Ответить
          • в руби


            за это надо платить понятием символ
            Ответить
            • А в 'J' можно менять элементы массива, в том числе строки:
              NB. всегда будет создаваться копия:
                 s =: 'alala'
                 'ooo' (0 2 4)} s
              ololo
                 NB. но если результату даётся то же имя, модификация будет инплэйс:
                 ]s =: 'zz' (1 3)} s
              azaza
              Ответить
      • В делфях можно так: function lol(const s:string);

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

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

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

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

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