Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на C / C++


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Асмик Гаряка
Статус: Советник
Рейтинг: 10942
∙ повысить рейтинг »
Коцюрбенко Алексей aka Жерар
Статус: Советник
Рейтинг: 4122
∙ повысить рейтинг »
CradleA
Статус: Бакалавр
Рейтинг: 2270
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / C/C++

Номер выпуска:1766
Дата выхода:06.11.2012, 19:00
Администратор рассылки:Киселёва Алёна aka Verena (Академик)
Подписчиков / экспертов:102 / 70
Вопросов / ответов:1 / 1

Консультация # 186760: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: Прошу вас помочь написать программу - словарь: Описание задания Реализацию КЧ-дерева нашел здесь: Реализация дерева Язык любой ...


Консультация # 186760:

Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:

Прошу вас помочь написать программу - словарь: Описание задания

Реализацию КЧ-дерева нашел здесь: Реализация дерева

Язык любой (С/С++), но чем быстрее работает программа, тем лучше (почему-то на С++ некоторые программы не проходят time limit, а они же, реализованные на Си, проходят).

Заранее огромное спасибо откликнувшимся экспертам!

С уважением,

Иван.

Дата отправки: 29.10.2012, 18:25
Вопрос задал: Барс Иван (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Александр Чекменёв (Профессор):

Здравствуйте, Барс Иван!

В паре мест C++11 - возможно, для компиляции потребуется явно указать ключ, подобный -std=c++11 для gcc(-std=c++0x тоже соберёт).

Код :
#include <algorithm>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <map>

using namespace std;

typedef unsigned long long uint64;

map<string, uint64> dict;

void err(const string & message)
{
    cerr << "ERROR: " << message << "\n";
}

void out(const string & str)
{
    cout << str << "\n";
}

bool isWord(const string & str)
{
    return find_if(str.begin(), str.end(), [](char c) { return !isalpha(c); }) == str.end();
}

bool isValidWord(const string & str)
{
    return isWord(str) && str.length() <= 256;
}

void save(const string & path)
{
    ofstream file(path, ios::out | ios::binary | ios::trunc );
    if (file.is_open())
    {
        for (const auto & pair : dict)
        {
            const string & key = pair.first;
            unsigned char keyLen = key.length();
            file.write(reinterpret_cast<const char *>(&keyLen), 1);    // remember that key string is no more than 256 characters
            file.write(key.data(), keyLen);

            const uint64 & val = pair.second;
            file.write(reinterpret_cast<const char *>(&val), sizeof(uint64));
        }
        file.close();
        out("OK");
    }
    else
    {
        err("Unable to open file " + path + " for writing");
    }
}

#define CHECK_FS_GOOD(fs)   if (!fs.good()) \
                            { \
                                err("Bad file format"); \
                                fs.close(); \
                                return; \
                            }

void load(const string & path)
{
    ifstream file(path, ios::in | ios::binary );
    if (file.is_open())
    {
        vector<char> buf;
        while (file.good())
        {
            unsigned char keyLen;
            file.read(reinterpret_cast<char *>(&keyLen), 1);
            // If EOF is after full data group it is OK.
            if (file.eof())
            {
                break;
            }
            // But the other fails are not.
            CHECK_FS_GOOD(file)

            buf.reserve(keyLen+1);  // one more character to a terminal symbol
            file.read(buf.data(), keyLen);
            CHECK_FS_GOOD(file)
            buf[keyLen] = 0;    // add a terminal symbol to the raw string data
            string key(buf.data());

            uint64 val;
            file.read(reinterpret_cast<char *>(&val), sizeof(uint64));
            CHECK_FS_GOOD(file)

            //cout << "keyLen = " << (int)keyLen << "; key = " << key << "; val = " << val << "\n";

            dict[key] = val;
        }

        file.close();
        out("OK");
    }
    else
    {
        err("Unable to open file " + path + " for reading");
    }
}

#define CHECK_SS_GOOD(ss)   if (!ss.good()) \
                            { \
                                err("Invalid command"); \
                                return; \
                            }

#define CHECK_WORD(word)    if (!isValidWord(word)) \
                            { \
                                err("String " + key + " is not valid"); \
                                return; \
                            }

void lowercase(string * str)
{
    transform(str->begin(), str->end(), str->begin(), ::tolower);
}

void process(const string & command)
{
    stringstream ss;
    ss << command;

    CHECK_SS_GOOD(ss)
    string tok;
    ss >> tok;
    if (tok == "+")
    {
        CHECK_SS_GOOD(ss)
        string key;
        ss >> key;
        // String validity check.
        CHECK_WORD(key)
        lowercase(&key);

        CHECK_SS_GOOD(ss)
        uint64 val;
        ss >> val;

        if (dict.count(key) == 0)
        {
            dict[key] = val;
            out("OK");
        }
        else
        {
            out("Exist");
        }
    }
    else if (tok == "-")
    {
        CHECK_SS_GOOD(ss)
        string key;
        ss >> key;
        CHECK_WORD(key)
        lowercase(&key);

        if (dict.count(key) > 0)
        {
            dict.erase(key);
            out("OK");
        }
        else
        {
            out("NoSuchWord");
        }
    }
    else if (tok == "!")
    {
        CHECK_SS_GOOD(ss)
        ss >> tok;
        if (tok == "Save")
        {
            CHECK_SS_GOOD(ss)
            string path;
            ss >> path;

            save(path);
        }
        else if (tok == "Load")
        {
            CHECK_SS_GOOD(ss)
            string path;
            ss >> path;

            load(path);
        }
        else
        {
            err("Invalid command");
        }
    }
    else if (isValidWord(tok))
    {
        lowercase(&tok);
        if (dict.count(tok) > 0)
        {
            out("OK: " + dynamic_cast<std::ostringstream &>(std::ostringstream() << dict[tok]).str());
        }
        else
        {
            out("NoSuchWord");
        }
    }
    else
    {
        err("Invalid command");
    }
}

int main(int argc, char *argv[])
{
    /*while (true)
    {
        string command;
        getline(cin, command);
        if (command == "exit") break;
        process(command);
    }*/

    if (argc < 2)
    {
        cout << "Usage: my_cool_prog input_file" << endl;
        return 1;
    }

    ifstream file(argv[1]);
    if (file.is_open())
    {
        while (file.good())
        {
            string command;
            getline(file, command);
            process(command);
        }
    }
    else
    {
        err("Unable to open file " + string(argv[1]) + " for reading");
    }
    
    return 0;
}



Путь к файлу команд - первый(и обязательный) аргумент командной строки.

Пример файла команд:
Код :
+ a 1
+ b 2
+ qwerty 512345678942
- b
qwerty
+ abc4 2
! Save database
- qwerty
qwerty
! Load database
qwerty
+ aBc 42
AbC


Соответствующий вывод:
Код :
OK
OK
OK
OK
OK: 512345678942
ERROR: String abc4 is not valid
OK
OK
NoSuchWord
OK
OK: 512345678942
OK
OK: 42

Консультировал: Александр Чекменёв (Профессор)
Дата отправки: 05.11.2012, 09:55
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!



В избранное