На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
  
> Рассуждения на тему "С++ vs интерпретируемые языки"
    У всех языков свои особенности. Нельзя даже сказать что достоинства или недостатки. Где-то достоинства, а где-то недостатки.

    У C++ одна из основных ключевых фишек это итераторы. Везде и всегда итераторы. Ими можно осуществлять ввод, вывод, перебор, перестановку, перемещение, копирование, заполнение и так далее. Даже указать позицию для вставки или элемент для удаления.

    У C# его енумераторы, как-бы предоставляют базовую функциональность итераторов, но труба пониже, а дым пожиже. Можно перечислить коллекцию. Можно даже что-то сэмитировать. Но этого мало. А в итоге приходится огород городить. С другой же стороны в C# чуть иная объектная модель. Например, ту же задачу для C# я бы решил передав объект абстрактного типа TextWriter. А там уже пофиг какой именно объект StreamWriter, StringWriter или иное чудо-юдо.
    Но это корректно именно в C#. А для C++ просто так поток не передать. Ну, тоесть можно передать ссылку, а внутри хранить указатель на std::ostream. Раньше, кстати, именно так и делал, но такой код выглядит неестественным. Да уж, если говорить прямо, то старомодным. Использование чистых небезопасных указателей, это весьма рискованный ход повышающий шанс отстрелить себе ногу. К тому же это создаёт искуственные ограничения. А ведь до чего же удобно, записать текст прямо в строку, не дёргая потоки.

    У php и видимо большинства скриптовых языков, дела с итераторами и перечислениями обстоят ещё хуже. Ну что это за ботва, когда енумератор скрыт в самом контейнере? Да, на простых задачках это удобно и даже в чём-то упрощает жизнь. А что делать если надо два или три перечислителя? Тогда же приходится совсем жутко извращаться, доходя даже до полного дублирования самого контейнера. С другой же стороны, у скриптовых языков, проблемы типизации объектов, не стоят так остро и можно юзать трюки, которые в плюсах доступны лишь через шаблоны.

    Кстати, я внедоумении от файловых потоков в C++. Они, помоему, слишком ретроградны. Используют тоже один или два курсора, вместо итератора. А ведь эти потоки, можно и даже нужно рассматривать, как полноценные контейнеры вроде std::vector или std::list. Это позволило бы упростить алгоритмы и унифицировать внутренние сущности. Единственное что их оправдывает, так это обратная совместимость и традиционность.

    А касательно концептов, так их обещались добавить в C++17. Так что жду и недождусь.
    http://zouev.blogspot.ru/2009/07/blog-post_09.html

    Я же не имея возможности воспользоватся автогенератором кода, был вынужден написать примерно то, как представляю механизм реализованный под копотом концептов. Это выглядит чудовищно... Но всё же, хоть так.
    А ведь в принципе, думаю, что это позволит, например в скомпилированную библиотеку направлять итераторы. Поскольку обёртка инстанцируется на стороне клиента, а реализация на стороне обработчика.

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

    Эта тема была разделена из темы "как передать произвольный итератор в скомпилированный класс?"
    Сообщение отредактировано: Eric-S -
      Видя такой код, я все больше и больше испытываю, мягко говоря, "уныние" от ЯП со статической типизацией. И все эти уверения "да это же помощь программисту!" сродни украинским СМИ :lol:

      Что мы имеет по сути? Есть некоторая функция, которая берет на вход контейнер (ну не контейнер, а его части, отдаваемые итератором) и функциональный объект, производит обработку. И все. А сколько усилий для преодоления "помощи программисту" :lool:

      Цитата Eric-S @
      Ну что это за ботва, когда енумератор скрыт в самом контейнере? Да, на простых задачках это удобно и даже в чём-то упрощает жизнь. А что делать если надо два или три перечислителя?


      Вот нельзя так огульно за все языки говорить. Возьму и добавлю свой Энумератор.
      Более того, есть возможность с помощью метатаблиц переоперделить оператор [], но это уже другая тема, тут не буду.

      Пример на Lua:

      ExpandedWrap disabled
        -- инициализация -----------------------------------
         
        Array = {1,2," три ",4,5," шесть ",7,8,9}
         
        -- свойство таблицы --------------------------------
         
        function Array:EnumeratorEven(Idx)
          return Idx*2 > #self and nil or Idx*2
        end
         
        -- печать таблицы по определенному свойству  -------
         
        function PrintEven(Container)
          local I,R = 0,''
          repeat
            I = I + 1  
            local T = Array[Array:EnumeratorEven(I)]
            if T then R = R .. T else break end
          until (false)
          print("Res: " .. R)  
        end
         
        -- точка начала исполнения -------------------------
         
        PrintEven(Array)


      Я понимаю, код не Бог весть какой, но мне простительно - изучаю Lua только один день. Внезапно понадобилось. А вот теперь представим сколько тонн шаблонов из STL потянет! А тут - просто свойства и особенности языка.

      ЗЫ: Lua - второе "откровение" после Руби, в целом "просто отлично"!
        Цитата JoeUser @
        Видя такой код, я все больше и больше испытываю, мягко говоря, "уныние" от ЯП со статической типизацией. И все эти уверения "да это же помощь программисту!" сродни украинским СМИ :lol:

        Э, нет. Дело не в статической типизации. А в компиляции в машинный код.
        Я бы обошёлся бы без всего этого, если бы сделал функцию шаблонной. То есть, хоп, функция шаблонная, и мне обёртка нафиг не нужна.
        Только я захотел нешаблонную функцию, а значит поехали приключения.
        Что же касается интерпретируемых языков, то они ведь все шаблонные по определению.

        Далее, если бы у всех классов, был бы единый базовый класс, да ещё бы в стандартной библиотеки имелись огромные коллекции интерфейсов на все случии жизни, причём всё и всегда передавалось бы по указателю, то вопрос опять бы не стоял. Конечно, это всё можно сделать. Но стоить будет слишком дорого.
        Банальная виртуализация зачастую избыточна. А значит от неё можно и нужно избавиться.Пусть будет опциональной, лишь для тех кому она нужна.
        Объекты в динамической памяти излишняя роскошь. Мелочь можно хранить на стеке. А значит динамическая память только опционально, когда она действительно нужна.

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

        Конечно, C++ уже морально устарел. У него много недостатков, а развитие слишком медленное. Но именно C++ позволяет мне делать всякие вкусняшки, которые труднодостижимы в интерпретируемых языках. При всей своей крутизне, даже сайтостроители, отказываются от интерпретаторов, в пользу C и C++.

        У других языков, вроде D или Rust тоже есть свои вкусняшки. Но они в погоне за плюшками, потеряли этакую своеобразную наивную чистоту C++.
          Цитата Eric-S @
          Но именно C++ позволяет мне делать всякие вкусняшки, которые труднодостижимы в интерпретируемых языках.

          Слабо верится :) Можно пример?
            Цитата JoeUser @
            Слабо верится :) Можно пример?

            Ну например частотный анализ звукового сигнала в реальном времени. Или даже банальная склейка фонем, опять же в реальном времени.
            Чтобы были бинарные буфера, которые поочереди подсовываются звуковухе для заполнения, а затем шерстятся несколькими алгоритмами вдоль и поперёк, определяя спектры частот, делают слепки, сравнивая их с базой данных, загруженной в память...

            А вот сейчас модернезирую обработку текста с распознанием внутренних лексических сущностей и моделированием разнообразных взаимодействий. Интерпретаторы от такого кошмарика ложатся из-за банальной нехватки памяти и быстродействия. Пробовал набрасывать отдельные элементы. Так разница по скорости обработки в тысячу раз.
            Ради интереса попробовал сделать загрузку и декодирование файлов на ruby... и озадачился кодировками. Почему-то не придумалось, как добавить парочку велосипедов. Да и хитрые алгоритмы поиска слов, не слишком удобно делать. Я лишь прикинул и решил, что не взлетит.

            Впринципе языки вроде rust, java, c# дают уже неплохую скорость. Но в них, труднее выразить некоторые абстракции, которые на C++ делаю банальным множественным наследованием. То есть языки с одиночным наследованием, ограничивают код по выразительности.

            Ах да, и конечно же, C++ позволяет мне обернуть вызов любой системной функции, с минимальными накладными расходами. Когда я написал словарь на C# (словарь в смысле базу данных специализированную для хранения и выборки слов), то очень огорчился низкой скоростью. На C++ этот же словарь (частично доделаный) работает гораздо быстрее. Ну да там ещё дело в конвертации типов данных и в маршализации. На C++ оно тоже получается быстрее и проще. А уж до чего прикольный конвертор получился на шаблонах... Я когда пытался повторить его на C# почти рыдал от невозможности прогнуть язык под свои хотелки.
            Сообщение отредактировано: Eric-S -
              Цитата Eric-S @
              Интерпретаторы от такого кошмарика ложатся из-за банальной нехватки памяти и быстродействия. Пробовал набрасывать отдельные элементы. Так разница по скорости обработки в тысячу раз.


              Остается верить на слово :lol: На каком интерпретируемом ЯП ты это пробовал?
                Ты прав. В холиварах этому диалогу самое место.

                Цитата JoeUser @
                Остается верить на слово :lol: На каком интерпретируемом ЯП ты это пробовал?


                Глупо верить любым голословным утверждениям, даже моим.
                Ради справедливости, надо переписать и протестировать идентичный функционал. Тогда получатся более реальные тайминги.

                Я начинал на C#. Попробовал перенести на php, но почти сразу бросил, обнаружив тормоза и уперевшись в доступный объём памяти. php брал как единственный известный мне кросплатформенный язык, способный из коробки открывать и писать файлы.

                За образец функционала, точнее за идею, брал код спелчекера на nodejs и морфера на python. Они делали нечто похожее, но с функциональными ограничениями.

                Откровенно говоря, подходы и опирации различались.
                То есть функционал далеко неоднозначный.

                Суть алгоритма объяснять долго, поскольку некоторые моменты не выкрестолизовались в моей голове. Там много мелких нюансов. Возможно ещё буду приставать к народу по этому поводу.

                Но если упрощать, то одну из задач, можно свести к постраению графа сырых слов. В точке само слово. А связи соединяют его с похожими словами.
                Сырые слова, в том смысле, что выдернутые прямо из текста, без какой либо морфологической и прочей обработки.
                Сравнивать надо всё со всем и чем больше слов, тем лучше.

                В конечном результате, программа, чисто эврестически должна создать словарь слов проставив каждому слову оценку его корректности.

                Там много всякого накручено, так что для более-менее адекватной синтетической замены, можно попробовать забацать классическую пузырьковую сортировку строк на огромном массиве.
                Сообщение отредактировано: Eric-S -
                  Вообще читая всякие тесты когда один язык сравнивается с другим, я каждый раз замечал, что тестировщик либо пишет неоптимальный код, либо какой-то язык из коробки приспособлен лучше для решения конкретной задачи, чем другой.
                  Так что в идеале, надо сравнивать примеры кода, написанные упоротыми фанатиками конкретного языка. Но тогда опять же алгоритмы будут различатся, затрудняя сравнения.
                  А ещё смущают некоторые вставки... Например php-разработчик вызывает функцию написанную на C. И приэтом считает себя выйгравшим. Мол php быстрее чем C.
                    Цитата Eric-S @
                    Там много всякого накручено, так что для более-менее адекватной синтетической замены, можно попробовать забацать классическую пузырьковую сортировку строк на огромном массиве.


                    Ну давай сравним :lol: С тебя реализация на С++ исполняемого файла. Постановка задачи простая:

                    1) Прочитать из текстового файла, заданного как аргумент командной строки, текст
                    2) Разбить на слова, разделителями слов являются: пробел, знак табуляции, перевод строки, возврат каретки
                    3) Вывести в STDOUT все найденные слова в порядке убывания частот, в формате слово : число_посторений

                    А я все тоже самое сделаю на Perl, Ruby, Lua - и запущу для теста на своей машине, результаты отпищу тут.
                    Для теста попробую собрать "эталоны" текстовых файлов в 100Мb, 500Mb, 1Gb, 4Gb

                    Договорились?

                    Добавлено
                    Цитата Eric-S @
                    Например php-разработчик вызывает функцию написанную на C. И приэтом считает себя выйгравшим.

                    Имеет право :) Ты же на C++ используешь API ОС, не пишешь свои драйвера? Почему бы мне не пользоваться, к примеру, на том же Perl'е модулем, который юзает чужую динамическую либу, которая позволит мне перенести часть вычислений на GPU, просто, чтобы перегнать тебя и "наказать за самоуверенность" :lol:
                      Цитата JoeUser @
                      Договорились?

                      Ох... И не лень?

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

                      Ладно... Я подумаю ещё. Может и напишу. Шибко оно похоже на "а тебе слабо?" От такого я бегу как от огня. Тем более стрёмно отстаивать честь C++, словно я самый крайний.

                      А вообще, надобы обговорить условия. Что можно использовать, а чего нельзя.
                      Очень хочется предложить повозможности использовать язык, а не его стандартную библиотеку. Но тут же возникает ощущение, что собираюсь обидеть ребёнка.

                      Цитата JoeUser @
                      Почему бы мне не пользоваться, к примеру, на том же Perl'е модулем, который юзает чужую динамическую либу, которая позволит мне перенести часть вычислений на GPU, просто, чтобы перегнать тебя и "наказать за самоуверенность" :lol:

                      Эх... Вот тут и вылизают недостатки синтетических тестов.
                      А зачем тогда вообще чего-то писать, если есть стандартные утилиты?

                      Вот ты предлагаешь выборку слова, определив конкретные разделители. Угу, тут всё просто, дёргаем функцию split или чего-нибудь вроде неё.
                      Но результат будет синтетический и нафиг ненужный.
                      Тоесть сам тест окажется притянутым зауши.

                      А как насчёт выборки реальных слов из реального текста? Там, где эти разделители хрен знает что. И уже хотя бы поэтому, стандартную функцию нельзя дёрнуть, а придётся писать свою функцию. Именно свою, поскольку в стандартных либах такой функции нет. Ну вот например знак '-' может разделять слова, а может быть внутри них. Знак точки может быть внутри слова, а может быть в конце предложения.

                      А как насчёт реального корректного сравнения слов? С учётом спецефичных особенностей? Слова надо раставить без учёта регистра, без учёта преффиксных и суффиксных символов и даже считая, но не ломая букву 'ё'?

                      Тут ведь подвох в самой задаче. Потому я и говорю, что мне ненравятся синтетические тесты. И сама задача надуманная. И условия подбираются так, чтоб компьютеру их было проще решить.

                      Я ведь не олемпиадник. И некоторые вещи из принципа делаю определённым образом. Например читаю и пишу файл потоками std::ifstream, std::ofstream. А тут, при постановке задачи, так и напрашивается открыть файл через CreateFilе. Я обычно использую стандартное выделение памяти, через vector или make_shared... Но тут так и хочется заюзать VirtualAlloc. То есть решение-то сильное, но далеко не жизненное.
                      И да, хочу заметить, что в большинстве известных мне интерпретаторов, включая и интерпретаторы байткода, используют спецефические менеджеры памяти. То есть будет очень даже справедливо, если я заюзаю тоже спецефический менеджер памяти.
                      Сообщение отредактировано: Eric-S -
                        Цитата Eric-S @
                        А как насчёт реального корректного сравнения слов? С учётом спецефичных особенностей? Слова надо раставить без учёта регистра, без учёта преффиксных и суффиксных символов и даже считая, но не ломая букву 'ё'?


                        В том-то и дело ... не нужно городить мозговыносный тест, что-то простое ... как сам сказал, без никаких либ, чисто инструментами языка.
                        Вот сам посуди. Пока ты размышлял о кораблях, бороздящих просторы тестов ... я собственно тест (тупо влоб) написал:

                        ExpandedWrap disabled
                          #!/usr/bin/perl
                          open (FD,$ARGV[0]) || die "Shit!";
                          map {$Freq{$_}++;} split /\s+/, join "", <FD>;
                          close (FD);
                          map {print $_." : ".$Freq{$_}."\n";} sort {$Freq{$b}<=>$Freq{$a}} keys %Freq;


                        Оптимизаций нуль. Но на малых текстах - твое время написания кода на С++, да плюс его выполнение - будут медленнее.
                        Уже медленее. Улавливаешь суть? :lol:

                        Добавлено
                        Цитата Eric-S @
                        Но тут так и хочется заюзать VirtualAlloc

                        На больших файлах - надо mmap, имхо. И по скорости, и по гемору - меньше.
                          Цитата JoeUser @
                          Вот сам посуди. Пока ты размышлял о кораблях, бороздящих просторы тестов ... я собственно тест (тупо влоб) написал:

                          Вообще-то мне тупо лень сейчас чего-то писать. Зато есть огромное желание защитить результат от жульнечества. Если уж тестить, то результат должен быть максимально объективным.

                          Добавлено
                          Цитата JoeUser @
                          Но на малых текстах - твое время написания кода на С++, да плюс его выполнение - будут медленнее.

                          Это естественно. Как я писал ранее, задачи у языков разные.

                          Добавлено
                          Цитата JoeUser @
                          На больших файлах - надо mmap, имхо. И по скорости, и по гемору - меньше.

                          Может быть и так, но я эту тему вообще не колупал.
                            Цитата Eric-S @
                            Если уж тестить, то результат должен быть максимально объективным.

                            Ну пока то у тя и защищать-то нечего)

                            Добавлено
                            Цитата Eric-S @
                            Может быть и так, но я эту тему вообще не колупал.

                            Да тут все просто как грабли - управление чтением и размещением данных в страницах памяти ты отдаешь на откуп операционной системе ... а "не учишь её как ей правильно жить" :)
                              Цитата JoeUser @
                              Пока ты размышлял о кораблях, бороздящих просторы тестов ... я собственно тест (тупо влоб) написал:

                              ExpandedWrap disabled
                                #!/usr/bin/perl
                                open (FD,$ARGV[0]) || die "Shit!";
                                map {$Freq{$_}++;} split /\s+/, join "", <FD>;
                                close (FD);
                                map {print $_." : ".$Freq{$_}."\n";} sort {$Freq{$b}<=>$Freq{$a}} keys %Freq;


                              Оптимизаций нуль. Но на малых текстах - твое время написания кода на С++, да плюс его выполнение - будут медленнее.

                              Ну тупо в лоб и на C++ примерно так же:
                              ExpandedWrap disabled
                                ifstream f(argv[0]);
                                string word;
                                unordered_map<string, size_t> dict;
                                while (f >> word) ++dict[word];
                                vector<pair<string, int> > res;
                                res.reserve(dict.size());
                                copy(dict.begin(), dict.end(), back_inserter(res));
                                sort(res.begin(), res.end(), [](const auto & a, const auto & b) {return a.second > b.second;});
                                for (auto & w_c : res) cout << w_c.first << " : " << w_c.second << endl;

                              Не? :D
                              Код не проверял, если что
                                Цитата D_KEY @
                                Код не проверял, если что

                                Норм код :)

                                Цитата D_KEY @
                                Не?

                                Ну а если по-честноку, то:

                                ExpandedWrap disabled
                                  #include <unordered_map>
                                  #include <algorithm>
                                  #include <iostream>
                                  #include <sstream>
                                  #include <vector>
                                   
                                  using namespace std;
                                   
                                  int main() {
                                      stringstream f("Мама мыла мыла раму");
                                      string word;
                                      unordered_map<string, size_t> dict;
                                      while (f >> word) ++dict[word];
                                      vector<pair<string, int> > res;
                                      res.reserve(dict.size());
                                      copy(dict.begin(), dict.end(), back_inserter(res));
                                      sort(res.begin(), res.end(), [](const auto & a, const auto & b) {return a.second > b.second;});
                                      for (auto & w_c : res) cout << w_c.first << " : " << w_c.second << endl;
                                      return 0;
                                  }


                                Т.е. +заголовки, +main, и +необработанный fstream. И это еще не все ... Это +подтягивание STL-а ...
                                А этого не хотел Eric-S, типа "давай без либ!". Я все исполнил честно :)

                                ЗЫ: Если с либами - заходим на http://www.cpan.org/ и выбираем модуль из которого будем писать программу в одну строчку :lol: Ну или почти ...
                                  D_KEY, а давай ты и я внесем в свой код правки - в качестве разделителей дополнительно считать разделителями < > ' " ) ( , . - + : ; ! ?
                                  Ну и посмотрим, сколько нам потребуется кликов для доработки? :)

                                  Скрытый текст
                                  Если че, у меня все готово ... :lol:

                                  ExpandedWrap disabled
                                    #!/usr/bin/perl
                                     
                                    open (FD,$ARGV[0]) || die "Shit!";
                                    map {$Freq{$_}++;} split /[-+\(\)\.,:\+\s;><"'\?!]+/, join "", <FD>;
                                    close (FD);
                                    map {print $_." : ".$Freq{$_}."\n";} sort {$Freq{$b}<=>$Freq{$a}} keys %Freq;
                                    Цитата JoeUser @
                                    А этого не хотел Eric-S, типа "давай без либ!".

                                    Хотел или нет, это неважно. Просто, помоему, задача, слишком синтетическая, чтобы дать практически полезный результат.
                                    Это именно что холивар, тоесть пиписькомер. А внешний размер, далеко не главное.
                                    Вы бы чем-нибудь более полезным занялись!

                                    А если же по коду... Ну очевидно же, что разбивать строки на новые строки не эффективно. Надо запоминать начало и конец слова в объекте. А уже эти объекты обрабатывать.
                                    Сообщение отредактировано: Eric-S -
                                      Цитата Eric-S @
                                      А если же по коду... Ну очевидно же, что разбивать строки на новые строки не эффективно. Надо запоминать начало и конец слова в объекте. А уже эти объекты обрабатывать.

                                      Ну так это делается с помощью конечного автомата. Однако и регулярки - тот же конечный автомат, только предварительно компилируемый во время исполнения. Более того, в сишной библиотеке PCRE ничего не разбивается - там возвращается массив индексов соответствия паттерну. В Perl'е встроенный механизм другой. Поэтому тебе наверное стоит написать именно разработчику языка о том, что он не прав :lol:
                                        Регулярки тормозить будут, мама не горюй.
                                          Цитата applegame @
                                          Регулярки тормозить будут, мама не горюй.

                                          За удобства нужно платить. Тем не менее, при составлении регулярок есть некоторое (хотя и слабое) соответствие составлению запросов на SQL. И на SQL-ле можно составить запрос так, что сервер попросит прощения человеческим голосом.

                                          Не спорю, лучше зарядить уж связку Bison/Flex - но, имхо, это уж очень узко-специализированные применения, где выжимать нужно по максимуму. Регулярок "в быту" за глаза хватает.
                                            Цитата JoeUser @
                                            За удобства нужно платить. Тем не менее, при составлении регулярок есть некоторое (хотя и слабое) соответствие составлению запросов на SQL.
                                            Удобства? По мне так из пушки по воробьям. Неужели в перле нет простого сплита без регулярок? И кстати, твоя программа осилит файло в UTF-8?
                                            Вот решение задачи на D (текст должен быть в UTF-8), без оптимизаций, файло тупо грузится целиком в оперативу:
                                            ExpandedWrap disabled
                                              import std.file;
                                              import std.stdio;
                                              import std.array;
                                              import std.algorithm;
                                               
                                              void main(string[] args) {
                                                  int[string] words;
                                                  readText(args[1])
                                                      .splitter!(c => canFind(" \n\r\t<>'\")(,.-+:;!?", c))
                                                      .filter!(w => !w.empty)
                                                      .each!(w => words[w]++);
                                                  words
                                                      .byKeyValue
                                                      .array
                                                      .sort!((a, b) => a.value > b.value)
                                                      .each!(p => writefln("%s: %s", p.key, p.value));    
                                              }

                                            Цитата JoeUser @
                                            Не спорю, лучше зарядить уж связку Bison/Flex - но, имхо, это уж очень узко-специализированные применения, где выжимать нужно по максимуму. Регулярок "в быту" за глаза хватает.
                                            Накой для такой примитивной задачи Bison/Flex? :blink:

                                            Тестовй файлик: Прикреплённый файлПрикреплённый файлtest.txt (15,28 Кбайт, скачиваний: 193)
                                            Сообщение отредактировано: applegame -
                                              Цитата applegame @
                                              Неужели в перле нет простого сплита без регулярок?

                                              Нету. Может библиотечные и есть, но языковая конструкция - только на регулярках.

                                              Цитата applegame @
                                              И кстати, твоя программа осилит файло в UTF-8?

                                              Нужно добавить в начало "use encoding 'utf8';" тогда осилит.

                                              Цитата applegame @
                                              Вот решение задачи на D

                                              Ниче так - кросава :)

                                              Цитата applegame @
                                              Накой для такой примитивной задачи Bison/Flex?

                                              Да в начале разговора вообще шла тема запредельных нагрузок, поэтому и решил, что построить автоматы надо заранее.
                                                Цитата applegame @
                                                Вот решение задачи на D

                                                Очень похоже на Ruby :)

                                                ExpandedWrap disabled
                                                  H = {}
                                                  File.open("Testo.txt","r:UTF-8"){|f| f.read}
                                                   .split(/[-+\(\)\.,:\+\s;><"'\?!]+/)
                                                    .collect{|w| H[w] = H[w].to_i.succ}
                                                  H.sort_by(&:last)
                                                    .reverse!.each {|k,v| puts "#{k} : #{v}\n"}
                                                  Цитата applegame @
                                                  Накой для такой примитивной задачи Bison/Flex?
                                                  Вообще-то bison не нужен, достаточно одного flex'а. Программа должна получиться строк на десять, не больше.
                                                    Цитата amk @
                                                    Вообще-то bison не нужен, достаточно одного flex'а.

                                                    У тебя есть практика использования?
                                                      Цитата amk @
                                                      Программа должна получиться строк на десять, не больше.
                                                      Прекрасно, давай ее сюды.
                                                        Цитата JoeUser @
                                                        Я пользовался когда-то lex и C.
                                                        Цитата applegame @
                                                        Прекрасно, давай ее сюды.
                                                        А она что, кому-нибудь нужна? Просто мне лень ставить нужные для проверки кода программы.

                                                        Добавлено
                                                        Если бы мне эту задачу пришлось решать, я бы её на питоне решал.
                                                        ExpandedWrap disabled
                                                          from re import finditer
                                                          from collections import Counter
                                                          from sys import argv
                                                          wordcount = Counter()
                                                          for line in open(argv[1], 'rt', encoding='cp1251'):
                                                              for word in finditer('[^-+().,:\s;><"\'?!]', line)
                                                                  wordcount[word] += 1
                                                          for count, wors in sorted((c, w) for w, c in wordcount.items()):
                                                              print(word, count)

                                                        Вот примерно так.
                                                          Цитата amk @
                                                          '[^-+().,:\s;><"\'?!]'

                                                          Подозрительная регулярка - имхо, кривая.
                                                            Да, перед s надо двойной бэкслэш поставить
                                                            А всё остальное там правильно. В квадратных скобках почти все спецсимволы теряют своё специальное значение.
                                                              Цитата amk @
                                                              почти все спецсимволы

                                                              Со знаком минус нужно быть аккуратнее, если нужен именно символ "-" - нужно его ставить последним, перед закрывающей скобкой.

                                                              Добавлено
                                                              Равно как и "шапочка" ^, чтобы она не значила отрицания.

                                                              Добавлено
                                                              shm, раз уж пошла такая пьянка ... запили работающий код питона на ideone.com, читаем не из файла, а из строки с переводами строк, возвратами каретки и всякими там табуляциями. Будет нагляднее.
                                                                Я вообще-то ищу как раз то, что не перечислено в скобках. Так что ^ там это именно отрицание.
                                                                Следом за ним идёт -, который в начале перечисления тоже не означает диапазона.
                                                                Да, ещё одну ошибку заметил - надо после закрывающей ] поставить плюсик, чтобы не по-символьно искать, а по словам.
                                                                  Аааа ... ту так да)

                                                                  Добавлено
                                                                  Все равно - кинь на ideone.com работающее. Просто интересно.
                                                                    Цитата JoeUser @
                                                                    shm, раз уж пошла такая пьянка ... запили работающий код питона на ideone.com, читаем не из файла, а из строки с переводами строк, возвратами каретки и всякими там табуляциями. Будет нагляднее.

                                                                    ???
                                                                      Цитата shm @
                                                                      ???
                                                                      amk подразумевался, думается. Вас, трёхбуквенных, крайне мало, посему разум вполне может склеить эти две точки. :blush:

                                                                      Можно поставить на автоудаление.
                                                                        Цитата shm @
                                                                        ???

                                                                        Ну тож же код, только для заданной строки, а не из файла
                                                                          Что-ж, смотрите

                                                                          Добавлено
                                                                          Можно поменять комментирование data, чтобы код файл читал
                                                                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                          0 пользователей:


                                                                          Рейтинг@Mail.ru
                                                                          [ Script execution time: 0,0896 ]   [ 17 queries used ]   [ Generated: 16.04.24, 08:31 GMT ]