Форум программистов, компьютерный форум CyberForum.ru

Нужно оптимизировать готовый код, чтобы не было стыдно показать - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 5.00
DraikoN
0 / 0 / 0
Регистрация: 07.08.2012
Сообщений: 14
19.09.2012, 01:28     Нужно оптимизировать готовый код, чтобы не было стыдно показать #1
Мне дали сделать задачку, чтобы проверить мои знания в ООП (я только 2 месяца назад начал изучать С++).
И так, задача:
Определить класс (или структуру данных при использовании процедурного подхода), описывающий покупку одного и того же штучного товара по одной и той же цене (в рублях) в течение одного месяца и содержащий сведения о дне покупки и количестве приобретенных единиц.
Допускаются еще три варианта покупок:
1. со скидкой, задаваемой процентом от стоимости;
2. со скидкой в цене (например, цена товара 5000 руб., скидка 300 руб.);
3. с надбавкой за транспортные расходы на доставку товара.
Создать консольное приложение, в котором последовательно выполнить следующие задания:
– определить набор покупок различного вида (не менее 10);
– вывести на консоль в табличном виде (можно без границ) набор покупок (полный состав атрибутов);
– вычислить и вывести стоимость всех покупок;
– отсортировать покупки по возрастанию дня покупки и вывести их на консоль;
– определить, была ли покупка в десятый день месяца.

Требования:
– Использовать объектно-ориентированный подход для описания покупок.
– Массив или коллекцию покупок инициализировать в коде с помощью конструктора или метода. Как следствие, не использовать внешние источники данных: консоль (т.е. ввод с клавиатуры), файлы, СУБД, XML и т.п.
– Приложение должно быть консольным. Не использовать графический интерфейс! Таким образом, приложение ничего не должно вводить, а только выводить результаты на консоль.

Предпочтения по выбору:
– языка программирования: 1) Java; 2) C++; 3) другой ООП язык.
– реализации сортировки и поиска: 1) интерфейс внешних библиотек; 2) собственный код.
Я написал программу, и теперь прошу Вас проверить ее на "идусость" и подсказать, где можно уменьшить код, где что поменять, чтобы программа выгладила красиво. И мне нужно добавить больше ООП.

собственно исходный код ниже:
Заголовочный файл "shopping_list.h"
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef SHOPPING_LIST_H_
#define SHOPPING_LIST_H_
namespace SHOPLIST
{
    class ShoppingList
    {
    private:
        static const int price = 5000;                      //цена товара
        int dayOfMonth;                                     //день покупки
        int count;
        int discountPercent;                                //скидка задаваемая процентом от стоимости
        int discountPrice;                                  //скидка в цене
        int bonusAllowance;                                 //надбавка за транспортные расходы
    public:
        ShoppingList();                                     //конструктор по умолчанию
        ShoppingList(int day, int discPer, int discPr, int bonus, int cnt); //конструктор
        ~ShoppingList();                                    //диструктор
        int returnDay() const {return dayOfMonth;}          //возвращает значение дня покупки
        int returnPrice() const;                            //возвращает окончательную цену за вычетом процентов и тп
        friend void sortingShList(ShoppingList * t);        //сортировка по возрастанию
        friend void ShowDays(ShoppingList * t);
        friend std::ostream & operator<< (std::ostream & os, const ShoppingList & t);   
    };
    long int amountOfPurchases(ShoppingList * t);
    void Swap(ShoppingList * Arr, int i);
    void checkDate(ShoppingList * t, int day = 10);
    void ShowDays(ShoppingList * t);
    void exitTime(void);                                    //чтобы программа сама закрывалась
}
#endif
файл с функциями "shopping_list.cpp"
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <iostream>
#include <algorithm>
#include <ctime>
#include "shopping_list.h"
namespace SHOPLIST
{
    ShoppingList::ShoppingList()
    {
        dayOfMonth = discountPercent = discountPrice = bonusAllowance = 0;
    }
    ShoppingList::ShoppingList(int day, int discPer, int discPr, int bonusAll, int cnt)
    {
        dayOfMonth = day;
        count = cnt;
        discountPercent = discPer;                              
        discountPrice = discPr;                             
        bonusAllowance = bonusAll;
    }
    ShoppingList::~ShoppingList()
    {
 
    }
    int ShoppingList::returnPrice() const
    {
        return (price * count) - (price * count * discountPercent / 100) - discountPrice + bonusAllowance;
    }
    std::ostream & operator<< (std::ostream & os, const ShoppingList & t)
    {
        os << t.dayOfMonth << "\t" << t.count << "\t" << t.discountPercent
            << "\t\t" << t.discountPrice << "\t\t" << t.bonusAllowance 
            << "\t\t" << t.returnPrice() << std::endl;
        return os;
    }
    void sortingShList(ShoppingList * Arr)
    {       
        int Start, Left;
        Start = Left = 0;
        int N = 15;
        int Right, Last;
        Last = Right = N-1;
        do
        {
            for (int i = Right; i >= Left; i--)         //Сдвигаем к концу массива "легкие элементы"
            {
                if (Arr[i-1].dayOfMonth > Arr[i].dayOfMonth)
                {
                    Swap(Arr, i);
                    Last = i;                           //Запомнить место пследней перестановки
                }
            }
            Left = Last + 1;
            for (int i = Left; i <= Right; i++)         //Сдвигаем к началу массива "тяжелые элементы"
            {
                if (Arr[i-1].dayOfMonth > Arr[i].dayOfMonth)
                {
                    Swap(Arr, i);
                    Last = i;                           //Запомнить место пследней перестановки
                }
            }
            Right = Last - 1;
        }
        while (Left <= Right);
    }
    void Swap(ShoppingList * Arr, int i)
    {
        ShoppingList TEMP;
        TEMP = Arr[i];
        Arr[i] = Arr[i-1];
        Arr[i-1] = TEMP;
    }
    void checkDate(ShoppingList * t, int day)
    {
        int qq = 0;
        std::cout << "\n\nПокупки совершенные в " << day << " день:\n";
        for (int i = 1; i < 15; i++)
            if (t[i].returnDay() == day)
            {
                ++qq;
                std::cout << t[i];
            }
        std::cout << "\nБыло совершено " << qq << " покупок.\n";
    }
    long int amountOfPurchases(ShoppingList * t)
    {
        int SUM = 0;
        for (int i = 0; i < 15; i++)
            SUM = SUM + t[i].returnPrice();
        return SUM;
    }
    void ShowDays(ShoppingList * t)
    {
        std::cout << "\nДень\tКол-во\tСкидка %\tСкидка R\tНадбавка\tЦена\n";
        for (int i = 0; i < 15; i++)
            std::cout << t[i];
    }
    void exitTime(void)
    {
        float secs = 10;
        clock_t delay = secs * CLOCKS_PER_SEC;
        clock_t start = clock();
        while (clock() - start < delay);
    }
}
ну и главный файл main
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <Windows.h>
#include <cstdlib>
#include <ctime>
#include "shopping_list.h"
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    using SHOPLIST::ShoppingList;
    srand(time(0));
    const int NUM = 15;                     //определяется и отображается набор покупок                 
    ShoppingList purchase[NUM];
    int iday, idiscA, idiscB, ibon, icnt;
    for (int i = 0; i < NUM; i++)
    {
        iday = rand() % 30 + 1;
        idiscA = rand() % 80;
        idiscB = rand() % 1000;
        ibon = rand() % 1000;
        icnt = rand() % 10 + 1;
        purchase[i] = ShoppingList(iday, idiscA, idiscB, ibon, icnt);
    }
    ShowDays(purchase);
    std::cout << "\n\nСтоимость всех покупок\n"
              << " с учетом скидок и надбавок за транспортные расходы составило: " 
              << amountOfPurchases(purchase) << " рублей.\n\n";
    sortingShList(purchase);
    ShowDays(purchase);
    checkDate(purchase);
    std::cin.get();
    SHOPLIST::exitTime();
    return 0;
}
Заранее спасибо
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.09.2012, 01:28     Нужно оптимизировать готовый код, чтобы не было стыдно показать
Посмотрите здесь:

C++ Доисать код, чтобы можно было добавлять в список несколько книг
Как сделать в коде программы, чтобы можно было вводить числа самому, а не случайно. (Код прилагается) C++
C++ Нужно оптимизировать код
C++ Нужно сделать, чтобы в Edit можно было вводить не более 3-х символов
Переделать код так, чтобы значения можно было задавать с клавиатуры C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vxg
Модератор
 Аватар для vxg
2663 / 1674 / 157
Регистрация: 13.01.2012
Сообщений: 6,251
19.09.2012, 07:39     Нужно оптимизировать готовый код, чтобы не было стыдно показать #2
- почему класс называется "список" если это фактически одна единственная запись?
- необычно, что цена константное статическое поле. я понимаю, что цена в пределах месяца постоянная, но может в другом месяце она будет другая?
- в конструкторе использовать списки инициализации
C++
1
2
3
4
ShoppingList::ShoppingList(int day, int discPer, int discPr, int bonusAll, int cnt):
    dayOfMonth(day),
    ...
{}
- почему у функции проверки даты значение по умолчанию именно 10 ?
- в функции вычисления цены можно убрать скобки - приоритеты не дадут выражению вычисляться иначе
- в функции оперирующие с массивом нужно передавать его размер - указание волшебного числа 15 внутри - это плохо
- блок ожидания в конце программы можно заменить на system("pause") - во всяком случае если вы работаете под Windows и нажатие клавиши для выхода из программы не считается вводом... функция exitTime в любом случае тяжелая. там должно было быть Sleep, но я подозреваю, что она была сделана так как сделана, что бы быть переносимой на другие платформы. цикл в этой функции будет грузить систему.
- для хранения списка можно использовать не только массив. например, std::list.
- для сортировки списка можно использовать библиотечную функцию qsort. или, если список хранить в std::list определить свою функцию sort
- сделать имена единообразными - они то с большой буквы начинаются, то с малой. некоторые имена набраны большими - обычно это делают для макроопределений.
- осмыслить для себя, что означает имя каждой функции. например, sortingShList - я так понимаю сортированный список, то есть имя формируется по наименованию результата. однако в то же время имеем функцию ShowDays - имя сформировано по производимому действию.
- зачем ShowDays вызывается два раза?
- если используется std::endl, то как правило не используется \n
=
а так вообще нормально.

Добавлено через 10 минут
...больше ООП будет только наверное если вместо массива сунуть std::list и переопределить для него sort.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//res = true - x должен быть расположен перед y
static bool cmp
(
    const ShoppingList * const x, const ShoppingList * const y
)
{
    return x->dayOfMonth < y->dayOfMonth;
}
 
std::list<ShoppingList *> objs;
objs.push_back(new ShoppingList(...));
objs.sort(cmp);
 
//для прохода по списку
for
(
    std::list<ShoppingList *>::iterator i = objs->begin();
    i != objs->end();
    i++
)
{
    if ((*i)->dayOfMonth == ...) ...
}
ну и тогда сделать функцию освобождения памяти перед выходом
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
19.09.2012, 08:59     Нужно оптимизировать готовый код, чтобы не было стыдно показать #3
vxg, для сортировки списка можно использовать библиотечную функцию qsort. или, если список хранить в std::list определить свою функцию sort
Все же использовать std::sort, а для list-а написать всего лишь свой предикат, а не sort ( в сущности для std::sort тоже написать просто свой предикат).
defer
秘密
 Аватар для defer
555 / 235 / 3
Регистрация: 29.11.2010
Сообщений: 783
19.09.2012, 09:03     Нужно оптимизировать готовый код, чтобы не было стыдно показать #4
Цитата Сообщение от ForEveR Посмотреть сообщение
Все же использовать std::sort, а для list-а написать всего лишь свой предикат
Покажите пример предиката для list
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
19.09.2012, 09:04     Нужно оптимизировать готовый код, чтобы не было стыдно показать #5
defer, Дык выше на пост же есть + http://en.cppreference.com/w/cpp/container/list/sort
vxg
19.09.2012, 09:24
  #6

Не по теме:

ForEveR, да, не так выразился, имелось ввиду определение cmp

DraikoN
0 / 0 / 0
Регистрация: 07.08.2012
Сообщений: 14
19.09.2012, 10:21  [ТС]     Нужно оптимизировать готовый код, чтобы не было стыдно показать #7
vxd, спасибо, за такой большой ответ но ты задание не внимательно прочел.
на счет имен, передачи размера массива и тп - я учел, изменил в коде.
а на счет list(), я пока этого не изучил. Ты мог бы отправить меня где обьясняется для чайников, что это и с чем его едят дай ссылочку. А то я нашел пару ресурсов, но пока самому разобраться без примеров не могу.
http://ru.cppreference.com/w/cpp/container/list
http://www.rsdn.ru/forum/src/2261478.1

Можно пример на моем коде привести с использованием list?
vxg
Модератор
 Аватар для vxg
2663 / 1674 / 157
Регистрация: 13.01.2012
Сообщений: 6,251
19.09.2012, 13:20     Нужно оптимизировать готовый код, чтобы не было стыдно показать #8
пример для main

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    std::list<ShoppingList> purchase;
 
    for (int i = 0; i < NUM; i++)
    {
        iday = rand() % 30 + 1;
        idiscA = rand() % 80;
        idiscB = rand() % 1000;
        ibon = rand() % 1000;
        icnt = rand() % 10 + 1;
        purchase.push_back(ShoppingList(iday, idiscA, idiscB, ibon, icnt));
    }
 
    std::cout << "\n\nСтоимость всех покупок\n"
                  << " с учетом скидок и надбавок за транспортные расходы составило: " 
                  << amountOfPurchases(&purchase) << " рублей.\n\n";
пример для функции

C++
1
2
3
4
5
6
7
8
9
10
11
12
    long int amountOfPurchases(std::list<ShoppingList> *t)
    {
        int SUM = 0;
        for
        (
            std::list<ShoppingList>::iterator i = t->begin();
            i != t->end();
            i++
        )
            SUM += i->returnPrice();
        return SUM;
    }
сортировка

C++
1
2
3
4
5
6
7
8
9
10
11
12
//res = true - x должен быть расположен перед y
static bool cmp
(
    const ShoppingList &x, const ShoppingList &y
)
{
    return x.dayOfMonth < y.dayOfMonth;
}
 
...
purchase.sort(cmp);
...
Добавлено через 2 минуты
"изучал" по этому http://mirknig.com/2007/10/01/cc_spr...grammista.html
(качать по ссылке на депозитфайл)
-=ЮрА=-
Заблокирован
Автор FAQ
19.09.2012, 13:30     Нужно оптимизировать готовый код, чтобы не было стыдно показать #9
Цитата Сообщение от DraikoN Посмотреть сообщение
void sortingShList(ShoppingList * Arr)
* * { * * *
* * * * int Start, Left;
* * * * Start = Left = 0;
* * * * int N = 15;
* * * * int Right, Last;
* * * * Last = Right = N-1;
* * * * do
* * * * {
* * * * * * for (int i = Right; i >= Left; i--) * * * * //Сдвигаем к концу массива "легкие элементы"
* * * * * * {
* * * * * * * * if (Arr[i-1].dayOfMonth > Arr[i].dayOfMonth)
* * * * * * * * {
* * * * * * * * * * Swap(Arr, i);
* * * * * * * * * * Last = i; * * * * * * * * * * * * * //Запомнить место пследней перестановки
* * * * * * * * }
* * * * * * }
* * * * * * Left = Last + 1;
* * * * * * for (int i = Left; i <= Right; i++) * * * * //Сдвигаем к началу массива "тяжелые элементы"
* * * * * * {
* * * * * * * * if (Arr[i-1].dayOfMonth > Arr[i].dayOfMonth)
* * * * * * * * {
* * * * * * * * * * Swap(Arr, i);
* * * * * * * * * * Last = i; * * * * * * * * * * * * * //Запомнить место пследней перестановки
* * * * * * * * }
* * * * * * }
* * * * * * Right = Last - 1;
* * * * }
* * * * while (Left <= Right);
* * }
- я бы её написал 1-й строкй через std::sort и friend функцию сравнения для ShoppingList, мне кажется это глупо чтоли юзать продвинутые алгоритмы и до сих пор вот так сортировать, также для всех покупок я бы завёл вектор (в него и добавлять легко и сортировать). Было бы больше времени полностью перекроил бы весь код, он очень раздут, но за неимением такового(времени) могу лишь написать свои мысли...

Добавлено через 1 минуту
Упс, увидел посты 4,5 ну да именно, а для хранения покупок vector
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.09.2012, 18:18     Нужно оптимизировать готовый код, чтобы не было стыдно показать
Еще ссылки по теме:

Какой нужно знать минимум, чтобы уже можно было искать работу по C++ C++
Как преобразовать файл в биты (в нули и единицы), чтобы потом можно было его зашифровать в код Грея? C++
C++ Сделать, чтобы размер массива нужно было вводить с клавиатуры и он заполнялся случайными числами

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
DraikoN
0 / 0 / 0
Регистрация: 07.08.2012
Сообщений: 14
19.09.2012, 18:18  [ТС]     Нужно оптимизировать готовый код, чтобы не было стыдно показать #10
Друзья, всем спасибо
Узнал, что такое list()
И за справочник отдельное спасибо vxg
Yandex
Объявления
19.09.2012, 18:18     Нужно оптимизировать готовый код, чтобы не было стыдно показать
Ответ Создать тему
Опции темы

Текущее время: 08:29. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru