1. C++ / Говнокод #9165

    +1001

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    bool IsDigit(char cKey, const char *cKeys) {
    	for (int i = 0; i < strlen(cKeys); i++)
    		if (cKeys[i] == cKey)
    			return true;
    	return false;
    }

    Запостил: FalseCoder, 18 Января 2012

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

    • и?
      Ответить
    • опять strlen в форе...
      стоп. а как соотносится название isDigit с проверкой наличия символа в строке
      Ответить
      • Есть ли цифра [в строке].
        Ответить
        • по названию, видя isDigit, я полагаю, что это будет проверка, является ли строка числом или конкретный символ числовой. а тут что?!
          Ответить
          • никто не утверждает, что имя выбрано правильно. Правильней has_digit/hasDigit.
            Ответить
            • вообще у меня первая мысль была о том, что cKey - это символ, который проверяется на вхождение в массив "цифр" cKeys - если найден, значит cKey - цифра
              думаю, в зависимости от содержимого в cKeys подошло бы (ckey >= '0' && ckey <= '9') в лучшем случае и binary_search в худшем
              Ответить
              • сишкопроблемы, для символа и байта - один универсальный тип
                Ответить
              • А ещё есть
                #include <ctype>
                int isdigit(int c);
                который обычно реализуется в виде таблички.
                Ответить
                • > в зависимости от содержимого в cKeys
                  > в зависимости от содержимого в cKeys
                  > в зависимости от содержимого в cKeys
                  только афтар знает что там
                  может сканкоды клавиш устройства
                  например 0x90, 0x93, 0x96, 0xA0, 0xA3, 0xA6 и т.д.
                  я всё это выше учел
                  Ответить
              • >и binary_search в худшем
                А в помойку его.
                std::unordered_map
                Ответить
                • Использовать std::unordered_map для небольших массивов выглядит существенным оверхедом.
                  Ответить
                  • Чего это? О(1) он и в Африке О(1).
                    Ответить
                    • Константа всё захавает, перевеся O()
                      Ответить
                      • Что константа захавает? hash_search точно лучше binary_search для данного случая.
                        Ответить
                        • твой хеш сёрч для ~10 элементов "цифр" затратами на вычисление хеша + поиска значения по этому хешу далеко не факт, что обгонит 1-4 простых сравнения бинарного поиска, а уж по памяти явно проиграет непрерывному массиву из ~10 значений

                          если бы ты намекнул о простом трюке - берем таблицу из 255 элементов bool и записываем в нее true туда, где элементы - "цифры", т.о. сводим определение "цифра"/"не цифра" к if (digits_table[passed_char]) - это бы еще имело право на жизнь
                          но не unordered_set, извини
                          Ответить
                          • >затратами на вычисление хеша
                            Убрать до естественного вычисления хеша, данные подходящие.

                            >а уж по памяти явно проиграет непрерывному массиву из ~10 значений
                            Согласен.

                            >если бы ты намекнул о простом трюке - берем таблицу из 255 элементов bool
                            vector<bool>? Имеет право на жизнь. Компактно относительно.
                            Ответить
                          • тащемта bitset например
                            Ответить
                        • Для маленького массива - нет, лучше без хешей. А ещё лучше brootforce_search.
                          Ответить
            • А, блин туплю. Имя правильное. Просто передавать явно строку символов, соответствующих цифрам - бредовая идея.
              Ответить
            • Can i haz digit?
              Ответить
    • Как java-программист всегда завидовал программистам на С++ из-за наличия вещей, подобных <algorithm>. Так почему же столь многие из них не знают о своём счастье?
      Ответить
      • очевидно же
        отдельный вид программистов - крестодельфины - развиваются в изолированной экосистеме, и вмешательство STL в их скромную цивилизацию может привести к трагедии
        поэтому ученые сегодня стараются только наблюдать, на будущее разрабатывая методики психокоррекции для возможной ассимиляции этого подвида среди обычных людей
        Ответить
        • > крестодельфины

          Это что за мутант?
          Ответить
          • пишут как будто на дельфи, но только их еще заставляют применять чужеродный синтаксис с фигурными скобками
            Ответить
        • > крестодельфины
          Мне почему-то представился дельфин (млекопитающие) с большим крестом на брюхе. Я один такой?
          Ответить
          • цэ плюс плюс быдлер же!
            Ответить
          • Сегодня Крещение, сегодня можно.
            Ответить
          • ...это были страшные чудовища, похожие на дельфинов с огромным крестообразным вырезом на брюхе... Говорят, что когда-то злой маг Страа'уструу'п решил заколдовать обычных дельфинов, мирных морских существ, чтобы набрать себе армию слуг, но вместо этого получил он страшных созданий, навеки повисших между жинзью и смертью...
            Ответить
          • На брюхе крест только у попов, обычно кресты на спинах.
            Ответить
      • >Как java-программист всегда завидовал программистам на С++ из-за наличия вещей, подобных <algorithm>.
        Говнецо то ещё...
        Ответить
        • Задумка универсальных алгоритмов (с гарантированной сложностью!) неплоха, но очень не хватает удобных адаптеров. Например, чтобы вместо такого:
          std::find(some_container.begin(), some_container.end(), some_value) != some_container.end()

          писать что-то вроде:
          some_container.contains(some_value)
          Ответить
          • На самом деле в java тоже можно сделать похожие штуки, но их полезность сильна ограничена из-за отсутствия быстрого mem_fun
            Ответить
          • такие операции и так есть в контейнерах, которые задуманы для оптимального поиска в них элементов - std::set::count/std::map::count
            делать такой метод в std::list - глупо, если программист так сильно хочет найти элемент в нем, значит его ничто не остановит сделать это в виде линейного std::find
            Ответить
            • Если поиск нужно провести один раз - гораздо быстрее осуществить его прямым перебором, нежели строить set/map.
              Ответить
    • Кстати, о strlen в условии for. Давно думаю, почему не ввели какой-нибудь копрофикатор модификатор, чтобы зафиксировать часть условия? Чтобы она не вычислялась на каждой итерации? Было бы удобнее оптимизировать..
      Ответить
      • Проще эту часть условия положить в переменную.
        Ответить
        • В рамках существующего инструментария так делать нужно. Но я бы не сказал, что так удобно.. Это ж лишняя строчка будет :)
          Ответить
    • Даже не знаю, как оценивать этот код. Вот если бы автор написал для чего он предназначается, тогда другое дело.
      Ответить
    • показать все, что скрытоМногие из присутствующих здесь приняли этот код за говнокод. На самом деле это не так. Я вас специально решил подловить на названии функции. На самом деле её можно было назвать InArray или как кому будет угодно. Это универсальный код. На вход поступает сам проверяемый символ, а также массив char с нулевым символом (отсюда и strlen), по которому идёт цикл. Всё зависит от решаемой задачи. Например, я хочу добиться вывода только чисел, минусов, запятых и к примеру нижнего подчёркивания. Вот такая вот реализация замечательно подойдёт. Главная, что ф-я универсальна.
      Ответить
      • int n = strlen(s); for(int i = 0; i < n; i ++)
        ГК именно за это.
        Ответить
        • А вот с этим я действительно налажал. Видел, знал, но не учёл, что функция выполняется каждый раз в цикле. Ну, а в другом я совершенно убеждён, что вариант вполне адекватный :)
          Ответить
          • > вариант вполне адекватный
            для ANSI C c учётом strlen может быть, и то там можно лучше написать. А в плюсах это вообще унылый не особо реюзабельный велосипед.
            Ответить
            • Можно увидеть вашу C++ реализацию этой функции?
              Ответить
              • В с++ вообще ничего писать не надо, для этого есть <algorithm>, и boost, как уже было замечено выше. Если уж оставаться в рамках сишки, то тут возможны варианты: реализация зависит от желаемых характеристик и уровня общности. Наиболее общей и наименее эффективной реализацией была бы следующая:
                int is_member_of(void *elem,
                                 void *it,
                                 void* (*next) (void *),
                                 int (*eq) (void*, void*))
                {
                  while (NULL != it) {
                    if (eq(it, elem)) return 1;
                    it = next(it);
                  }
                  return 0; 
                }

                Пример использования со строками:
                http://codepad.org/WqTdlt2N
                Разумеется, такая реализация имеет ряд ограничений и может пригодится разве что внутри какой-нибудь библиотеки для работы с множеством различных структур-последовательностей. Алгоритм линейного поиска в массиве известного типа вы и сами можете написать. Хотя я бы использовал бинарный поиск и таблицы везде где это возможно.
                Ответить
                • да даже в сишке есть strchr
                  а то насоветуешь щяс ему
                  Ответить
                  • да я же поглумиться
                    Ответить
                    • > поглумиться
                      над тарасом, реализовав рантайм-метапрограммирование даже в сишке с её сишкопроблемами
                      Ответить
                      • Глумись. Только в компил-тайм ты этот код не перенесёшь даже в крестах, придётся тебе дублировать всё.
                        Ответить
                        • boost::mpl вам в помощь. Много контейнеров с итераторами на этапе компиляции.
                          Ответить
                          • Пилять, я не говорю, что нет контейнеров этапа компиляции. Я говорю, что в крестах нельзя задать шаблон от не-констант. И либо у тебя void, либо у тебя template, а и то, и другое одним кодом кресты не могут.
                            Ответить
      • классно ты нас всех наебал
        написал велосипед, где strlen каждую итерацию
        кроме того чрезвычайно универсальный велосипед работает только с char, и конечно будет искать только по null-terminated массиву
        покури boost::is_any_of() и другие вещи из algorithm - для базового поиска

        тем, кому нужна действительно скорость для определения "число ли это", "пробел ли это", "пригоден ли символ для имени" - пользуются таблицами из 256 элементов, например смотри lookup-tables описанные в хвосте этого заголовка (честноспижженный rapidxml в недрах буста):
        http://www.boost.org/doc/libs/1_48_0/boost/property_tree/detail/rapidxml.hpp
        Ответить
        • Функция писалась для консоли, чтобы принимать символы, которые вводились и определять входят ли они в те самые не ограничиваемые символы.
          Для int как и было уже сказано есть int isdigit(int c)
          Универсальность определялось той динамичностью, при которой добавив в массив cKeys ещё любые символы, можно было использовать ф-ю для разного вида ограничений ввода символов.
          Ну, если конечно массив небольшой, то этот вариант вполне подойдёт.
          Ответить
      • Ursus, ты?
        Ответить
    • Последнее время я только и вижу сообщения вида: "Это проблема крестов" или "Для С++ это нельзя использовать". У вас мода новая что ли на такого рода фразы? Я читал много сообщений и статей по поводу различия С и С++, так многие отмечают, что их совсем немного. А тут куда голову не сунь, везде "Это проблема крестов"
      Ответить
      • Кресты виноваты во всех бедах программистов.
        Это модно.
        Ответить
      • это проблема крестолюбов
        Ответить
      • > их совсем немного
        I LOL'D
        Ответить
        • Ну да, таки эпично написал. Но факт остаётся фактом. С++ хоть и стал объектно-ориентированным языком, огромных отличий кроме нововведений я не вижу. К тому же всё сделано для лучшей разработки приложений.
          Нововведениями Си++ в сравнении с Си являются:
          * поддержка объектно-ориентированного программирования;
          * поддержка обобщённого программирования через шаблоны;
          * дополнительные типы данных;
          * исключения;
          * пространства имён;
          * встраиваемые функции;
          * перегрузка операторов;
          * перегрузка имён функций;
          * ссылки и операторы управления свободно распределяемой памятью;
          * дополнения к стандартной библиотеке.
          Ответить
      • Звучит так же мерзко как паста из мерзкого бложика
        Ответить
      • КРЕСТОПРОБЛЕМЫ
        Ответить
    • показать все, что скрытоЯ так подумал и понял, что мне абсолютно всё равно какими ВЫЕБОНОСИШНОКРЕСТОВЫМИ способами вы решаете задачи. Я протестировал при помощи AQTime работу моей функции поиска символа в строке и поиск символа всё по той же строке функции is_member_of roman-kashitsyn.

      Результат:
      Routine Name Time Time with Children Shared Time Hit Count
      IsDigit 2,77621043270976E-7 2,77621043270976E-7 100 1

      Routine Name Time Time with Children Shared Time Hit Count
      is_member_of 8,54411333532516E-7 1,53142582714098E-6 55,7918848167539 1
      Ответить
      • Тебе все же сказали, что нужно использовать стандартную библиотеку. В подмножестве С есть strchr, эквивалентный по семантике коду в топике. В stl/boost вообще решения таких задач на все случаи жизни.

        Нашёл что сравнивать...
        > Наиболее общей и наименее эффективной реализацией
        Я же сказал, что is_member_of медленно работать будет. Это функция высшего порядка, которая совершает ещё два вызова по указателю на каждой итерации, какая уж тут скорость. Зато её можно использовать для обхода списков, деревьев, графов, etc. И даже она побьёт по производительности код в топике на достаточно больших строках, потому что у кода в топике квадратичная сложность.
        Ответить
        • ОН НАС АПЯТЬ ПРОВИРЯЕТ!!!1
          Ответить
        • А ещё посложнее библиотеки не найдётся? Даже годные программисты не хотят соваться в эту библиотеку, ибо никому не нужна зависимость проекта от лишний библиотеки + в некоторых случаях падение производительности (чаще лучше написать свой велосипед, но производительный). Использование boost оправдано при более серьёзных проектах, а не программы на 200 строчек. А мне это тем более не надо. Я не крестофил, чтобы трястись над каждой строчкой кода, которая не похожа на реализацию из С++. Рабочий и быстродейственный вариант - это то, что мне нужно в проектах. Правда со strlen налажал, но увы, я С/С++ начал изучать 5 месяцев назад.
          Ответить
          • ну так из твоего кода было неясно, это очередная говнолаба, кусок кода из рабочего проекта в нормальной среде (где есть и STL и нет религиозных запретов), или кусок кода из рабочего проекта в дерьмосреде (не будем поминать всуе)
            три случая разные, и если в первом от тебя требуется написать именно велосипед, потому что ты учишься, а в третьем тебе приходится писать именно велосипед, потому что жизнь говно и не повезло с профессией, то во втором случае игнорирование хотя бы STL уже ничего хорошего не сулит
            > годные программисты не хотят соваться в эту библиотеку
            этому есть много объяснений - главное, потому что страшно
            потому что они не пишут новое, а дорабатывают старое, а когда всё работает, лучше не трогать
            и еще пример из жизни - разговаривал тут с одними, разрабатывают ERP лет десяток-другой, спросил про буст - говорят не рискуют, сами не пробовали, слышали неоднозначные мнения. зато с нетерпением ждут поддержки C++11 их компилятором - на вопрос как так получилось, что немалая часть boost доказала свою востребованность настолько, что её скопипастили в новый стандарт, который вы так ждёте, но вы всё еще кипятите - пожали плечами
            буст многогранен, если ты откроешь список, то там дохера отдельных библиотек - не надо разбираться во всех, а в тех, которые ты будешь использовать, буст обычно инлайновый, поэтому в твой код попадет только то, что ты использовал, буст кроссплатформенен, и кому то (мне) это крайне важно в реальных рабочих проектах
            ну и факт того, что не приходится на каждый чих писать свой велосипед - это касается не только этого говнокода, но и всех, которые ты постил здесь, оно знаешь ли, не только очень экономит время разработки, но и сильно снижает вероятность создания ошибок, которые тебе потом надо ловить
            Ответить
            • Ну, предыдущие говнокоды у меня в проектах не используются, а этот, но уже исправленный вариант всё-таки останется в проекте до лучших времен.
              Ответить
              • в случае твоего кода ничего лучше char lookup[256] по одновременно быстродействию и гибкости быть не может - ты же собрался ввод с клавиатуры анализировать?
                struct lookup_table {
                    char table_[256];
                    lookup_table(char const * allowed) {
                        memset(lookup_table, 0, sizeof(lookup_table));
                        for (; *allowed; ++allowed)
                            table_[*allowed] = 1;
                    }
                    bool is_on(char c) { return table_[c] == 1; }
                };
                // usage
                lookup_table allowed1("0123456789-,_");
                allowed1.is_on(key);

                тогда сложность поиска будет меньше любого strchr
                Ответить
    • http://www.cplusplus.com/reference/clibrary/cctype/isdigit/
      Ответить
    • FalseCoder, пойдем на велосипедах покатаемся!?
      Ответить

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