Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Качество кода: вектор векторов и т.д. 
:(
    Опции темы
nerezus
  Дата 13.5.2009, 01:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вселенский отказник
****


Профиль
Группа: Участник
Сообщений: 3330
Регистрация: 15.6.2005

Репутация: 3
Всего: 43



Код

vector< vector<string> > regex_search_all(string text, string pattern) {
    vector< vector<string> > results;
    string::const_iterator start, end;
    boost::regex re(pattern);
    boost::match_results<string::const_iterator> res;
    start = text.begin();
    end = text.end();
    boost::match_flag_type flags = boost::match_default;
    while(boost::regex_search(start, end, res, re, flags)) {
        vector<string> line;
        for(int i = 0; i < res.size(); i++) {
            line.push_back(string(res[i].first, res[i].second));
        }
        results.push_back(line);
        flags |= boost::match_prev_avail;
        flags |= boost::match_not_bob;
        start = res[0].second;
    }
    return results;
}


Я не умею писать на C++. Это видно из качества данного кода.
Кто хочет мне дать какие советы?


--------------------
Сообщество художников Artsociety.ru
PM MAIL WWW   Вверх
Lazin
Дата 13.5.2009, 08:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



что-бы не возвращать вектор из ф-ии и избежать лишнего копирования, можно передавать в нее insert iterator, тип можно не указывать явно
Код

template<class InsertIterator>
void regex_search_all(string text, string pattern, InsertIterator i) 
{
...
    //results.push_back(line);
    *i++ = line;
...
}


использовать можно так:
Код

typedef std::vector< std::vector< std::string > > search_results_type;
search_results_type results;
std::insert_iterator< search_results_type > inserter(results, results.end());
regex_search_all(text, pattern, inserter);

PM MAIL Skype GTalk   Вверх
azesmcar
Дата 13.5.2009, 08:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



nerezus

1.vector< vector<string> > -  не мешало бы тайпдефнуть это безобразие smile
2. возвращать vector по ссылке, или как сказал Lazin
3.

Цитата(nerezus @  13.5.2009,  01:52 Найти цитируемый пост)

string::const_iterator start, end;
boost::regex re(pattern);
boost::match_results<string::const_iterator> res;
start = text.begin();
end = text.end();

почему бы не инициализировать start и end сразу там где они нужны?
Код

    string::const_iterator start = text.begin();
    string::const_iterator end = text.end();

а вообще зачем нужны эти переменные?
Цитата

for(int i = 0; i < res.size(); i++) {
            line.push_back(string(res[i].first, res[i].second));
        }

этот цикл наверняка можно заменить на алгоритм std::copy (я просто точно не знаю что там буст возвращает)

Добавлено через 6 минут и 6 секунд
Цитата

        flags |= boost::match_prev_avail;
        flags |= boost::match_not_bob;

зачем это нужно в цикле?

PM   Вверх
xvr
Дата 13.5.2009, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Здесь явно напрашивается класс
Код

class RegexSerachAll {
 vector<pair<size_t,size_t> > results;
 vector<string> lines;

public:
 RegexSerachAll (string text, string pattern) {
    string::const_iterator start, end;
    boost::regex re(pattern);
    boost::match_results<string::const_iterator> res;
    start = text.begin();
    end = text.end();
    boost::match_flag_type flags = boost::match_default;
    while(boost::regex_search(start, end, res, re, flags)) {
        size_t mark=lines.size();
        for(int i = 0; i < res.size(); i++) {
            lines.push_back(string(res[i].first, res[i].second));
        }
        results.push_back(make_pair(mark,lines.size());
        flags |= boost::match_prev_avail;
        flags |= boost::match_not_bob;
        start = res[0].second;
    }
};
Двойной итератор по results->lines оставляю в качестве упражнения  smile 
PM MAIL   Вверх
nerezus
Дата 13.5.2009, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вселенский отказник
****


Профиль
Группа: Участник
Сообщений: 3330
Регистрация: 15.6.2005

Репутация: 3
Всего: 43



Цитата

что-бы не возвращать вектор из ф-ии и избежать лишнего копирования, можно передавать в нее insert iterator
 Чем это лучше передачи results по ссылке?


Цитата
typedef std::vector< std::vector< std::string > > search_results_type;
 
Цитата
1.vector< vector<string> > -  не мешало бы тайпдефнуть это безобразие 
 done

Цитата

2. возвращать vector по ссылке, или как сказал Lazin
 Что лучше: итератор, ссылка, или vector< vector< string > > * ?

Цитата

этот цикл наверняка можно заменить на алгоритм std::copy (я просто точно не знаю что там буст возвращает)
 

Цитата

flags |= boost::match_prev_avail;
flags |= boost::match_not_bob;
 Насколько я понял, это так надо для работы данной либы для такого поиска.

Цитата

Здесь явно напрашивается класс
 Не думаю. Обычная функция с 3 переменными(2 in, 1 out). Даже обернутая в класс не добавит удобаства.


--------------------
Сообщество художников Artsociety.ru
PM MAIL WWW   Вверх
azesmcar
Дата 13.5.2009, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(nerezus @  13.5.2009,  14:29 Найти цитируемый пост)
 Чем это лучше передачи results по ссылке?

STL-овский стиль. 

Цитата(nerezus @  13.5.2009,  14:29 Найти цитируемый пост)
 Насколько я понял, это так надо для работы данной либы для такого поиска.

да, но зачем в цикле? значение то от этого не меняется.


если
boost::match_results<string::const_iterator> res;
стл совместимый контейнер, то цикл можно заменить на std::copy.
PM   Вверх
Lazin
Дата 13.5.2009, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(nerezus @  13.5.2009,  14:29 Найти цитируемый пост)
Чем это лучше передачи results по ссылке?

гибкостью, можно передавать любой итератор, у которого value_type = std::vector< std::string >
PM MAIL Skype GTalk   Вверх
xvr
Дата 13.5.2009, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(nerezus @ 13.5.2009,  14:29)
Цитата

Здесь явно напрашивается класс
 Не думаю. Обычная функция с 3 переменными(2 in, 1 out). Даже обернутая в класс не добавит удобаства.

Позволит избавится от вектора векторов, довольно расточительная конструкция  smile 

PM MAIL   Вверх
nerezus
Дата 15.5.2009, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вселенский отказник
****


Профиль
Группа: Участник
Сообщений: 3330
Регистрация: 15.6.2005

Репутация: 3
Всего: 43



Цитата

можно передавать любой итератор, у которого
 По смыслу этого не надо делать. Внешняя структур всегда будет вектором.

Цитата

Позволит избавится от вектора векторов, довольно расточительная конструкция   
 Почему расточительная? Только за счет генерации?
А если я хочу написать что-то многомерное, есть ли приемлемый контейнер для этого?

P.S. Какой контейнер может держать разнотипные данные? Или, как я понял, это зло, и надо использоватьь структуры/классы?


--------------------
Сообщество художников Artsociety.ru
PM MAIL WWW   Вверх
zim22
Дата 15.5.2009, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Цитата(nerezus @  15.5.2009,  12:09 Найти цитируемый пост)
P.S. Какой контейнер может держать разнотипные данные? 

эти данные вообще друг с другом не связаны? тогда не знаю.
если же это производные классы - то достаточно в контейнер поместить указатель на их базовый класс.


--------------------
PM MAIL   Вверх
xvr
Дата 15.5.2009, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(nerezus @ 15.5.2009,  12:09)
Цитата

Позволит избавится от вектора векторов, довольно расточительная конструкция   
 Почему расточительная? Только за счет генерации?

За счет увеличения количества векторов. Если во внешнем векторе будет много маленьких внутренних векторов, то такая конструкция приведет к массе алокаций маленьких кусочков памяти вместо одного большого (как будет в случае 2х векторов - вектор всех внутренних элементов и вектор индексов).
Это ОЧЕНЬ неэффективно по скорости, кроме того, это может привести к фрагментации кучи.

Добавлено через 44 секунды
Цитата(nerezus @ 15.5.2009,  12:09)
P.S. Какой контейнер может держать разнотипные данные?

boost::any

PM MAIL   Вверх
nerezus
  Дата 15.5.2009, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вселенский отказник
****


Профиль
Группа: Участник
Сообщений: 3330
Регистрация: 15.6.2005

Репутация: 3
Всего: 43



Цитата

кроме того, это может привести к фрагментации кучи.
 Я думал, что память под него выделяется в стеке.


--------------------
Сообщество художников Artsociety.ru
PM MAIL WWW   Вверх
mes
Дата 15.5.2009, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(nerezus @  15.5.2009,  13:29 Найти цитируемый пост)
 Я думал, что память под него выделяется в стеке. 

не путайте  "под него" и "под его данные". Вектор - это оболочка над динамическим массивом,
и при стандартной аллокации, память под массив выделяется в куче.


--------------------
PM MAIL WWW   Вверх
Lazin
Дата 15.5.2009, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(nerezus @  15.5.2009,  14:29 Найти цитируемый пост)
Я думал, что память под него выделяется в стеке. 

под сам вектор - да, под данные, которые он хранит - нет, это-же динамический массив
PM MAIL Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1453 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.