Re: Удаление лишних пробелов в строке
От: LaFlour Австралия blog: http://spaces.live.com/laflour
Дата: 19.08.03 06:54
Оценка: 3 (1)
Здравствуйте, bip29, Вы писали:

B> Народ не подскажет ли кто каким образом из строки убрать лишние пробелы и управляющие символы (\n,\r и др.). Мысль коечно есть но не хотелося б посимвольно читать строку. Может есть другие варианты. Хотелося б увидеть варианты на С или С++(не VCL,MFS b др).

B>Заранее благодарен.
STL пойдет?!

                // Trim begin/end spaces
                if(tempStr.find_first_of(' ')==0)
                    tempStr.replace(0, tempStr.find_first_not_of(' '), "");
                if (!tempStr.empty() && (tempStr.find_last_of(' ')+1)==tempStr.size())
                    tempStr.replace(tempStr.find_last_not_of(' '), std::string::npos, "");
LaFlour слушает "Metallica — No Leaf Clover"
Re[5]: Удаление лишних пробелов в строке
От: AI Россия  
Дата: 13.06.05 18:33
Оценка: 2 (1)
Здравствуйте, gok, Вы писали:

gok>Здравствуйте, Анатолий Широков, Вы писали:


gok>Нее, не все, один должен остаться:

gok>
gok>«Саша    +     Маша     =» ->  «Саша + Маша =»
gok>


gok>Пользую CString:

gok>
gok>while ( currentString.Replace("  ", " ") > 0 ){}
gok>

gok>Mожет что за один проход есть?

имхо тут в любом случае в независимости от того как ты обершёь эту фичу в красивую обёртку внутри алгоритм всё равно будет работаь либо через индекс массива либо через указатель инкрементируя его. Не стои затрат по времени так как кроме вшенести ты ничего не выйграешь
Re: Удаление лишних пробелов в строке
От: srez Россия  
Дата: 14.06.05 13:28
Оценка: 2 (1)
B> Народ не подскажет ли кто каким образом из строки убрать лишние пробелы и управляющие символы (\n,\r и др.). Мысль коечно есть но не хотелося б посимвольно читать строку. Может есть другие варианты. Хотелося б увидеть варианты на С или С++(не VCL,MFS b др).

Есть такой вариант:
#include <functional>
#include <algorithm>
#include <locale>

template <typename CharType>
struct compress_spaces_comparator
    : std::binary_function<CharType,CharType,bool> {

    bool operator()(const CharType& a, const CharType& b) const
    {
        return std::isspace(a) && std::isspace(b);
    }

};

template <typename StringType>
void compress_spaces(StringType& str)
{
    typename StringType::iterator end = str.end();
    compress_spaces_comparator<typename StringType::value_type> comparator;
    str.erase(std::unique(str.begin(), end, comparator), end);
}

Функция compress_spaces, применённая к строке, оставляет по одному символу класса space из каждой подпоследовательности таких символов.

Использование:
std::string test = ",    Саша    +   Маша         =";
compress_spaces(test);
Re[3]: Удаление лишних пробелов в строке
От: Анатолий Широков СССР  
Дата: 14.06.05 21:15
Оценка: 2 (1)
Просто у автора не совсем дописан функтор. Попробуй:

template <typename CharType>
struct compress_spaces_comparator
    : std::binary_function<CharType,CharType,bool> {
    std::locale loc;
    compress_spaces_comparator(std::locale const &loc = std::locale()) : loc(loc) {}
    bool operator()(const CharType& a, const CharType& b) const
    {
        return std::isspace(a, loc) && std::isspace(b, loc);
    }
};
Удаление лишних пробелов в строке
От: bip29  
Дата: 19.08.03 06:42
Оценка:
Народ не подскажет ли кто каким образом из строки убрать лишние пробелы и управляющие символы (\n,\r и др.). Мысль коечно есть но не хотелося б посимвольно читать строку. Может есть другие варианты. Хотелося б увидеть варианты на С или С++(не VCL,MFS b др).
Заранее благодарен.
Re: Удаление лишних пробелов в строке
От: Анатолий Широков СССР  
Дата: 19.08.03 07:08
Оценка:
http://www.rsdn.ru/Forum/Message.aspx?mid=274119&amp;all=1
Автор: LaFlour
Дата: 22.05.03
Re[2]: Удаление лишних пробелов в строке
От: gok Россия  
Дата: 11.06.05 00:20
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

А если пробелы в середине?
gok
Re[3]: Удаление лишних пробелов в строке
От: Анатолий Широков СССР  
Дата: 11.06.05 08:10
Оценка:
Здравствуйте, gok, Вы писали:

gok>Здравствуйте, Анатолий Широков, Вы писали:


gok>А если пробелы в середине?


Если хочется убрать все пробелы, то

std::string str(" 1 2 ");
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
Re: Удаление лишних пробелов в строке
От: Юнусов Булат Россия  
Дата: 12.06.05 17:02
Оценка:
Здравствуйте, bip29, Вы писали:

http://www.rsdn.ru/Forum/Message.aspx?mid=220504#220504
Автор: Юнусов Булат
Дата: 21.03.03
Re: Удаление лишних пробелов в строке
От: Valodzka Беларусь  
Дата: 12.06.05 17:51
Оценка:
Здравствуйте, bip29, Вы писали:

B> Народ не подскажет ли кто каким образом из строки убрать лишние пробелы и управляющие символы (\n,\r и др.). Мысль коечно есть но не хотелося б посимвольно читать строку. Может есть другие варианты. Хотелося б увидеть варианты на С или С++(не VCL,MFS b др).

B>Заранее благодарен.
string s;
copy(istream_iterator(cin), istream_iterator(), back_inserter(s))

по умолчанию пропустит все пробельные символы
Не перебивайте меня, когда я вас перебиваю
Re[4]: Удаление лишних пробелов в строке
От: gok Россия  
Дата: 13.06.05 18:22
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

Нее, не все, один должен остаться:
«Саша    +     Маша     =» ->  «Саша + Маша =»


Пользую CString:
while ( currentString.Replace("  ", " ") > 0 ){}

Mожет что за один проход есть?
gok
Re[5]: Удаление лишних пробелов в строке
От: Pavel Chikulaev Россия  
Дата: 13.06.05 18:48
Оценка:
Здравствуйте, gok, Вы писали:

gok>Mожет что за один проход есть?


Изврат правда

void eat_some_whitespaces (string & s)
{
    istringstream i(s);
    ostringstream o;
    copy(istream_iterator<string>(i), istream_iterator<string>(), ostream_iterator<string>(o, " "));
    s.swap (o.str());
    if (!s.empty()) s.resize(s.size() - 1);   
}


Пожалуйста! Правда не уверен в производительности, но зато за один проход.
Re[6]: Удаление лишних пробелов в строке
От: Анатолий Широков СССР  
Дата: 13.06.05 20:39
Оценка:
Позволь буквы поесть

s.swap (o.str());


не прокатит, поскольку o.str() rvalue, а swap принимает lvalue, поэтому правильно будет:

o.str().swap(s);
Re[7]: Удаление лишних пробелов в строке
От: Pavel Chikulaev Россия  
Дата: 13.06.05 20:53
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>Позволь буквы поесть

Thanks Компилятора под рукой не было, не запускал, так бы и сам увидел
Re[2]: Удаление лишних пробелов в строке
От: gok Россия  
Дата: 14.06.05 19:58
Оценка:
Здравствуйте, srez, Вы писали:

Сорри за офф. Пытаюсь компилить пример, вылазит непонятное сообчение:
bool std::isspace(_Elem,const std::locale &)' : expects 2 arguments — 1 provided

хотя в ctype.h такое определение:

_CRTIMP int __cdecl isspace(int);

что за беда? Помогите!
gok
Re[6]: Удаление лишних пробелов в строке
От: gok Россия  
Дата: 14.06.05 21:04
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

PC>Пожалуйста! Правда не уверен в производительности, но зато за один проход.


Работает! Производительность не обнадеживает:
CString: 1:00
STL: 2:45
но было предупреждение.

Спасибо!
gok
Re[4]: Удаление лишних пробелов в строке
От: gok Россия  
Дата: 14.06.05 22:02
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>Просто у автора не совсем дописан функтор. Попробуй:


Работает!
И даже довольно быстро!
CString: 1:00
STL: 1:27
Спасибо!
gok
Re[6]: Удаление лишних пробелов в строке
От: Erop Россия  
Дата: 14.06.05 22:21
Оценка:
Здравствуйте, AI, Вы писали:

gok>>Пользую CString:

gok>>
gok>>while ( currentString.Replace("  ", " ") > 0 ){}
gok>>

gok>>Mожет что за один проход есть?

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



Приведённое решение работает за квадратичное время от длины строки. Так что может легко взорваться

Даже просто строка из 100 000 пробелов скорее всего будет обрабатываться очень очень долго (надо будет переслать что-то порядка 5 000 000 000 байт из памяти в память
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Удаление лишних пробелов в строке C-style :)
От: Erop Россия  
Дата: 14.06.05 22:43
Оценка:
Здравствуйте, bip29, Вы писали:

B> Народ не подскажет ли кто каким образом из строки убрать лишние пробелы и управляющие символы (\n,\r и др.). Мысль коечно есть но не хотелося б посимвольно читать строку. Может есть другие варианты. Хотелося б увидеть варианты на С или С++(не VCL,MFS b др).



Привет!
Интересно было бы сравнить со скоростью ещё и такого подхода:


bool isMySpace( char ch )
{
    return ch == ' ';    //    это соответсвует твоему примеру.

//    а это чуть гибче, и более соответсвует тому, что просишь :)
    return isspace( ch ) || ch == '\n' /*|| что хочешь ещё.*/;

//    как варинат можно и так:
    const char* spaces = " \t\r\n";
    return strchar( spaces, ch ) != 0;    //    :)
}


void removeExtraSpaces( CString& str )
{
    int length = str.GetLength();
    int insPos = 0;
    int curPos = 0;
    char* ptr = str.GetBuffer( length );
    while( curPos < Length ) {
        if( !isMySpace( ptr[curPos] ) ) {
            ptr[insPOs++] = ptr[curPos++];
            continue;
        }
        ptr[insPos] = ' ';
        curPos++;
        while( curPos < length && isMySpace( ptr[curPOs] ) )
            curPos++;
    }
    ptr[insPos] = 0;
    str.ReleaseBuffer( insPos );
}


Опять же интересно узнать что за строчки использовались для измерения
Что-то мне так кажется, что такой C-style подход должен сильно делать и твой CString и предложенные STL варианты на строчках, где есть заметное число замен. Скажем где все слова разделены цепочками из нескольких пробелов и слов много


p. s.
1) Компилятора с MFC под рукой нету . Если не компилится, то прости. Я думаю тебе тут помогут отладить
2) Я так понял, что CString -- это из MFC
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Удаление лишних пробелов в строке C-style :)
От: gbt Россия  
Дата: 15.06.05 03:52
Оценка:
Здравствуйте, Erop, Вы писали:

E>Привет!

E>Интересно было бы сравнить со скоростью ещё и такого подхода:

E>

E>bool isMySpace( char ch )
E>{
E>    return ch == ' ';    //    это соответсвует твоему примеру.

E>//    а это чуть гибче, и более соответсвует тому, что просишь :)
E>    return isspace( ch ) || ch == '\n' /*|| что хочешь ещё.*/;

E>//    как варинат можно и так:
E>    const char* spaces = " \t\r\n";
E>    return strchar( spaces, ch ) != 0;    //    :)
E>}
E>


isspace returns a non-zero value if c is a white-space character (0x09 – 0x0D or 0x20).
Так что isspace решает все проблемы

bool isMySpace(char ch)
{
    return isspace(ch); // Вернет true для ' ', '\t', '\n', '\r'.
}
Re[7]: Удаление лишних пробелов в строке
От: Pavel Chikulaev Россия  
Дата: 15.06.05 04:30
Оценка:
Здравствуйте, gok, Вы писали:

gok>CString: 1:00

gok>STL: 2:45

надеюсь тестил в релизе, а иначе STL будет еще больше тормозить
Re: Удаление лишних пробелов в строке
От: Pavel Chikulaev Россия  
Дата: 15.06.05 06:18
Оценка:
Здравствуйте, bip29, Вы писали:

B> Народ не подскажет ли кто каким образом из строки убрать лишние пробелы и управляющие символы (\n,\r и др.). Мысль коечно есть но не хотелося б посимвольно читать строку. Может есть другие варианты. Хотелося б увидеть варианты на С или С++(не VCL,MFS b др).

B>Заранее благодарен.

Вот еще два гибрида C-style с C++-style:
Подход у них один — у первого оптимизация по скорости, у второго — по размеру

void eat_some_whitespaces2 (string & s)
{
    string temp(s.size(), 0);

    string::iterator curr = s.begin(),
        end  = s.end(),
        out  = temp.begin();

    locale loc;

    while (curr != end)
    {
        if (isspace(*curr, loc)) 
        {
            *out = ' ';
            ++out;
            ++curr;
            while (curr != end)
            {
                if (isspace(*curr, loc)) ++curr;
                else 
                {
                    *out = *curr;
                    ++out;
                    ++curr;
                    break;
                }
            }
        }
        else
        {
            *out = *curr;
            ++out;
            ++curr;
        }
    }
    temp.resize(out - temp.begin());
    s.swap(temp);
}

void eat_some_whitespaces3 (string & s)
{
    string temp(s.size(), 0);

    string::iterator curr = s.begin(),
        end  = s.end(),
        out  = temp.begin();

    locale loc;

    bool write = true;

    while (curr != end)
    {
        if (isspace(*curr, loc)) 
        {
            if (write)
            {
                *out = ' ';
                ++out;
                write = false;
            }
            ++curr;
        }
        else
        {
            *out = *curr;
            ++out;
            ++curr;
            write = true;
        }
    }
    temp.resize(out - temp.begin());
    s.swap(temp);
}


Надеюсь сделают всех (в релизе естественно)
Если известно что строки contiguous вместо string::iterator можно написать char * (В 100% реализациях STL)
Re[5]: Удаление лишних пробелов в строке
От: Анатолий Широков СССР  
Дата: 15.06.05 06:32
Оценка:
Здравствуйте, gok, Вы писали:

gok>Здравствуйте, Анатолий Широков, Вы писали:


АШ>>Просто у автора не совсем дописан функтор. Попробуй:


gok>Спасибо!


srez-а благодари, а не меня.
Re: Удаление лишних пробелов в строке
От: kaa_t Россия  
Дата: 15.06.05 08:57
Оценка:
Здравствуйте, bip29, Вы писали:


char *space_deleter( char *s )
{
      char *b=s,*p=s;
      for(;*p;p++) if (*p==' ') *b++ = *p;
      *b=0; return s; 
}

char *trim_str( char *s , int l)
{
      char *b=s,*p=s,*p2=s+l-1;
      for(;*p;p++) if (*p==' ') *b++ = *p; else break;
      for(;*p2==' ';p2--)*p2=0;
      for(;*p;p++,b++) *b=*p;
      *b=0; return s; 
}
Re[8]: Удаление лишних пробелов в строке
От: gok Россия  
Дата: 15.06.05 18:36
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

Ага, релиз, из-под 7.0.
gok
Re[2]: Удаление лишних пробелов в строке
От: Pavel Chikulaev Россия  
Дата: 16.06.05 14:59
Оценка:
Здравствуйте, kaa_t, Вы писали:

[skipped]

А ты в курсе что это совсем не "Удаление лишних пробелов в строке"? Если да, то скажи зачем ты это запостил? C rulez?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.