И так, перешел от чара к стрингу, появились вопросы.
1) Есть такой вот стринг:
***
Всем привет, это Денис, шмокжмафгыкормхклкфыы!
Желаю приятного блждыыыыгогогогогогоахах дня.
***
Нужно найти слова длиннее 20 символов (тут их 2) и заменить на VAU!!!
Слово может быть, как в середине теста, так и первым/последним. Количество знаков препинания фиксировано: .,!?:;
Желательно пример кода, так как у меня нет идей (помимо полного уж изврата).
2) Дальше идут 3 задания:
// b. Не должно идти подряд более одного пробела
// c. Между словом и знаком препинания не должно быть пробела
// d. После знака препинания всегда должен идти пробел
Тут код не нужен, просто подсказка. Чем тут пользоваться? .find() ?
================
В общем, буду благодарен как за помощь, так и за ссылку на толковую статью по string-у.
Всем спасибо.
30 сентября 2009 в 12:02
Я не про поиск подстроки написал, а про поиск разделителей, которые образуют некоторое множество символов.
30 сентября 2009 в 12:01
Алгоритм поиска подстроки в строке не меняется. Я знаю принцип его работы.
Но в данном случае я предложил метод именно поиска одного символа. То есть моим методом сложность будет O(n) где n – кол-во символов в строке. (разумеется без учета работы алгоритма замены, но если можно использовать вторую строку, то тоже O(n))
30 сентября 2009 в 12:00
Один символ да, а группу символов? Я не думаю, что в библиотеке тупо сравнивается текущий символ с каждым символом из образца, ведь тогда сложность будет O(m*n),
а можно и за O(log(m)*n) это реализовать(m – кол-во символов в образце, n – длина строки). replace – перемещает блоки памяти,
делает реаллокацию, самому такое оптимально тоже не очень просто написать.
А по регекспам даже не знаю, что посоветовать. Погугли.
30 сентября 2009 в 11:05
ну насчет скорости что тут спорить один символ все равно быстрее не найдешь чем тупо перебор строки.
Регэкспы это круто конечно. Есть толковая справка для нубов?
30 сентября 2009 в 11:01
Насчет скорости можно поспорить.
В стандартной библиотеке методы написаны оптимальным образом,
и далеко не факт, что твоя реализация будет быстрее.
Насчет регекспов – команды в vim:
1) :%s/[^ .,!?:;]\{21,}/VAU!!!/g
2) b) :%s/ \{2,}/ /g
c) :%s/\([^,.!\?:;]\) \{1,}\([,.!\?:;]\)/\1\2/g
d) :%s/\([,.!\?:;]\)\([^ ]\)/\1 \2/g
Для awk они по-моему тоже подходят, хотя я не уверен.
30 сентября 2009 в 11:00
Boost библиотеку себе установи.
Наследуй класс string и добавь свои методы туда.
30 сентября 2009 в 10:04
Но все равно, с регекспами проще намного. Все вышеперечиленные задания делаются в одну строчку.
30 сентября 2009 в 10:04
забавно) но скорости это не добавит.
Хотя, некоторой гламурности кода добавит. А как с регэкспами делать?
30 сентября 2009 в 10:03
По ссылке смотри.
Например первое задание:
======================
#include <iostream>
using namespace std;
int main()
{
string str = "Всем привет, это Денис, шмокжмафгыкормхклкфыы!\n"
"Желаю приятного блждыыыыгогогогогогоахах дня.";
string separators = " ,.!?:;\"'\t\n";
string replacement = "VAU!!!";
cout << "====\n" << str << endl;
size_t from = 0, to;
size_t len;
while ( from < str.length() )
{
to = str.find_first_of( separators, from);
if ( to == string::npos )
{
to = str.length() – 1;
}
len = to – from;
if ( len > 20 )
{
str.replace( from, len, replacement);
from += replacement.length() + 1;
} else
{
from = to + 1;
}
}
cout << "====\n" << str << endl;
return 0;
}
========================
Вывод:
====
Всем привет, это Денис, шмокжмафгыкормхклкфыы!
Желаю приятного блждыыыыгогогогогогоахах дня.
====
Всем привет, это Денис, VAU!!!!
Желаю приятного VAU!!! дня.
30 сентября 2009 в 10:03
Блин, форматирование поплыло.
См. тут:
//webcodes.ru/publ/1-1-0-1511
30 сентября 2009 в 8:03
Ну а вообще есть подходящий метод, find_first_of
//www.cplusplus.com/reference/string/string/fin...
30 сентября 2009 в 8:03
и как ей пользоваться? пример?
30 сентября 2009 в 8:02
можно регекспы использовать, через них все просто получается.
Но в стандартной библиотеке их вроде нет
30 сентября 2009 в 1:05
А как еще можно?
29 сентября 2009 в 21:00
Это не объектный подход – вы предлагаете тот же char*
29 сентября 2009 в 15:04
если пробел тоже понимать как знак препинания (в терминах программирования пробел+знаки_препинания=разделитель), то я бы делал так:
* (можно сделать копию строки если она нам нужна в целости и сохранности)
* бежим по строке (тупо цикл), ищем где разделитель меняется на не_разделитель.
* это будет у нас начало слова
* бежим дальше, ищем разделитель
* это у нас будет конец слова
* сразу находим длину слова, а координаты начала и конца уже есть
* если надо удалить эту часть строки, то справитесь я думаю и без меня =)
* повторяем бег по циклу пока строка не кончилась еще.