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

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


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

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

Чемпионы рейтинга экспертов в этой рассылке

Гаряка Асмик
Статус: Профессионал
Рейтинг: 4632
∙ повысить рейтинг »
Boriss
Статус: Академик
Рейтинг: 2475
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 1996
∙ повысить рейтинг »

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

Номер выпуска:1572
Дата выхода:04.10.2010, 16:30
Администратор рассылки:Verena, Профессионал
Подписчиков / экспертов:338 / 171
Вопросов / ответов:1 / 2

Вопрос № 180088: Уважаемые эксперты,помогите пожалуйста решить задачу. Организовать меню,в ктором составить описание класса для объектов-векторов, которые задаются координатами конца в трехмерном пространстве. Обеспечить операции сложения и вычитания с получением ...



Вопрос № 180088:

Уважаемые эксперты,помогите пожалуйста решить задачу.
Организовать меню,в ктором составить описание класса для объектов-векторов, которые задаются координатами конца в трехмерном пространстве. Обеспечить операции сложения и вычитания с получением вектора(-суммы или -разности), вычисления скалярного произведения двух векторов, длины вектора и косинуса угла между векторами.
И если можно,то с комментариями. Очень нужно
Заранее спасибо!

Отправлен: 29.09.2010, 16:29
Вопрос задал: Olgaa, Посетитель
Всего ответов: 2
Страница вопроса »


Отвечает Евгений Набоков, 1-й класс :
Здравствуйте, Olgaa.

Вот полный код программы на с++ для вашей задачи: компилировал в Dev-C++, но и в MS Visual C++ тоже должен сработать.

Поместила код в приложение.
-----
∙ Отредактировал: Verena, Профессионал
∙ Дата редактирования: 30.09.2010, 22:04 (время московское)

Приложение:

Ответ отправил: Евгений Набоков, 1-й класс
Ответ отправлен: 29.09.2010, 20:04
Номер ответа: 263255

Оценка ответа: 5
Комментарий к оценке:
Программа работает. Большое спасибо!!! и всё очень ясно и понятно )

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 263255 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Отвечает Micren, Профессионал :
    Здравствуйте, Olgaa.
    Программа. Проверял в MS VS 2010.
    Работает по принципу калькулятора с обратной(польской) записью.
    Код:
    // Компилировать с включеной информацией о типах времени выполнения 
    // Для MS VS это /GR

    #include <locale>
    #include <limits>
    #include <iostream>
    #include <iomanip>
    #include <deque>
    #include <valarray>
    #include <stdexcept>
    #include <cfloat>
    #include <typeinfo>
    #include <sstream>
    #include <string>

    using namespace std;

    // Программа работает по принципу калькулятора с обратной(польской) записью
    // Этот класс здесь исключительно для полиморфиз ма и возможности выводить/хранить
    // в регистрах как числа, так и вектора
    class register_object
    {
    public:
    virtual string to_string() const=0;
    virtual ~register_object(){};
    };

    // Собственно вектор
    class my_vector:public register_object
    {
    public:
    // Конструктор
    explicit my_vector(double dx=0,double dy=0,double dz=0);
    // Деструктор
    virtual ~my_vector();
    // Оператор сложения
    my_vector operator+(const my_vector& right) const;
    // Оператор вычитания
    my_vector operator-(const my_vector& right) const;
    // Скалярное произведение
    double operator*(const my_vector& right) const;
    // Длина вектора
    double length() const;
    // Выводит на экран
    virtual string to_string() const;
    // Сосинус между векторами
    friend double cos(const my_vector& left,const my_vector& right);
    // Оператор вывода
    template<class Elem,class Traits> friend basic_istream<Elem,Traits>& operator>>(basic_istream<Elem,Traits>& stream,my_vector& vec);
    private:
    double _dx,_dy,_dz;
    };

    // Служит для хранения в регистрах калькулятора чисел типа double
    class my_num:public register_object
    {
    public:
    explicit my_num(double val=0);
    virtual ~my_num();
    virtual string to_string() const;
    private:
    double _val;
    };

    // Собственно программа
    class application
    {
    public:
    ~application();
    void run();
    private:
    // Возможный выбор пользователя
    enum user_choice
    {
    INPUT,
    PLUS,
    MINUS,
    SCALAR,
    LENGTH,
    COS,
    DELETE,
    QUIT
    };

    // Меню
    user_choice menu();
    // Ввод вектора
    my_vector input_vector();
    // Печать регистров калькулятора
    void print_registers();
    // Сложение векторов
    my_ vector plus_operation();
    // Вычитание векторов
    my_vector minus_operation();
    // Скалярное произведение
    double scalar_operation();
    // Длина
    double length_operation();
    // Косинус
    double cos_operation();

    typedef deque<register_object*> register_stack;
    typedef register_stack::const_reverse_iterator rev_it;
    // Здесь будем хранить значения
    register_stack registers;

    void check_registers(register_stack::size_type count) const;
    void delete_registers(register_stack::size_type count);
    };

    int main()
    {
    locale::global(locale(""));

    application app;
    app.run();

    return 0;
    }

    my_vector::my_vector( double dx/*=0*/,double dy/*=0*/,double dz/*=0*/ )
    :_dx(dx)
    ,_dy(dy)
    ,_dz(dz)
    {}

    my_vector my_vector::operator+( const my_vector& right ) const
    {
    return my_vector(_dx+right._dx,_dy+ri ght._dy,_dz+right._dz);
    }

    my_vector my_vector::operator-( const my_vector& right ) const
    {
    return my_vector(_dx-right. _dx,_dy-right._dy,_dz-right._dz);
    }

    double my_vector::operator*( const my_vector& right ) const
    {
    return _dx*right._dx+_dy*right._dy+_dz*right._dz;
    }

    double my_vector::length() const
    {
    return sqrt(_dx*_dx+_dy*_dy+_dz*_dz);
    }

    string my_vector::to_string() const
    {
    stringstream sstream;
    sstream<<'('<<_dx<<','<<_dy<<','<<_dz<<')';
    return sstream.str();
    }

    my_vector::~my_vector()
    {
    }

    double cos( const my_vector& left,const my_vector& right )
    {
    double result=left*right/left.length()/right.length();
    if(!_finite(result))
    {
    throw runtime_error("Невозможно вычислить косинус");
    }
    return result;
    }

    template<class Elem,class Traits>
    basic_istream<Elem,Traits>& operator>>(basic_istream<Elem,Traits>& stream,my_vector& vec)
    {
    double dx,dy,dz;
    stream>>dx>>dy>>dz;
    if(!stream.fail())
    {
    vec._dx=dx;
    vec._dy=dy;
    vec._dz=dz;
    }
    return stream;
    }


    my_num::my_num( double val/*=0*/ )
    :_val(val)
    {

    }

    string my_num::to_string() const
    {
    stringstream sstream;
    sstream<<_val;
    return sstream.str();
    }

    my_num::~my_num()
    {

    }

    application::~application()
    {
    // Освободим память.
    // Т.к. полиморфизм работает через указатели/ссылки мы ее выреляли динамически
    while(!registers.empty())
    {
    delete registers.front();
    registers.pop_front();
    }
    }

    void application::run()
    {
    user_choice choice;
    // Реакция на ввод пользователя
    while((choice=menu())!=QUIT)
    {
    try
    {
    switch(choice)
    {
    case INPU T:
    {
    registers.push_front(new my_vector(input_vector()));
    break;
    }
    case PLUS:
    {
    my_vector tmp=plus_operation();

    delete_registers(2);
    registers.push_front(new my_vector(tmp));
    break;
    }
    case MINUS:
    {
    my_vector tmp=minus_operation();

    delete_registers(2);
    registers.push_front(new my_vector(tmp));
    break;
    }
    case SCALAR:
    {
    double tmp=scalar_operation();

    delete_registers(2);
    registers.push_front(new my_num(tmp));
    break;
    }
    case LENGTH:
    {
    double tmp=length_operation();

    delete_registers(1);
    registers.push_front(new my_num(tmp));
    break;
    }
    case COS:
    {
    double tmp=cos_operation();

    delete_registers(2);
    registers.push_front(new my_num(tmp));
    break;
    }
    case DELETE:
    {
    delete_registers(1);
    break;
    }
    }
    }
    catch(const runtime_error& ex)
    {
    cout<<ex.what()<<endl;
    }
    catch(...)
    {
    cout<<"Необработанное исключение"<<endl;
    }
    print_registers();
    }
    }

    application::user_choice application:: menu()
    {
    while(true)
    {
    cout<<"Меню:"<<endl
    <<"1 - Ввод вектора "<<endl
    <<"2 - Сложить"<<endl
    <<"3 - Вычесть"<<endl
    <<"4 - Скалярное произведение"<<endl
    <<"5 - Длина вектора"<<endl
    <<"6 - Косинус угла между векторами"<<endl
    <<"7 - Удалить последнее значение"<<endl
    <<"0 - Выход"<<endl
    <<"Ваш выбор:";
    wint_t choice=_getwche();
    cout<<endl<<endl;
    switch(choice)
    {
    case '0':
    return QUIT;
    case '1':
    return INPUT;
    case '2':
    return PLUS;
    case '3':
    return MINUS;
    case '4':
    return SCALAR;
    case '5':
    re turn LENGTH;
    case '6':
    return COS;
    case '7':
    return DELETE;
    default:
    cout<<"Будьте внимательней"<<endl;
    }
    }
    }

    my_vector application::input_vector()
    {
    my_vector res;
    cout<<"Введите координаты вектора(dx,dy,dz):";
    cin>>res;
    if(cin.fail())
    {
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(),'\n');
    throw runtime_error("Ошибочный ввод");
    }
    return res;
    }

    void application::print_registers()
    {
    if(registers.size())
    {
    cout<<"------------------------------"<<endl;
    cout<<"Стек регистров калькулятора:"<<endl;
    cout<<"------------------------------"<<endl;
    register_stack::size_ type i=registers.size();
    while(i--)
    {
    cout<<setw(14)<<left<<(i?"":"Результат:")<<registers[i]->to_string()<<endl;
    }
    cout<<"------------------------------"<<endl;
    }
    }

    my_vector application::plus_operation()
    {
    check_registers(2);
    return *dynamic_cast<my_vector*>(registers[0])+*dynamic_cast<my_vector*>(registers[1]);
    }

    my_vector application::minus_operation()
    {
    check_registers(2);
    return *dynamic_cast<my_vector*>(registers[1])-*dynamic_cast<my_vector*>(registers[0]);
    }

    double application::scalar_operation()
    {
    check_registers(2);
    return *dynamic_cast<my_vector*>(registers[1])**dynamic_cast<my_vector*>(registers[0]);
    }

    double application::length_operation()
    {
    check_registers(1);
    return dynamic_cast&l t;my_vector*>(registers[0])->length();
    }

    double application::cos_operation()
    {
    check_registers(2);
    return cos(*dynamic_cast<my_vector*>(registers[0]),*dynamic_cast<my_vector*>(registers[1]));
    }

    // Проверяет требуемое количество регистров на наличие в них векторов, а не, например, чисел
    void application::check_registers( register_stack::size_type count ) const
    {
    stringstream sstream;

    if(registers.size()<count)
    {
    sstream<<"Требуется "<<count<<" операнд(а)";
    throw runtime_error(sstream.str());
    }
    for(register_stack::size_type i=0;i<count;++i)
    {
    // Проверка на соответствие по типу указателя
    if(typeid(*registers[i])!=typeid(my_vector))
    {
    sstream<<"Требуется "<<count<<" вектор(а)";
    throw runtime_error(sstream.str ());
    }
    }
    }

    // Очищает требуемое количество регистров
    void application::delete_registers( register_stack::si ze_type count )
    {
    if(count>registers.size())
    {
    count=registers.size();
    }
    while(count--)
    {
    delete registers.front(); registers.pop_front();
    }
    }


    Пример работы:
    Код:
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:1

    Введите координаты вектора(dx,dy,dz):1 2 3
    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    Результат: (1,2,3)
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:1

    Введите координаты вектора(dx,dy,dz):3 4 5
    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    (1,2,3)
    Результат: (3,4,5)
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:1

    Введите координаты вектора(dx,dy,dz):0 5 0
    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    (1,2,3)
    (3,4,5)
    Результат: (0,5,0)
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:1

    Введите координаты вектора(dx,dy,dz):1 0 0
    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    (1,2,3)
    (3,4,5)
    (0,5,0)
    Результат: (1,0,0)
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:1

    Введите координаты вектора(dx,dy,dz):2 4 6
    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    (1,2,3)
    (3,4,5)
    (0,5,0)
    (1,0,0)
    Результат: (2,4,6)
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произ ведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:1

    Введите координаты вектора(dx,dy,dz):9 8 6
    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    (1,2,3)
    (3,4,5)
    (0,5,0)
    (1,0,0)
    (2,4,6)
    Результат: (9,8,6)
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:1

    Введите координаты вектора(dx,dy,dz):7 7 7
    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    (1,2,3)
    (3,4,5)
    (0,5,0)
    (1,0,0)
    (2,4,6)
    (9,8,6)
    Результат: (7, 7,7)
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Дли на вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:5

    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    (1,2,3)
    (3,4,5)
    (0,5,0)
    (1,0,0)
    (2,4,6)
    (9,8,6)
    Результат: 12,1244
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:7

    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    (1,2,3)
    (3,4,5)
    (0,5,0)
    (1,0,0)
    (2,4,6)
    Результат: (9,8,6)
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скаляр ное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:4

    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    (1,2,3)
    (3,4,5)
    (0,5,0)
    (1,0,0)
    Результат: 86
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:7

    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    (1,2,3)
    (3,4,5)
    (0,5,0)
    Результат: (1,0,0)
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:6

    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    (1,2,3)
    (3,4,5)
    Результат: 0
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:7

    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    (1,2,3)
    Результат: (3,4,5)
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:2

    ------------------------------
    Стек регистров калькулятора:
    ------------------------------
    Результат: (4,6,8)
    ------------------------------
    Меню:
    1 - Ввод вектора
    2 - Сложить
    3 - Вычесть
    4 - Скалярное произведение
    5 - Длина вектора
    6 - Косинус угла между векторами
    7 - Удалить последнее значение
    0 - Выход
    Ваш выбор:

    Ответ отправил: Micren, Профессионал
    Ответ отправлен: 29.09.2010, 23:59
    Номер ответа: 263262

    Оценка ответа: 5

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 263262 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFpro.ru, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.21 от 28.09.2010

    В избранное