Кресты / Говнокод #26603 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
CStringUtf8::iterator& CStringUtf8::iterator::operator++() 
{ 
    m_ptr += CCharUtf8Ref::s_bytesForUTF8Sequence[*m_ptr]; 
    return *this;
}

CStringUtf8 CStringUtf8::subString( size_t startChar, size_t count ) const
{
    iterator start = this->begin();
    while( start!=this->end() && startChar>0 )
    {
        start++;
        startChar--;
    }

    iterator afterLast = start;
    while( afterLast!=this->end() && count!=0 )
    {
        afterLast++;
        count--;
    }
    return CStringUtf8( start.c_ptr(), afterLast.c_ptr() );
}

CStringUtf8::iterator CStringUtf8::findSubString( CStringUtf8 const& sample, CStringUtf8::iterator startFrom ) const
{
    CStringUtf8::iterator pos = startFrom;
    CStringUtf8::iterator foundPos = pos;
    CStringUtf8::iterator samplePos = sample.begin();

    for( ;; )
    {
        if( samplePos==sample.end() )
            return foundPos;

        if( pos==this->end() )
            return this->end();

        if( *samplePos == *pos )
        {
            if( samplePos==sample.begin() )
                foundPos = pos;
            samplePos++;
            pos++;
        }
        else
        {
            if( samplePos==sample.begin() )
                pos++;
            samplePos = sample.begin();
        }
    }
}

std::vector<CStringUtf8> CStringUtf8::componentsSeparatedByString( CStringUtf8 const& separator ) const
{
    std::vector<CStringUtf8> comps;

    size_t sepLen = std::distance( separator.begin(), separator.end() );
    size_t startPos = 0;
    CStringUtf8::iterator itStart = begin();

    if( sepLen > 0 )
    {
        CStringUtf8::iterator itEnd;
        while( ( itEnd = findSubString( separator, itStart ) ) != end() )
        {
            size_t cnt = std::distance( itStart, itEnd );
            CStringUtf8 str = subString( startPos, cnt );
            comps.push_back( str );

            itStart = itEnd;
            std::advance( itStart, sepLen );

            startPos += cnt + sepLen;
        }
    }

    size_t cnt = std::distance( itStart, end() );
    if( cnt > 0 )
    {
        CStringUtf8 str = subString( startPos, cnt );
        comps.push_back( str );
    }

    return comps;
}

Привычный для всех плюсовиков велосипед по работе со строкой (походу свой в каждом проекте).
Более 10 лет не замечали тормоза в componentsSeparatedByString, который 100 Кб текст разбирал на строки за 5-10 сек (!!!).

Запостил: jojaxon jojaxon, (Updated )

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

  • > тормоза

    Да пофиг на тормоза, функция findSubString() вообще не рабочая. Попробуй найти "aab" в "aaab", к примеру.
    Ответить
      • Бля. Видимо не очень-то и нужен был поиск. Конец строки ищет и ладно.
        Тесты - это больная мозоль. Их мало, но они в тельняшках.
        Ответить
    • Протрнйсил в голове, вроде норм.

      Не могла же она просуществовать 10 лет некорректная?
      Ответить
  • Не понимаю, в языке же есть поддержка ООП, почему её не используют? Почему, например, получение размера строки нельзя прокешировать при изменении строки и затем брать из отдельного метода класса CStringUtf8, вроде length()?

    В чём логика передачи пустой строки как аргумента метода componentsSeparatedByString()? Куда разумнее здесь было бы бросить assert, нет? Если уж смысл в том, чтобы вернуть массив, содержащий единственный элемент, равный исходной строке (хотя, как мне кажется, логичнее при пустом аргументе было бы разбить всю строку по символам и вернуть массив этих символов), почему нельзя сделать отдельную проверку в самом начале с последующим простым возвратом из метода, вместо того чтобы считать размер строки и брать подстроку равную исходной строке?

    subString() делает что-то уж совсем сложное, почему просто не сделать clamp() по 0, размеру строки и стартовому индексу и передать первым параметром со сдвигом по внутреннему указателю, а затем, аналогично, clamp() по 0, размеру строки и размеру подстроки, передав полученный результат со сдвигом по указателю вторым параметром в конструктор класса? Так нельзя?

    Про findSubString() уже всё сказали выше. Опять же, я бы тоже не позволял просто так в метод передавать пустой аргумент в качестве строки поиска или делал бы такую проверку отдельно в самом начале и возвращал 0.

    Я не особый специалист по плюсам, возможно, где-то херню написал.
    Ответить
    • Не понимаю, в языке же есть поддержка ООП, почему её не используют?
      Не понимаю, в языке же есть поддержка процедурного программирования, почему её не используют?
      Не понимаю, в языке же есть поддержка ФП, почему её не используют?
      Не понимаю, в языке же есть поддержка АОП, почему её не используют?
      Не понимаю, в языке же есть поддержка Си, почему её не используют?
      Не понимаю, в языке же есть поддержка макросов, почему её не используют?
      Не понимаю, в языке же есть поддержка шаблонов, почему её не используют?
      Не понимаю, в языке же есть поддержка комплексных чисел, почему её не используют?

      Как же без всего этого со строками то раьотать?
      Ответить
      • А самое главное - почему тут не используется функция Бесселя? Её что, просто так в стандарт добавляли?
        Ответить
        • в стандартную либу добавили Бесселя, а mysql_real_escape не добавили. Почему?
          Ответить
            • мы уже обсуждали, да) причем он там так красиво сделан, что его можно поверх стрима навернуть вроде
              Ответить
            • А функций для работы со строками, типа упперкасе нету.

              Какой C++ )))
              Ответить
              • А зачем нужны функции для работы со строками, если строк нет?
                Ответить
                    • да там все алгоритмы с какой-то херней работают. Проще цикл написать, чем у кого-то занимать чем алгоритмы заюзать. Поневоле скриптушатникам завидовать начинаешь.
                      Ответить
                      • У скриптушатников тоже не у всех всё гладко. В том же js куда не сунься, везде свой dosomething.js, а стандартная либа настолько нищая, что поневоле понимаешь, почему люди всякие реакты и ноды так любят.
                        Ответить
      • Очень смешно )

        Ну вы тогда или крестик снимите, или штаны наденьте ) Или используйте ООП, или нет. А то набрали классов, а что с ними делать — хз )
        Ответить
    • Метода length() нет за ненадобностью. Что он должен возвращать? Кол-во кодепоинтов? Где это может потребоваться? Есть lengthInBytes(), который считается как разность указателей.

      Пустые строки и впрямь никто не рассматривал. Возможно в тестах бы и проверили, но тестов нет. Любой, кто будет передавать пустые строки - ССЗБ.

      subString() отсчитывает кодепоинты и выдергивает подстроку, передавая указатели в конструктор. Считаю, что передавать позицию в кодепоинтах также бессмысленно как и считать в них длину строки.
      clamp в 2005 не было. Описанный алгоритм не понял, почитаю позже.
      Кстати проблема с тормозами решилась добавлением версии subString() с итераторами.
      Ответить
      • > Пустые строки и впрямь никто не рассматривал. Возможно в тестах бы и проверили, но тестов нет. Любой, кто будет передавать пустые строки - ССЗБ.

        Как же вы можете доверять работе написанного кода, если у вас все предусловия прописаны неявно и никак не контролируются? Вы же не будете рассказывать каждому новому программисту о том, какая специфика работы каждого из написанных методов? ) Или у вас подробная документация есть? Но даже если так, документацию к классам читают обычно, когда что-то не работает, по-хорошему, интерфейс должен работать предсказуемым образом )
        Да, вряд ли кто-то явно будет передаст указатели друг на друга в качестве параметров, но ведь любая ошибка в связанном коде — и они могут там оказаться.

        Я понимаю, что это не ваш код, но и защищать его по принципу «это не код небезопасный, а программист глупый» тоже не очень правильно )

        > subString() отсчитывает кодепоинты и выдергивает подстроку, передавая указатели в конструктор. Считаю, что передавать позицию в кодепоинтах также бессмысленно как и считать в них длину строки.

        Я понял, ошибся, перепутал размеры сдвига у итератора с переданным размером строки.

        > clamp в 2005 не было.
        Он реализуется в одну-две строки ) Но не суть.
        Ответить
  • В плюсах-то уже можно пользоваться std::string для utf-8? Или надо С++26 ждать?
    Ответить

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

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8