Re: Помогите реализовать алгоритм
От: korzhik Россия  
Дата: 22.09.04 20:38
Оценка:
Здравствуйте, momart, Вы писали:

M>Здравствуйте!

M>Есть такая задача:
M>строка [word1] bla-bla-bla [word2] tra-ta-ta [word1] be-be-be [word3] a-a-a [word2] и так далее. Надо оставить только первые вхождения слов в скобках:
M>[word1] bla-bla-bla [word2] tra-ta-ta be-be-be [word3] a-a-a

вот мой вариант:
#include <iostream>
#include <string>
#include <vector>

template<typename Iterator>
class tokenizer
{
private: 
    tokenizer(const tokenizer&);
    tokenizer& operator=(const tokenizer&);
public:
    struct token
    {
        Iterator first;
        Iterator last;
    };    

public:
    tokenizer()
    {
    }
    
    void set_str(Iterator first, Iterator last)
    {    
        first_    = first;
        last_    = last;
        current_= first_;
    }
    
    token current_token()
    {
        return token_;
    }
    
    bool next();

private:
    Iterator    first_;
    Iterator    last_;
    Iterator    current_;

    token        token_;
};

//-----------------------------------------------------------------------
template<typename Iterator>
bool tokenizer<Iterator>::next()
{
    if (current_ == last_) 
    {
        return false;
    }

    while (current_ != last_ && *current_ != '[') 
    {
        ++current_;
    }

    if (current_ == last_) 
    {
        return false;
    }

    unsigned count = 0;
    Iterator p = current_;

    while (p != last_ && *p != ']') 
    {
        ++p;
        ++count;
    }

    ++count;

    if (p == last_) 
    {
        return false;
    }

    token_.first = current_;
    token_.last  = current_ + count;

    current_ += count;

    return true;
}

//-----------------------------------------------------------------------
int main()
{
    std::string str("[word1] bla-bla-bla [word2] tra-ta-ta [word1] be-be-be [word3] a-a-a [word2]");

    typedef tokenizer<std::string::iterator> tokenizer;
    
    tokenizer tok;
    tok.set_str(str.begin(), str.end());

    std::vector<tokenizer::token> tokens;

    while (tok.next())
    {
        tokenizer::token tk = tok.current_token();

        std::vector<tokenizer::token>::iterator it   = tokens.begin();
        std::vector<tokenizer::token>::iterator last = tokens.end();

        for (;it != last; ++it)
        {
            if (std::distance(it->last, it->first) == std::distance(tk.last, tk.first) && 
                std::string(it->first, it->last) == std::string(tk.first, tk.last))
            {
                tok.set_str(str.erase(tk.first, tk.last), str.end());
            }
        }

        tokens.push_back(tok.current_token());
    }

    std::cout << str << std::endl;
}


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