![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| ТарасАтавин |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 370 Регистрация: 26.8.2013 Репутация: нет Всего: нет |
Дан приблизительно вот такой: "<tab>1552</tab><variable>y</variable><LeftAssigneOperator><fraction><numerator><function>sin</function>(<variable>x</variable>)</numerator><denominator><function>cos</function>(<variable>x</variable>)+<fraction><numerator>3</numerator><denominator>2</denominator></fraction></denominator></fraction>" код формулы. Здесь <tab></tab> - тег табуляции в пикселах, <LeftAssigneOperator> - тег стрелки влево (вместо знака равенства), а всё остальное - xml код правой части. <fraction></fraction> - тег дроби, <numerator></numerator> - тег числителя, <denominator></denominator> - тег знаменателя, <function></function> - тег идентификатора функции, а <variable></variable> - тег идентификатора переменной. Не дробные члены выражения вне дроби следует разместить посередине между строками числителя и знаменателя. Ниже и выше могут быть другие строки. Пока дробь двухэтажная, проблем нет, но как только в числителе, или знаменателе тоже есть дроби, то соседние строки налазят на них. Как оценить количество этажей дроби и отдельно её числителя и знаменателя и как в связи с этим выставить вертикальные смещения фрагментов формулы?
Это сообщение отредактировал(а) ТарасАтавин - 30.8.2013, 09:19 -------------------- Не так всё плохо, как оно есть на самом деле. |
|||
|
||||
| ТарасАтавин |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 370 Регистрация: 26.8.2013 Репутация: нет Всего: нет |
-------------------- Не так всё плохо, как оно есть на самом деле. |
|||
|
||||
| ТарасАтавин |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 370 Регистрация: 26.8.2013 Репутация: нет Всего: нет |
Проблема дроби в знаменателе была в том, что сбивала высота номера, выводимого после самой строки. А вот если эта же строка закодирована так: "<tab>1552</tab><variable>y</variable><LeftAssigneOperator><fraction><numerator><function>sin</function>(<variable>x</variable>)+<fraction><numerator>3</numerator><denominator>2</denominator></fraction></numerator><denominator><function>cos</function>(<variable>x</variable>)</denominator></fraction>", то получается
![]() вместо ![]() . И здесь проблема именно в высоте числителя. Как её заранее оценить до начала вывода выражения и как обработать? Это сообщение отредактировал(а) ТарасАтавин - 30.8.2013, 10:29 -------------------- Не так всё плохо, как оно есть на самом деле. |
|||
|
||||
| akizelokro |
|
|||
![]() Крокодил ![]() ![]() Профиль Группа: Участник Сообщений: 761 Регистрация: 30.7.2007 Репутация: 1 Всего: 5 |
Делай класс "Выражение" вида
class Expression { .... bool _fraction; // флаг, дробь или выражение в строку bool isFraction() {retrun _fraction; }; Expression * numerator; // что в числителе // аналогично для знаменателя, указатель на выражение. в случае если выражение не дробь оба эти указателя NULL long getHeight() { int numeratorHeight = 0; if(numerator) numeratorHeight = numerator->getHeight(); // рекурсия, о которой ты вчера упоминал. и заодно сделаешь код, который можно будет потом юзать много раз ..... дальше если ссылка на знаменатель не NULL а дальше либо суммируешь высоты для числителя и знаменателя, либо если вообще не дробь, вычисляешь просто высоту выражения } } сначала парсишь выражение, если дробь, по идёшь парсить по дереву перебора, пока не дойдёшь до конца. создаёшь все нужные экземпляры класа Expression, дальше их юзаешь можешь всё это сделать и через функции без классов, но в коде погрязнешь просто. В смысле, дроби у тебя могут быть и "многоэтажные", мой подход это учитывает. Это сообщение отредактировал(а) akizelokro - 30.8.2013, 11:11 -------------------- a = a + b; b = a - b; a = a - b; |
|||
|
||||
| akizelokro |
|
|||
![]() Крокодил ![]() ![]() Профиль Группа: Участник Сообщений: 761 Регистрация: 30.7.2007 Репутация: 1 Всего: 5 |
И лучше вообще СSize выдавать, а не отдельно высоту
-------------------- a = a + b; b = a - b; a = a - b; |
|||
|
||||
| ТарасАтавин |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 370 Регистрация: 26.8.2013 Репутация: нет Всего: нет |
Ничего не понял.
-------------------- Не так всё плохо, как оно есть на самом деле. |
|||
|
||||
| akizelokro |
|
|||
![]() Крокодил ![]() ![]() Профиль Группа: Участник Сообщений: 761 Регистрация: 30.7.2007 Репутация: 1 Всего: 5 |
Что тут непонятного? В числителе и знаменателе могут быть в свою очередь дроби. Значит, вопрос свести математическое выражение не к последней по счёту элементарной дроби, а к однострочному выражению, которое, к тому же, может быть частью дроби.( А может и не быть.) То есть задача такая, чтобы найти такую модель построения классов выражений, чтобы всё хорошо описывалось. Представим, что дробь - однострочный объект, но разделённый на два "этажа", числитель и знаменатель. Которые в свою очередь однострочные объекты и могут быть дробями в свою очередь, по нашей терминологии однострочными объектами, разделенными на два этажа. Ферштеен? Абстрагируешься от того, что числитель и знаменатель это строки, рассматриваешь их как этажи. Сама дробь - это, к примеру дом, а знаменатель - первый этаж, числитель второй этаж. Дальше предполагаешь что, числитель не просто этаж, а ещё и дом, в котором тоже может быть два этажа. И так далее, хоть до бесконечности. То есть, тебе в самом первом объекте дома нужен логический флаг, определяющий, что "дом" это не просто "дом", а двухэтажный дом. И адреса-номера этажей, в моей модели это указатели на объекты. (Если этажей нет, то указатели равны NULL)/ Модель вложенных поэтажно друг в друга двухэтажных домов. Добавлено @ 12:06 В принципе, так можно построить и многомерные аналоги дробей. Чего уж мелочиться? Это сообщение отредактировал(а) akizelokro - 30.8.2013, 12:07 -------------------- a = a + b; b = a - b; a = a - b; |
|||
|
||||
| ТарасАтавин |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 370 Регистрация: 26.8.2013 Репутация: нет Всего: нет |
1. Ну и как это будет выглядеть? 2. Что оно будет значить? Допустим. А какова здесь роль класса? -------------------- Не так всё плохо, как оно есть на самом деле. |
|||
|
||||
| ТарасАтавин |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 370 Регистрация: 26.8.2013 Репутация: нет Всего: нет |
Проблема решена рекурсивными функциями:
-------------------- Не так всё плохо, как оно есть на самом деле. |
|||
|
||||
| akizelokro |
|
|||
![]() Крокодил ![]() ![]() Профиль Группа: Участник Сообщений: 761 Регистрация: 30.7.2007 Репутация: 1 Всего: 5 |
Роль класса здесь свелась бы к элементарному упорядочиванию. .и развитию на перспективу. Потому что в класс можно было бы не только навесить метод определения выражения, но и другие полезные методы. Например, рисование части дроби. Также, класс бы дал хорошую возможность не слишком загружать код при увеличении "уровней дроби" или сложности выражения. На простом примере, степень в подстроке, в которую возводится частичная дробь. или корень Квадратный. А то и интеграл. -------------------- a = a + b; b = a - b; a = a - b; |
|||
|
||||
| ТарасАтавин |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 370 Регистрация: 26.8.2013 Репутация: нет Всего: нет |
Степень здесь не уместна из-за неоднозначности поведения в области отрицательных чисел, что оставляет функцию в качестве единственно допустимого обозначения степени. Корень - та же степень. А нижний индекс будет. Но я не вижу препятствий против его реализации в процедурной парадигме. Зато они отлично видны именно в объектной.
-------------------- Не так всё плохо, как оно есть на самом деле. |
|||
|
||||
| akizelokro |
|
|||
![]() Крокодил ![]() ![]() Профиль Группа: Участник Сообщений: 761 Регистрация: 30.7.2007 Репутация: 1 Всего: 5 |
Времени бы ушло примерно одинаково. Зато с классами можно делать задел для будущего. Раз ты уж сразу не захотел использовать никакую библиотеку. Получается, что ты вместо возможности сделать хороший задел для чего-то большего, ограничился меньшим. Хотя затраты времени были те же самые. -------------------- a = a + b; b = a - b; a = a - b; |
|||
|
||||
| ТарасАтавин |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 370 Регистрация: 26.8.2013 Репутация: нет Всего: нет |
Я делаю сразу то самое большое без задела на переделку. Все ограничения логичны и естественны. Та же степень. Обозначить её верхним индексом можно только одним способом, функции покрывают всё разнообразие степеней. А как степень с действительным показателем должна вести себя при отрицательном основании? Не так уж это однозначно. Поэтому функция. Нижний же индекс в значении "индекс элемента массива" ни чем таким не страдает. А вот с классами будет или супер ограничение "в правой части только дроби и ни каких операций", или сотни рефакторингов с топтанием на месте, потому что они здесь ни чего полезного не добавляют к тому, что проще делается в процедурной парадигме. Это сообщение отредактировал(а) ТарасАтавин - 3.9.2013, 06:09 -------------------- Не так всё плохо, как оно есть на самом деле. |
|||
|
||||
| akizelokro |
|
|||
![]() Крокодил ![]() ![]() Профиль Группа: Участник Сообщений: 761 Регистрация: 30.7.2007 Репутация: 1 Всего: 5 |
В какой такой процедурной парадигме? С одного момента начинается полный завал, когда количество функций превышает определенное число. Классы позволяют их группировать и достаточно удобно менять. И ты меня не понял. Я тебе говорил про какую модель? Про формально однострочные выражения. если у тебя "а + дробь", то а парсится как однострочное выражение, для плюса ты можешь оператор сделать со своеобразным поведением, или приписать как данные в класс (сам придумай как, это уже мелочи). Дробь же парсится дальше на класс выражения, в котором есть указатели на числитель и знаменатель (которые в свою очередь экземпляры класса однострочного выражения). И так там рекурсивно доходится до конца. И когда появляется четырехэтажная дробь (видел и такие), то там разбираться она будет на основе уже написанного кода, а не придётся всё переписывать и переделывать -------------------- a = a + b; b = a - b; a = a - b; |
|||
|
||||
| ТарасАтавин |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 370 Регистрация: 26.8.2013 Репутация: нет Всего: нет |
Добавлено @ 07:08 Как вообще можно классом что либо делать с функциями вне самого класса? Попутка же свалить в класс не относящиеся к нему функции вызовет завал уже на первой такой функции и разгрести его будет не возможно. К тому же по требованию задачи все фигурирующие в выражениях функции должны быть даже вне самого проекта. Это сообщение отредактировал(а) ТарасАтавин - 3.9.2013, 07:10 -------------------- Не так всё плохо, как оно есть на самом деле. |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |