Помогите, пожалуйста оптимизировать код программы

Тема в разделе "Общие вопросы по С и С++", создана пользователем lrad, 1 май 2007.

Статус темы:
Закрыта.
  1. lrad

    lrad Гость

    Условие задачи:
    1. Описать класс (структуру) со следующими полями:
    - фамилия, инициалы авторов;
    - название книги;
    - издательство;
    - год издания;
    - количество страниц;
    - количество глав в книге;
    - название дисциплины.
    2. Написать программу, выполняющую следующие действия:
    - ввод информации в файл;
    - вывод всей информации на экран;
    - вывод на экран информации о фамилии автора, название и количества страниц книги, обеспечивающих дисциплину, название которой введено с клавиатуры.
    Код (Text):
    #include <iostream.h>
    #include <fstream.h>
    #include <string.h>
    #include <conio.h>
    #include <iomanip.h>
    #include <stdlib.h>
    #define FIO 20
    #define name 20
    #define PUBLISHERS 20
    #define YEAR 4
    #define PAGES 6
    #define CHAPTER 6

    //--------------------------------------------------------------------------------------
    struct book
    {
    char fio[25];
    char name_book [25];
    char publishers[25];
    int year_publishers;
    int pages;
    int chapter;
    char discipline[17];
    };
    //----------------------------------------------------------------------------------------

    // прототипы функций
    void sozdanie();
    void prosmotr();
    void vibor();
    void tabl();
    //-----------------------------------------------------------------------------------------

    // Опеpация-функция ввода с клавиатуpы
    istream &operator >> (istream &in, book &x)
    {
    cout<<"\nФамилия и инициалы:";
    in.seekg(0,ios::end);
    in.get(x.fio,FIO-1,'\n');
    cout<<" \nНазвание книги:";
    in.seekg(0,ios::end);
    in.get(x.name_book,name-1,'\n');
    cout<<"\nИздательство:";
    in.seekg(0,ios::end);
    in.get(x.publishers,PUBLISHERS-1,'\n');
    cout<<"\nГод издания:";
    in.seekg(0,ios::end);
    in >>x.year_publishers,YEAR-1;
    cout<<"\nКоличество страниц:";
    in.seekg(0,ios::end);
    in >>x.pages, PAGES-1;
    cout<<"\nКоличество глав в книге:";
    in.seekg(0,ios::end);
    in>>x.chapter, CHAPTER-1;
    cout<<" \nНазвание дисциплины:";
    in.seekg(0,ios::end);
    in >>x.discipline;
    return in;
    }
    //------------------------------------------------------------------------

    // Опеpация-функция вывода на дисплей
    ostream &operator << (ostream &out, book x)
    {
    out.setf (ios::left); // установка флага равнения по левому краю
    out << "|" << setw(17) << x.fio << "|" << setw(15) << x.name_book
    << "|"<< setw(11)<< x.publishers  << "|" << x.year_publishers
    << "|" << setw(4)<< x.pages << "|"<< setw(4)<< x.chapter
    << "|" <<setw(16)<< x.discipline << "|\n";
    return out;
    }

    // Опеpация-функция чтения из файла
    ifstream &operator >> (ifstream &in, book &x)
    {
    in.getline(x.fio,FIO,'\n');
    in.getline(x.name_book, name,'\n');
    in.getline(x.publishers,PUBLISHERS,'\n');
    in>>x.year_publishers,YEAR;
    in>>x.pages, PAGES-1;
    in>>x.chapter, CHAPTER-1;
    in >>x.discipline;
    in.seekg (2L, ios::cur);
    return in;
    }
    // Опеpация-функция записи в файл
    ofstream &operator << (ofstream &out, book &x)
    {
    out << x.fio << endl
    << x.name_book << endl
    << x.publishers << endl
    << x.year_publishers << endl
    << x.pages << endl
    << x.chapter << endl
    << x.discipline << endl;
    return out;
    }


    //------------------------------------------------------------------------

    void main(void)
    {
    char c;
    while (1)
    {
    cout << endl << "1. Создание файла";
    cout << endl << "2. Просмотр содержимого";
    cout << endl << "3. Вывод на экран информации о фамилии автора," << endl;
    cout <<"  название книги и количество страниц";
    cout << endl << "4. Выход";
    cout << endl << "Ваш выбор -> ";
    cin.seekg(0,ios::end);
    c = cin.get();
    switch(c)
    {                                                                                                        
    case '1':
    sozdanie();
    break;

    case '2':
    prosmotr();
    break;

    case '3':
    vibor();
    break;

    case '4':
    return;




    default:
    cout << "Вводите только цифры от 1 до 4" << endl;
    }
    }
    }


    // определение функции вывода на экран шапки таблицы
    void tabl()
    {
    cout << "-------------------------------------------------------------------------------------------\n";
    cout << "|   Ф.И.О.   | Название книги|  Изд-во | Год|Стр.|Глав| Дисциплина |\n";
    cout << "|-----------------|--------------------|----- ------|-----|-----|------|-------------------|\n";
    }



    // определение функции создания файла
    void sozdanie()
    {
    char c;
    ofstream ff; // создание потока ff для записи в файл
    book s;
    ff.open( "bok.txt" );
    // открытие файла book.txt и связывание его
    // c потоком ff
    if ( !ff) // проверка открытия файла
    {
    cerr << "Ошибка открытия файла bok.txt для записи\n";
    exit(1);     // аварийный выход
    }

    // Цикл записи элементов в файл
    do
    {
    cin >> s;   // обращение к операции-функции ввода с клавиатуpы
    ff << s;    // обращение к операции-функции записи в файл
    cout<<"\nПpодолжить ввод?(Y/N или Д/H)";
    cin.seekg(0L, ios::end);
    c = cin.get();
    }
    while ( c == 'y' || c == 'Y' || c == 'д' || c == 'Д');
    ff.close();   // закpытие файла
    }


    // определение функции вывода всей информации на экран
    void prosmotr()
    {
    ifstream finp; // создание потока finp для чтения из файла
    book s;
    finp.open( "bok.txt", ios::in );
    // открытие файла bok.txt и связывание его
    // с потоком finp

    if ( !finp ) // проверка открытия файла
    {
    cerr << "Ошибка открытия файла bok.txt для чтения\n";
    exit(1);     // аварийный выход
    }
    cout << "\nСписок элементов из файла\n";
    tabl(); // вывод на экран шапки таблицы
    while ( finp )
    {
    finp >> s;  // обращение к операции-функции чтения из файла
    if ( strlen ( s.discipline) <= 0 )
    // длина первого поля в записи меньше либо равна нулю
    break;   // выход из цикла

    cout << s;  // обращение к операции-функции вывода на экран
    }
    finp.close();    // закpытие файла

    }

    // определение функции вывода на экран информации,
    // отвечеющей условию поиска
    void vibor()
    {
    char discipline[15]; // для ввода условия поиска
    ifstream fi;    // создание потока fi для чтения из файла
    book b;
    fi.open("bok.txt", ios::in);
    // открытие файла bok.txt и связывание его
    // с потоком fi

    if ( !fi ) // проверка открытия файла
    {
    cerr << "Ошибка открытия файла bok.txt для чтения\n";
    exit(1);     // аварийный выход
    }

    cout << "Введите название дисциплины:";
    cin.seekg(0,ios::end);
    cin.get(discipline,'\n');
    cout << "Информация о книге\n";
    tabl(); // вывод на экран шапки таблицы
    while (!fi.eof())
    {
    fi >> b;      // обращение к операции-функции чтения из файла
    if (strcmp(b.discipline,discipline)==0)
    // дисциплины совпали
    cout << b;  // обращение к операции-функции вывода на экран
    }
    fi.close();

    }
     
  2. North

    North Гость

    Что здесь оптимизировать ?
    1. Чтение из файла ? Для этого можешь отмапить свой файл "bok.txt" с помощью функции MapViewOfFile( map_file, FILE_MAP_READ, 0, offset, len); таким образом содержимое файла последовательно записывается в память (подробности в MSDN)

    2. Сравнение строк ? Функцию strcmp(b.discipline,discipline)==0 можно заменить, на сравнение кодов сравниваемых строк. Эти самые коды вычисляются заранее и представляют числовое значение соответствующее первым 6 символам в строке. Исли эти коды различны - строки уже различны, если коды одинаковы необходима проверка оставшихся n-6 символов строк. Это непросто и требует создания велосипеда вроде std::string.

    3. Поиск ? Рекомендую использовать hash-функции, в первую очередь контейнер std::map
     
  3. tansa

    tansa Гость

    Ты не описал в чем проблемма.
    Но я тебе могу сказать вот что(только косметика).

    1.В C++ не модно писать #include <iostream.h>, вроде как нужно #include <iostream>. Может у тебя и компилится, но у меня LInux + gcc не хотят.
    2. Вот за такое:
    Код (Text):
    // прототипы функций
    void sozdanie();
    void prosmotr();
    void vibor();
    void tabl();
    У меня в универе половину пунктов снимают сразу.

    3. Определись с языком в котором пишешь, потому что если это C++, то в нем не приветствуются глобальные функции, а все это прячется в структуру. А если C, то там ты не перегрузишь операторов "<<", ">>" и т.п.

    4. Чтобы работали cout, cin, и др. Тебе надо using namespace std; или писать "std::cout", но вообще изменение стандартного namespace'а не приветствуется.

    5. А в чем собственно твой вопрос?
     
  4. North

    North Гость

    НА самом деле вся эта задача решается "десятью строчками" если использовать STL контейнеры и алгоритмы
     
  5. tansa

    tansa Гость

    Для: North
    это не интересно :)
     
  6. lrad

    lrad Гость

    1)Насчет #include <iostream> и using namespace std
    у меня задание написать эту программу в среде борланд 3.11, а там без ".h" не компилируется и using namespace std выдает тут же ошибку
    2)
    А как это сделать? Подскажите, пожалуйста
    Дело в том, что я учусь на заочном за 300 км от универа и мне узнать больше негде
     
  7. tansa

    tansa Гость

    <!--QuoteBegin-lrad+1:05:2007, 12:02 -->
    <span class="vbquote">(lrad @ 1:05:2007, 12:02 )</span><!--QuoteEBegin-->Дело в том, что я учусь на заочном за 300 км от универа и мне узнать больше негде
    [snapback]64084" rel="nofollow" target="_blank[/snapback]​
    [/quote]

    Это уже зажисит от того, какое у тебя задание и как называется предмет. Потому что мне на объектовом программировании запрещали STL использовать.

    А операторы << и >> лучше в структуру засунь.
     
  8. lrad

    lrad Гость

    Задание звучит так:
    Задание: Задача по обработке файлов.
    В этой контрольной работе студент должен самостоятельно определить структуру записи и характеристики ее элементов, выполнить описание данной структуры и написать программу, содержащую функции создания файла, вывода на экран всей информации и информации, соответствующей условиям поиска : напечатать фамилии авторов, названия и количество страниц книг, обеспечивающих дисциплину, название которой введено с клавиатуры.
    Запись должна содержать следующую информацию: фамилия и инициалы авторов, название книги, издательство, год издания, количество страниц, количество глав в книге, название дисциплины.
    Для проверки правильности работы программы ее нужно протестировать. Для этого необходимо записать в файл 8-10 записей и далее выполнить вывод на экран вначале всей инфомации, а затем информации, соответствующей условию поиска.

    Предмет-Программирование на языках высокого уровня
     
  9. North

    North Гость

    Создаеш контейнер асоциированных пар для своих данных, т.е. [структура учебника:название предмета]

    struct compare
    {
    bool operator()(const char* discip1, const char* discip2) const
    {
    return strcmp(discip1,discip2)==0;
    }
    };

    std::map<const char*, struct book, compare> container;

    первый параметр Key - в твоем случае это название предмета
    второй Data - то что будет асоциировано с конкретным ключем (Key)
    третий параметр compare - объект выполняющий сравнение ключей(дисциплин)

    Заполняешь container. Далее испjльзуешь один из стандартных алгоритмов обьявленных в <alghoritm>, вроде std::find

    Короче твоя задача сводится к заполнению структуры данных container и выводу на экран её содержимого.

    ЕЩЕ. Среда разработки (Борданд С++ 3.11) ОЧЕНЬ устаревшая. Во время ее создания многого из вышеописанного могли еще не придумать :)

    Рекомендую прислушаться к словам tansa, причесать код под C++, минимизировать операции чтения данных из файла (читай загружать содержимое файла в память и уже в памяти выполнять поиск и проч.)
     
  10. lrad

    lrad Гость

    а как засунуть операторы << и >> в структуру?
     
  11. North

    North Гость

    именно
    istream &operator >> (istream &in, book &x);
    ifstream &operator >> (ifstream &in, book &x);
    ostream &operator << (ostream &out, book x);
    ofstream &operator << (ofstream &out, book &x);

    никак, у тебя это не получится
    а вот:
    void sozdanie();
    void prosmotr();
    void vibor();
    void tabl();
    следует вставить в структуру (сделать членами book)
     
  12. lrad

    lrad Гость

    Спасибо Всем, кто откликнулся
     
  13. tansa

    tansa Гость

    <!--QuoteBegin-North+1:05:2007, 12:51 -->
    <span class="vbquote">(North @ 1:05:2007, 12:51 )</span><!--QuoteEBegin-->никак, у тебя это не получится
    [snapback]64095" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    почему же не получится?

    в структуре пишешь
    Код (Text):
    ostream &operator << (ostream &out, const book& x);
    ну а снаружи пишешь
    Код (Text):
    book::ostream &operator << (ostream &out, const book& x)
    {
    out.setf (ios::left); // установка флага равнения по левому краю
    out << "|" << setw(17) << x.fio << "|" << setw(15) << x.name_book
    << "|"<< setw(11)<< x.publishers  << "|" << x.year_publishers
    << "|" << setw(4)<< x.pages << "|"<< setw(4)<< x.chapter
    << "|" <<setw(16)<< x.discipline << "|\n";
    return out;
    }
    И все впорядке....
     
  14. North

    North Гость

    Я не проверял твой код на работоспособность, но в своем суждении исхоу из следующего:

    1. << бинарный оператор.
    2. для любого бинарного оператора выражение a@b интерпретируется либо как a.operator @:)), либо как
    operator @(a,:)

    2.1 в первом случае ( a.operator @(B) ) функция operator@ определена как нестатический член (исключая new, delete и их вариации) класса A (а имеет тип A)
    2.2 во втором случае ( operator @(a,B) ) есть функция-не-член классов (A и B)

    3. Мы не можем изменять определение классов из std::. В том числе и std::eek:stream.

    Есть тонкая разница:
    Мы МОЖЕМ определить только
    ostream &operator << (ostream &out);
    как член класса book
    при этом вызов данного оператора будет таким:
    my_book << std::eek:ut;
    хотя наиболее привычным является
    std::eek:ut << my_book;


    [ушел читать Книгу Создателя]
     
  15. minsk_girl

    minsk_girl Гость

    Для: North
    помоги, пожалуйста. Зайди на мою тему "помогите плиз девушке"
     
Загрузка...
Похожие Темы - Помогите пожалуйста оптимизировать
  1. limbra
    Ответов:
    3
    Просмотров:
    68
  2. uxbmw3w
    Ответов:
    0
    Просмотров:
    90
  3. GREED
    Ответов:
    1
    Просмотров:
    545
  4. Рая
    Ответов:
    3
    Просмотров:
    791
  5. sonia2000
    Ответов:
    0
    Просмотров:
    965
Статус темы:
Закрыта.

Поделиться этой страницей