сравнение строк без учета регистра
От: Аноним  
Дата: 23.07.07 12:45
Оценка:
Как выполнить сабж в STL?
Re: сравнение строк без учета регистра
От: Peregrin  
Дата: 23.07.07 13:25
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как выполнить сабж в STL?


Сделать обоим строкам tolower/toupper и сравнить.
Re[2]: сравнение строк без учета регистра
От: Sni4ok  
Дата: 23.07.07 14:42
Оценка:
Здравствуйте, Peregrin, Вы писали:

P>Сделать обоим строкам tolower/toupper и сравнить.


плохо, ибо лишние стринги временные будут
Re: сравнение строк без учета регистра
От: Sni4ok  
Дата: 23.07.07 14:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как выполнить сабж в STL?


вот так например

template<typename stringT>
bool equal(const stringT& str1, const stringT& str2, const std::locale& loc = std::locale()){
    typedef stringT::value_type charT;
    return (str1.size() == str2.size() &&
        str1.begin() == std::search(str1.begin(), str1.end(), str2.begin(), str2.end(),
            boost::bind(&std::tolower<charT>,_1,loc) == boost::bind(&std::tolower<charT>,_2,loc)));
}
Re[2]: сравнение строк без учета регистра
От: Аноним  
Дата: 23.07.07 17:03
Оценка:
Здравствуйте, Peregrin, Вы писали:

А>>Как выполнить сабж в STL?


P>Сделать обоим строкам tolower/toupper и сравнить.


Да я так и хотел, но не нашел в std::string ничего похожего на tolower/toupper
Re[2]: сравнение строк без учета регистра
От: Аноним  
Дата: 23.07.07 17:08
Оценка:
Здравствуйте, Sni4ok, Вы писали:

А>>Как выполнить сабж в STL?


S>вот так например


S>
S>template<typename stringT>
S>bool equal(const stringT& str1, const stringT& str2, const std::locale& loc = std::locale()){
S>    typedef stringT::value_type charT;
S>    return (str1.size() == str2.size() &&
S>        str1.begin() == std::search(str1.begin(), str1.end(), str2.begin(), str2.end(),
S>            boost::bind(&std::tolower<charT>,_1,loc) == boost::bind(&std::tolower<charT>,_2,loc)));
S>}
S>


Ээ-э... А можно пояснить? И при чем тут буст? Неужели в STL нет стандартных средств для такой элементарной операции?
Re[3]: сравнение строк без учета регистра
От: Vain Россия google.ru
Дата: 23.07.07 17:26
Оценка: 1 (1) +1
Здравствуйте, Аноним, Вы писали:

А>Ээ-э... А можно пояснить? И при чем тут буст? Неужели в STL нет стандартных средств для такой элементарной операции?

А зачем тебе именно в STL нужно?
int _stricmp(
   const char *string1,
   const char *string2 
);
int _wcsicmp(
   const wchar_t *string1,
   const wchar_t *string2 
);
int _mbsicmp(
   const unsigned char *string1,
   const unsigned char *string2 
);
int _stricmp_l(
   const char *string1,
   const char *string2,
   _locale_t locale
);
int _wcsicmp_l(
   const wchar_t *string1,
   const wchar_t *string2,
   _locale_t locale
);
int _mbsicmp_l(
   const unsigned char *string1,
   const unsigned char *string2,
   _locale_t locale
);
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[3]: сравнение строк без учета регистра
От: Sni4ok  
Дата: 23.07.07 18:25
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Ээ-э... А можно пояснить? И при чем тут буст? Неужели в STL нет стандартных средств для такой элементарной операции?


ну разве не понятно?
в привидённом коде делается std::search по бинарному предикату std::tolower от твоих символов входных строк, так что никаких временных строк не создаётся, а поэтому- это более бысрый и удачный вариант, чем преобразование обоих строк к одному регистру и последующему их сравнению.
Re: сравнение строк без учета регистра
От: Alex Dav Россия  
Дата: 24.07.07 05:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как выполнить сабж в STL?


В STL нет (или пока нет) встроенного сравнения без учета регистра, если необходимо выполнить только одно сравнение см. выше подсказки, а если идет много работы со строками и надо без учета, то надо создать специльный тип строки со своим кодом трактовки символа см. basic_string<>
Re: сравнение строк без учета регистра
От: alzt  
Дата: 24.07.07 07:35
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как выполнить сабж в STL?


Написать функтор, который будет сравнивать без учёта регистра (с использованием tolower,toupper) и использовать его, когда нужно сравнить строки.
Re[2]: сравнение строк без учета регистра
От: Аноним  
Дата: 24.07.07 11:07
Оценка:
Здравствуйте, Alex Dav, Вы писали:

А>>Как выполнить сабж в STL?


AD>В STL нет (или пока нет) встроенного сравнения без учета регистра, если необходимо выполнить только одно сравнение см. выше подсказки, а если идет много работы со строками и надо без учета, то надо создать специльный тип строки со своим кодом трактовки символа см. basic_string<>


А подробнее можно? Что это значит, заменить char на что-то другое? И чем это поможет в сравнении?
Re[2]: сравнение строк без учета регистра
От: Аноним  
Дата: 24.07.07 11:18
Оценка:
Здравствуйте, alzt, Вы писали:

А>>Как выполнить сабж в STL?


A>Написать функтор, который будет сравнивать без учёта регистра (с использованием tolower,toupper) и использовать его, когда нужно сравнить строки.


Такие "функторы" уже есть — stricmp — но не очень хочется чтобы программа была заполнена такими "элегантными" строками вида
   if(stricmp(FirstStr.c_str(), SecondStr.c_str()) == 0)

Хочется просто использовать знак сравнения, в крайнем случае функцию возвращающую bool. Исходя их духа ООП все (или большинство) методов std::string должны быть виртуальными чтобы можно было легко переопределить их для своих целей — но почему-то Страуструп, пропагандируя такой подход в теории, в STL решил от него отказаться.

И вообще — я честно пытаюсь заставить себя писать на C++, но пока что ваши ответы не дают мне повода для оптимизма.
Re[3]: сравнение строк без учета регистра
От: Аноним  
Дата: 24.07.07 11:33
Оценка:
Здравствуйте, Аноним, Вы писали:

А>И вообще — я честно пытаюсь заставить себя писать на C++, но пока что ваши ответы не дают мне повода для оптимизма.


Пример из того же Страуструпа:

    bool compare_nocase(const string &str1, const string &str2)
    {
        string::const_iterator i1 = str1.begin(), i2 = str2.begin();
        std::locale loc = std::locale::classic();

        while((i1 != str1.end()) && (i2 != str2.end()))
        {
            if(std::toupper(*i1, loc) != std::toupper(*i2, loc))
            {
                return false;
            }

            ++i1, ++i2;
        }

        return (str1.length() == str2.length());
    }
Re[3]: сравнение строк без учета регистра
От: Alex Dav Россия  
Дата: 24.07.07 12:12
Оценка:
Здравствуйте, Аноним, Вы писали:



А>А подробнее можно? Что это значит, заменить char на что-то другое? И чем это поможет в сравнении?


есть базовый тип

template <
   class CharType,
   class Traits=char_traits<CharType>, 
   class Allocator=allocator<CharType> 
>
class basic_string


вот второй параметр это и есть трактовка символа, т.е. как я понимаю, это твое представление символа, код для примера

#include <string>
#include <iostream>
#include <cctype>
using namespace std;
struct onlyuppercase_tract : public std::char_traits<char>
{
 //дальше замещаем нужные функции типа
static bool eq(const char_type& _Ch1, const char_type& _Ch2)
{
    std::cout << "eq = ";
  return std::toupper(_Ch1) == std::toupper(_Ch2);
};
static bool lt(const char_type& _Ch1, const char_type& _Ch2)
{
    std::cout << "lt = ";
  return std::toupper(_Ch1) < std::toupper(_Ch2);
};

static int compare(const char_type* _Str1, const char_type* _Str2, size_t _Num)
{
    for(int i = 0; i < _Num; ++i)
    {        if(!eq(_Str1[i],_Str2[i]))
        {
            return lt(_Str1[i],_Str2[i])?-1:1;
        };
    };
    return 0;
};
//и т.д.

};

typedef std::basic_string<char,onlyuppercase_tract> mystring;

int _tmain(int argc, _TCHAR* argv[])
{
    mystring str1("Hi");
    mystring str2("hi");
    std::cout << std::boolalpha;
    std::cout << (str1 == str2) << endl;
    
    return 0;
}
Re[4]: сравнение строк без учета регистра
От: Аноним  
Дата: 24.07.07 20:12
Оценка:
Здравствуйте, Alex Dav, Вы писали:


AD>вот второй параметр это и есть трактовка символа, т.е. как я понимаю, это твое представление символа, код для примера


AD>
AD>#include <string>
AD>#include <iostream>
AD>#include <cctype>
AD>using namespace std;
AD>struct onlyuppercase_tract : public std::char_traits<char>
AD>{
AD> //дальше замещаем нужные функции типа
ADAD>//и т.д.

AD>};

AD>


Там походу много чего еще, стремабельность добавить. Потом эта новая строка никак не совместима с std::string. И замена алокатора к таком уже эффекту приведет. Ставнимость с учетом регистра потеряна. Кстати ноль всеравно стоит вконце std::string, c_str не дорогая операция
Re[5]: сравнение строк без учета регистра
От: Alex Dav Россия  
Дата: 25.07.07 05:10
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Там походу много чего еще, стремабельность добавить. Потом эта новая строка никак не совместима с std::string. И замена алокатора к таком уже эффекту приведет. Ставнимость с учетом регистра потеряна. Кстати ноль всеравно стоит вконце std::string, c_str не дорогая операция


Я не говорил что это лучший выход — все зависит от ваших потребностей, но если вам нужен строковой тип все операции с котором должны выполняться таким образом, то это самое оно. А что значит не совместим добавить самому оператор преобразования к string и будет.
Re[2]: сравнение строк без учета регистра
От: Аноним  
Дата: 26.07.07 15:32
Оценка:
Здравствуйте, Sni4ok, Вы писали:

S>вот так например


S>
S>template<typename stringT>
S>bool equal(const stringT& str1, const stringT& str2, const std::locale& loc = std::locale()){
S>    typedef stringT::value_type charT;
S>    return (str1.size() == str2.size() &&
S>        str1.begin() == std::search(str1.begin(), str1.end(), str2.begin(), str2.end(),
S>            boost::bind(&std::tolower<charT>,_1,loc) == boost::bind(&std::tolower<charT>,_2,loc)));
S>}
S>


В С++ не силен но все же хотел спросить — почему нету проверки на то не ссылаются ли стринги на один и тот же обьект?
Ну и просто такой вопрос — а не выгодней было-бы сделать метод который бы не просто сравнивал но еще и говорил бы как обьект больше?
Re: сравнение строк без учета регистра
От: tilarids Украина tilarids.blogspot.com
Дата: 04.10.07 11:41
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Как выполнить сабж в STL?


Скотт Мейерс: Эффективное использование STL. Совет #35. Еще вот хоть убей, не помню в какой из musthave книг описывалось создание класса на основе basic_string, но со сравнением строк без учета регистра. А пересматривать все лень

P.S. http://proklondike.com/contentview.php?content=16 — Мейерса можно скачать здесь. Но лучше купить.
<вырезано, дабы сохранить место на сервере>
Re[3]: сравнение строк без учета регистра
От: tilarids Украина tilarids.blogspot.com
Дата: 04.10.07 11:51
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Хочется просто использовать знак сравнения, в крайнем случае функцию возвращающую bool. Исходя их духа ООП все (или большинство) методов std::string должны быть виртуальными чтобы можно было легко переопределить их для своих целей — но почему-то Страуструп, пропагандируя такой подход в теории, в STL решил от него отказаться.


Дух ООП не пропагандирует наследование Наследование подразумевает очень сильную связанность. Поэтому чаще всего лучше от него отказаться. Но это не мне нужно рассказывать — об этом нужно читать и понимать.

P.S. Вот что значит — давно не включать RSDN@Home. Теперь я не знаю, ответили ли на это сообщение, или еще нет. И пока все не докачается, не узнаю
<вырезано, дабы сохранить место на сервере>
Re[2]: сравнение строк без учета регистра
От: Centaur Россия  
Дата: 04.10.07 12:35
Оценка: 1 (1)
Здравствуйте, Peregrin, Вы писали:

А>>Как выполнить сабж в STL?


Смотря на что сравнить — на равенство или на порядок.

P>Сделать обоим строкам tolower/toupper и сравнить.


Не будет работать.

Простейший пример. В французском языке буквы с диакритикой могут при переводе в uppercase её терять. Соответственно, буквы "Latin small letter A" и "Latin small letter A with acute" после toupper станут эквивалентными, в то время как исходно между ними был порядок (буква без диакритики стоит перед буквой с диакритикой).

Или, скажем, в японском языке слово может быть написано одной из двух слоговых азбук — хираганой или катаканой. Катакана используется для написания заимствованных слов, а также для выделения. Соответственно, регистронезависимое сравнение должно считать хирагану и катакану эквивалентными. Однако и tolower, и toupper оставят хирагану хираганой, а катакану катаканой.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.