Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Для новичков > Задачки для новичков! |
Автор: EnShTe1N 9.12.2007, 23:39 |
Думаю подойдут такие задачи для тренировки!!! Исходные данные вводятся с клавиатуры, а результаты выводятся на экран. Все числа - целые, не превышают по модулю 2 в 31 степени - 1.(Соответственно, они помещаются в переменные типа int) В программах, где это необходимо, следует использовать условный оператор if и оператор цикла while. Другие операторы цикла(for, repeat, do - while), а также другие операторы break, continue, exit, goto использовать не следует. 1. Дано трехзначное число. Найдите число, которое получится, если цифры исходного числа переписать в обратном порядке. 2. Даны переменные a и b. Напишите программу, которая будет менять значения этих переменных местами. 3. Найдите x в степени 4, выполнив наименьшее возможное число умножений. То же самое для 5. x в степени 7. 6. x в степени 22. 7. Даны 2 числа. Вывести наибольшее из них. 8. Даны 3 числа. Вывести наибольшее из них. 9. Даны 4 числа. Если они все различны, выведите "yes", иначе - "no". 10. Определите количество дней в данном году (от 1600 до 3000 года н.э.) по современному календарю 11. Выведите на правильном русском языке, сколько прошло лет с указанного года (между 1 и 2006 годом н.э.) до 2007г. Например, если введено 1986, то надо вывести "21 год", а если 2002, то "5 лет". 12. Даны размеры сторон конверта и открытки. Определите можно ли положить открытку в конверт не сгибая. (Стороны открытки должны быть параллельны сторонам конверта). 13. В первой строке указаны дата рождения Алисы, а во второй - Боба. Даты указаны в формате "год месяц день". Определите кто из низх старше(выведите имя: "Alice" или "Bob"). 14.Положение коня на шахматной доске задано двумя числами - номерами вертикального и горизонтального рядов.(Ряды нумеруются от 1 до 8) Найдите количество клеток, которые находятся под боем этого коня. 15. Вычислите: a в степени b, b >= 0. 16*.Крестики - нолики. Вася и Петя любят играть в крестики - нолики 3х3, но у них неожиданно закончилась бумага. Помогите им - напишите программу, которая позволит им ставить крестики и нолики на экране монитора. Вроде бы все! Скоро будет продолжение!!! |
Автор: zkv 9.12.2007, 23:45 |
для желающих потренироваться у нас целый полигон есть: http://forum.vingrad.ru/forum/Vingrad-help-center.html задач на всех хватит, особенно сейчас (период такой, сами понимаете ![]() Пропиарил. Хе-хе. |
Автор: EnShTe1N 10.12.2007, 00:18 |
ну, мож каму интересно будит! |
Автор: zvezda 12.12.2007, 09:57 |
Help/Срочно нужна прога. Пожалуйсто помогите кто может. Вариант №5: Для всех заданий необходимо разработать программу, которая создает файл размером, указанным в варианте виртуальной памяти и заполняющая его некоторыми данными. 1. Разработать менеджер памяти, у которого следующие параметры: Виртуальная память - 8М; Количество страничных кадров - 16; Размер страничного кадра - 4К; Менеджер памяти должен работать в начале по алгоритму по требованию, а после заполнения страничных кадров по алгоритму LRU. 2. Необходимо вывести на экран значение ячейки памяти, адрес которой вводится пользователем. Страница памяти и смещение необходимой ячейки, вычисляется и выводится на экран. Если страница уже загружена в память, необходимый элемент выводим на экран, иначе нужную страницу загружаем в память. Менеджер памяти необходимо реализовать через классы. |
Автор: pompei 12.12.2007, 11:06 |
2. обменять значения переменных a и b a = a ^ b; b = b ^ a; a = a ^ b; где ^ - побитовая операция "исключающее или" . |
Автор: MAKCim 12.12.2007, 13:21 | ||
zvezda,
|
Автор: Silent_s 14.12.2007, 22:17 |
Прикольные задачки!) А они для личного обдумывания? ![]() |
Автор: baldina 15.12.2007, 20:44 |
pompei, а если это переменные типа SuperPuperClass? И перегруженного оператора ^ нет (а если есть, может он работает тоже как-то super puper) |
Автор: EnShTe1N 16.12.2007, 10:08 | ||
Silent_s, если что будет не понятно, то можеш спрашивать. А так постарайся решить сам |
Автор: Silent_s 16.12.2007, 11:09 |
Ну пару месясев когда начал учить си большую часть подобных задач делал, только вот последнюю не знаю, там же функции из графики есть подскажите какие использовать... |
Автор: Чoо 11.9.2010, 22:23 | ||
Введите с клавиатуры 10 чисел. Затем выведите сначала одно самое большое, потом 2 самых больших и, наконец, 3 самых больших. Можно использовать циклы, условную инструкцию if ... then ... else и переменные типа int. Больше ни чего ![]() решение(может кривое, но лучше не придумал):
жаль спойлера нет. |
Автор: Чoо 15.9.2010, 22:07 | ||
вот еще одна задача. Определите функцию, которая возвращает ссылку на хотя бы один седловой элемент матрицы или NULL (NIL), а также "координаты" на этот узловой элемент (седловым элементом называется элемент, который наименьший в своей строке и одновременно наибольший в своем столбце (и наоборот)). Для решения, я решил разработать алгоритм поиска самостоятельно. Возможно, что он не самый оптимальный (но лучше не придумалось, а готовые решения искать - это уже не тренировка). Суть его в следующем: Сначала ищется в строке минимальный элемент. Если он будет найден, то в колонке, в которой находится этот элемент, ищется уже максимальный элемент. Если минимальный элемент строки и максимальный элемент столбца ссылаются на один и тот же элемент матрицы - то седловой элемент найден. Иначе поиск продолжается со следующей строки. И т.д. пока не пройдем все строки. Если все строки прошли, но седловой элемент не найден, то повторяем поиск от первой строки, только теперь ищем максимальный элемент в строке и минимальный в столбце. Как только найдем первый седловой элемент возвращаем указатель и координаты седлового элемента.
|
Автор: djamshud 16.9.2010, 00:19 |
Чoо, тут простаки напрашивается кеширование максимальных значений столбцов. Код не смотрел, что-то его очень много. |
Автор: Чoо 16.9.2010, 00:48 |
djamshud, мне тоже кажется, что кода очень много ![]() |
Автор: djamshud 16.9.2010, 13:06 |
Чoо, кешировать - т.е. не пересчиитывать каждый раз максимум для столбцов, т.к. в вашем примере, как я понимаю, для одних и тех же столбцов максимумы могут пересчитываться на каждой итерации. |
Автор: Чoо 16.9.2010, 18:43 |
djamshud, да, правильно поняли. Максимум каждый раз пересчитываю. что ж.. переделаю ![]() |
Автор: Чoо 19.9.2010, 16:54 | ||
Следующая задача. Нужна помощь. Кажется, что решил ее слишком криво. Звучит так: Заполнить кольцевой список. Создать функции: Подсчета количества элементов в списке, вывода списка на экран, очистки списка и функцию удаления по одному элементу. С кольцевыми списками ни когда не работал, не было необходимости, но все же как-то решил задачу. Собственно реализация:
|
Автор: vnf 19.9.2010, 17:02 |
я бы всё в класс упаковал, привыкайте к ООП |
Автор: Чoо 19.9.2010, 17:29 |
vnf, спасибо за замечание, я бы тоже упаковал (если б на паскале писал). Просто в с++ пока не дошел до раздела, посвященному ООП - стараюсь материал осваивать последовательно ![]() |
Автор: Чoо 11.11.2010, 13:36 | ||||
снова я.. вернулсо.. отсортировать массив слиянием по следующему алгоритму:
. Вобщем данного алгоритма я придерживался (потому что если точно его следовать, то сортировка проводилась корректно, только если количество элементов в исходном массиве было кратно степени двойки). Кода получилось много, но работает ![]()
на всякий я всё подробно откомментировал. Следующим этапом буду сортировать строки в текстовом файле(надо бы обойтись тремя файлами). |
Автор: baldina 12.11.2010, 12:46 |
bsa, а если строк в файле так много, что массив, хранящий индексы на строки исходного файла не помещается в память? |
Автор: Чoо 12.11.2010, 12:51 |
все верно. Если считывать в память, то файл можно отсортировать и более эффективно по скорости, однако файл может не поместиться в оперативку. С индексами интересней, но был бы смысл, если бы они уменьшили количество операций ввода вывода. И кода будет больше... Ща, я уже почти написал ![]() |
Автор: Чoо 12.11.2010, 14:28 | ||||
работает ![]() вообще думал что не справлюсь, так как сначала видел решение с использованием 4х файлов. эт потом понял как чо ![]() ... добавил. А можно измерить скорость, если главную процедуру переписать следующим образом?:
результат близок к правде, вот только смущает число после запятой (мерил секундомером, целая часть - совпадает с тем, что выдает программа). на сортировку 3'163'420 строк тратится (28,684137s). И да.. так кажется, что работа с файлом происходит не напрямую, как я ожидал, а через какой-то буфер. Сделал такой вывод, потому что светодиод, сигнализирующий обращение к жесткому диску, лишь изредка моргал и не было характерного "треска". |
Автор: Чoо 13.11.2010, 13:15 | ||
Дан большой текстовый файл с длиной строк не более 100 символов. Распечатайте 15 последних строк файла
|
Автор: Чoо 13.11.2010, 17:21 | ||
еще задача.. Нужна помощь..
Для того, что бы воспользоваться алгоритмом бинарного поискА, мне нужно знать количество строк в файле, а так же уметь позиционироваться на нужную строку в файле. Если я, что бы получить количество строк в файле, буду все их считывать, начиная от первой, возникает вопрос: смысл бинарного поискА, если я и так уже перебрал все строки. Так же, что бы установить указатель на нужную строку, мне нужны индексы (смещения) строк. Намекните, куда копать, если не трудно.. |
Автор: bsa 13.11.2010, 23:24 |
Чoо, ты с базами данных не работал? Особенно, от 1C: Предприятие. Так вот, там есть такая вещь, как индексные файлы. Т.е. файл содержащие индексную информацию о базе. Тебе нужно сделать такой же. Для этого необходимо сначала полностью прочитать словарь... |
Автор: Чoо 14.11.2010, 00:19 |
bsa, с базами данных работал (из серъезных - c firebird). Я вот еще перечитал ваше сообщение, про сортировку большого файла, с использованием индексом. Вобщем начал делать, но там возникли вопросы. Поскольку заранее неизвестно количество строк, то и память выделить по ходу считывания строк - не получится (во всяком случае с массивами как это сделать я не знаю пока что), разве что используя списки, что в принципе и делаю. Может так же тогда поступить: сделать индексный файл, затем считать его в массив и приступить к сортировке? Соотв. в этой задаче: сформировать индексный файл, считать его в массив, приступить к поиску? Если всё понял правильно, то где разместить информацию о количестве проиндексированных строк(по интуиции, разместил бы первой записью)? |
Автор: bsa 14.11.2010, 02:36 | ||||||
это очень медленно. Ты, надеюсь, знаешь, что случайный доступ к элементам списка невозможен с такой же скоростью, как к элементам простого массива?
Количество строк равно количеству записей в индексном файле. Размер записи известен (4 или 8 байт). Путем нехитрого деления можно получить количество строк. Размер файла можно узнать используя: filesize = lseek(file, 0, SEEK_END);
совсем не обязательно - он тоже может в память не поместиться. Ты должен будешь сортировать индексы прямо в файле. |
Автор: Jmylia 14.11.2010, 02:42 | ||||||||||||||||||||||
В этом году поступил в универ, на первом курсе учим С++, вот решил посмотреть что у вас тут за инструктажи и попал на задачки... В общей сложности С++, не сказал бы что учил, но пытался, 2 месяца. Вот решения ваших задач, нарешал за этот вечер, начну с тех что решил:
Решение:
Что бы не расписовать три задачи, решил написать три в одной:
Восьмую не делал, сделал только седьмую, исходник ниже, в восьмой тоже самое только еще дописать число d и два условия if (a<d<b) и вот такое if (d<d<a) ну для большей четкости еще можно if (a=b=d)
Решение:
Решение:
Теперь те что не решил: первая, мы как бы такого ен проходили, но думаю с ней проблем не будет, 9-ю почти решил, только ошибки поисправлять, чучуть не хватило времени, 10 не совсем понял, да и не понял как подсчитать дни. если например год высокостный, и как задать такой алгоритм? Вот №12 интерестная, а если брать длину конверта и открытки в числах, и их ввести с клавиатуры и задать такое что если (припустим длина конверта а а длина открпытки б), а>b вывсти на экран ответ, открытку можно вложить не згиная, но если a<b то вывести что нужно згинать, а еще было бы интереснее если нужно было учитывать и высоту конверта с открыткой - дополнительный цыкл... Над 13 и 14 нужно подумать, не хотелось, думаю завтра буду решать, а 16-я бомба, нас не учили подключать графику, мы пишем только примитивные калькуляторы!) Добавлено через 4 минуты и 32 секунды Прокоментируйте пожалуйста мои решения и еще назрел такой вопрос: как правильно выводить отображения целого числа? Потмоу что я использую значение %lf, другие, компилятор не хочет принимать (например %i или %d, может их нужно подключить, тогда как?) и выводи на монитор ответ целого числа в виде x=19.00000 b=271.00000 Как сделать что бы целые числа были без точки в виде: x=19 b=271 Спасибо!) |
Автор: Crafty 14.11.2010, 02:58 |
А где здесь С++? У вас тут сплошной С. |
Автор: Jmylia 14.11.2010, 12:16 | ||
Упс, это я перепутал, первый семестр, учим С, это второй семестр С++ Говорите полностью на С ... А ошибки какие-то есть? Правильность и логичность написания программы присутствуют? |
Автор: bsa 14.11.2010, 15:05 | ||||||
Jmylia, ты халтурщик и сачок! Я конечно рад, что ты знаешь стандартную библиотеку, но тут задания не на эти знания, а на знание математики и основ программирования.
решение в одну строчку.
... используя только умножение. |
Автор: Чoо 14.11.2010, 21:26 | ||||||
просто не знал про эту функцию. В учебнике до постановки задачи эта функция не рассматривалась. Стараюсь метериал усваивать последовательно. Хотя, уже начинаю чувствовать, что надо искать справочники. Без них ни как...
да, задумался вчера со списками. Поэтому приостановил вчера решение задачи. В данном случае, проблема списка будет заключаться в том, что что-бы перейти скажем к среднему элементу, надо будет последовательно перебрать все другие элементы (в любом направлении, если список двусвязный). Вычислить адрес памяти нужного элемента - не возможно. Другое дело массив. Нужен 10й элемент массива, хранящий элементы типа long, очевидно, что адрес этого элемента будет: адрес нулевого + 10 * 4. Хотя и адрес высчитывать не понадобится, все за нас сделает компилятор. правильно понял, на счет скорости? ![]() да.. не подумал просто..
ага, понял, спасибо. Сортировка в файле почти не будет отличаться от сортировки в памяти, поскольку размер каждого индекса одинаков. Завтра попробую предоставить решение двух задач: последней и с сортировкой большого файла по вашему методу. ** кстати, как вам решение задачи http://forum.vingrad.ru/index.php?showtopic=186246&view=findpost&p=2246278 ? |
Автор: bsa 14.11.2010, 23:51 | ||||
да
|
Автор: Dov 15.11.2010, 02:32 | ||||
Ещё вариант:
|
Автор: Dov 15.11.2010, 02:49 |
bsa, по-моему, он просто прикалывается... ![]() |
Автор: Dov 15.11.2010, 03:18 | ||||||
попробуем...
возможно и так, но не обязательно, достаточно знать размер файла. ![]()
![]() ![]()
тут думать надо... ![]() думаю, можно так попробовать: * устанавливаем левую и правую границу(или нижнюю и верхнюю, как тебе хочется). * далее в цикле(пока левая меньше правой): * находим середину файла(это может быть и середина слова) * смещаемся в начало слова и проверяем его * если совпало, то выводим сообщение, что нашли и завершаем прогу, иначе * устанавливаем(смещаем) новые границы поиска * выводим сообщение, что не нашли и завершаем прогу Вроде всё... ![]() Добавлено через 2 минуты и 9 секунд У меня есть одна мысля. Если что, завтра (уже сегодня, но к вечеру) покумекаю... |
Автор: Чoо 15.11.2010, 09:52 | ||||
мм.. вижу реккурсию ![]() пока что данный вариант что-то не заработал, еще подумаю над этим. на терминал выводит такую непонятную вещь и очень много:
хотя вот получение количества строк мне тут не нравится: sCount(in, s_count); (перебор каждой строки). Хотел время вывода строк из текстового файла размером в 25 мб замерить по-быстрому, сравнить, но пока не получилось ![]() поспорю ![]()
ну зная индекс строки - установить указатель на нее не вопрос конечно ![]() Над приведенным ниже алгоритмом подумаю чуть позже, уже в универ сильно опаздываю ![]() |
Автор: Чoо 15.11.2010, 15:04 |
а.. ну не работало, потому что я по-невнимательности указал не файл, а директорию, в которой он находится. Однако из рекурсии программа не выходит почему-то. Пишет Segmentation fault. что-то в рекурсии не то. Заменил ее на цикл while с предусловием - всё ок. примерно 0,7 секунд тратится на поиск и вывод последних 15 строк (всего строк 3 163 420 В моем решении 0,125. ну это естественно, так как я не перебираю все строки. Осталось разобраться почему рекурсия не пошла. ну да, поторопился спорить. но все-равно, как я пойму, что нахожусь не в начале строки? |
Автор: Dov 15.11.2010, 21:32 | ||
Может ты чего-то в функциях изменил? Попробуй такой вариант, без рекурсии:
Я, правда, особо не тестил, но если что, можно подправить. |
Автор: Dov 15.11.2010, 22:11 | ||
По поводу бинарного поиска в файле. Вот примерчик, нужно потестировать, ибо руки не дошли. Немного коряво написал, наверняка там что-то нужно доделать, но думаю, что направление ты поймёшь. Что-то бестолковка сегодня совсем не варит... из-за жары, наверно.
|
Автор: Чoо 15.11.2010, 22:25 | ||||||
да не, ни чего не менял, кроме пути к файлу. Может какое-то ограничение на количество точек входа? (я такое вообще не встречал). Вобщем суть в чем: маленький файл если взять, то в рекурсию входит и так же норм выходит ![]() Второй вариант чуть позже потестю. По поводу бинарного поиска. Так же гляну позже - в принципе по словесному описанию понял куда копать. Спасибо. Задачу хочу решить сперва сам, пусть хоть и будет криво.. Но пока решать даже и не начал. Что-то с индексами напутал в задаче с сортировкой большого файла. Точнее даже не с индексами.. вот функция открытия файла:
ну и собственно вызов, при котором возникает ошибка:
а если в вызывающей функции сделать так:
то ни какой ошибки не возникает. Я уже час пытаюсь понять в чем прикол.. Может нельзя выделять память в одной функции, а освобождать в другой (get_full_patch и OpenFile)? (про это еще не читал). |
Автор: Dov 15.11.2010, 22:40 |
Вот это правильно, давай работай. Потом расскажешь. Удачи!!! |
Автор: Чoо 15.11.2010, 22:41 |
вообще суть существования последних двух функций в том, что нельзя сформировать полный путь к файлу из составных частей при вызове функции fopen. Может есть, да я не знаю и изобрел вот эти вот костыли... Добавлено через 41 секунду спасибо ![]() |
Автор: Чoо 16.11.2010, 11:11 | ||||||
по поводу ошибки при освобождении памяти. Удивительно, что ошибки не возникают при определенных условиях.
А атк причина ошибки в том, что память выделялась по одному адресу, а освободить я пытался по другому. я думал, что после return dest fullpatch будет указывать на тот же участок памяти, что и dest. ** ни как не получается. пробовал убрать вышенаписанную функцию, а действия из нее перенести в вызывающуюю ее функцию. Все равно таже ошибка при попытке освободить память и при тех же условиях.
подскажите плз, как можно передать в функцию fopen составной путь (состоящий из пути к файлу и его имени)? *** о.. пошло.. как раз тогда когда собрался сдаться... ошибка в строке
в итоге переполнение массива, та как я не выделил память под нулевой символ. => кривое освобождение памяти |
Автор: Чoо 16.11.2010, 18:09 | ||
сделал я задачу сортировки большого файла с использованием индексов. Честно говоря расстроен, так как на сортировку затрачено времени примерно раз в 5 больше (153,755 сек против 28-29 сек без индексов). Отметки времени еще не расставлял, что бы узнать на каком этапе требуется много времени. вот решение с индексированием:
думаю можно ускорить программу за счет неполного считывания строки при сравнении двух строк по индексу. Хотя прирост скорости в этом случае будет не большим. Кажется, что львиная часть времени уходит на считывание строки по индексу. |
Автор: bsa 16.11.2010, 18:22 | ||
Не поможет. Так как из файла читается минимум 1 кластер (2-4 КБ). |
Автор: Чoо 16.11.2010, 18:41 |
логично.. да. снова не подумал я. А это нормально, что так скорость упала или это я что-то криво написал? ![]() |
Автор: bsa 17.11.2010, 00:40 |
Если ты сравниваешь с вариантом "полная загрузка в память", то нет ничего удивительного. Если же до этого ты сортировал как-то иначе из файла в файл, то удивительно. |
Автор: Чoо 17.11.2010, 00:47 |
bsa, я сравнивал с вариантом, когда делил исходный файл пополам (точнее на две половины), а потом эти половины сливал снова в один файл. Добавлено через 56 секунд вот с этим: http://forum.vingrad.ru/index.php?showtopic=186246&view=findpost&p=2246278 ![]() |
Автор: bsa 17.11.2010, 00:56 |
вот только как при этом ты уложился в 3 файла? |
Автор: Чoо 17.11.2010, 01:07 |
bsa, в смысле как? в один момент времени существовало не более 3х файлов: file_a, file_b и f. после распределения f по первым двум f можно было затирать... Я сейчас подумал над временной сложностью для последнего решения (первое сейчас еще пересмотрю). Если все учел правильно, то за одну фазу происходит N считываний при делении индексного файла на две части, N считываний из индексного файла (уже половинок, а не целого файла) при слиянии и еще N считываний из сортируемого файла, опять же во время слияния. В итоге имеем утроеное N. И так, полное рассчетное время будет выглядеть как: T = const * 3N * log2n Там где log2 - 2 нижним индексом. Время на получения индексного файла я не учитывал - разовая операция. Занимает примерно секунду при 3х миллионах строк. Добавлено @ 01:11 в первом решении T = const * 2N * log2n. Значит можно быстрее сделать, так как достаточно одного просмотра строк на каждом этапе. странно... может я неправильно считаю временную сложность, так как в этом случае скорость сортировки должна бы была упасть только в 1,5 раза, но не в 5 |
Автор: bsa 17.11.2010, 11:09 |
Чoо, в первом случае у тебя была последовательная работа с файлами. А во втором - случайный доступ. Он хуже ускоряется буферами, чем первый. |
Автор: Чoо 17.11.2010, 12:12 |
bsa, ааа... теперь понятно, спсибо за помощь. ** ну раз с данной задачей справились, перехожу к следующей, а именно: к бинарному поиску. Если успею, сегодня напишу решение ![]() |
Автор: Чoо 17.11.2010, 20:40 | ||||
поиск производится шустро ![]() Сейчас рассмотрю вариант, что предлагали выше ![]() |
Автор: Чoо 17.11.2010, 22:15 |
Dov, ваш вариант интересней будет. разобрал его. У меня слишком много кода и всё усложнено как-то. |
Автор: Dov 18.11.2010, 00:22 | ||||
Эт точно. Такое количество кода трудно переваривать, а то, что комментируешь это хорошо. Вот интересный момент:
Зачем так сложно? ![]() Вот немного переделал, вроде так попроще:
|
Автор: Чoо 18.11.2010, 01:11 | ||
можно было еще сделать как в главной функции Main ![]() обязательно разберу чуть по-позже, неясности кое-какие есть (в принципе пошагово проверить не проблема, потому не спрашиваю ![]() комментарии... ну с ними проще как-то.. Когда-то пренебрегал подробными комментами, пока не понадобилось "ковырять" старые проекты Добавлено @ 01:12 кстати вот не знал, что так можно:
конечно разобрал что к чему, но такую запись не видел еще ![]() |
Автор: Dov 18.11.2010, 10:04 | ||||
Чoо, я не про это говорю. Зачем сравнивать строки(), если можно сравнить символы?
|
Автор: Чoо 18.11.2010, 16:01 | ||||||||||||
Dov,
так надо? ![]() **добавил** Dov, разобрался с исходником. Меня смущало, что в цикле:
вы отнимали 2, а не единицу. Возникли вопросы почему так. В отладчике посмотрел: у меня русские буквы кодируются двумя байтами (вопрос - почему? В принципе догадываюсь: поскольку работаю в юникоде, русские буквы кодируются двумя байтамИ, а английские одним. Верно?),и, в принципе, программа не выходила за пределы строки. Если же англоязычный словарь, то получалось, что mid мог перейти и на предыдущую строку и продолжить перемещаться назад. и программа просто висла. пример словаря:
ищем слово ebel. Если декрементировать mid, то всё ищет и не виснет. и еще сократил:
до
**добавил**
сообразил... это потому что у меня словарь в юникоде ![]() |
Автор: Чoо 22.11.2010, 18:21 | ||||||||
мое решение:
правда я не понимаю предупреждение:
почему преобразование устаревшее, и как сделать неустаревшим ![]() Добавлено через 56 секунд это ругается на
и все вызовы метода print |
Автор: bsa 22.11.2010, 18:24 | ||
Должно быть:
|
Автор: Чoо 22.11.2010, 22:33 | ||||
bsa, оказывается все просто ![]() вот еще одну задачу решил:
можно было бы сделать еще метод принт, что бы не было безобразия с выводом координат прямоугольников ![]() |
Автор: Чoо 23.11.2010, 15:24 | ||
сейчас пересмотрел задачу про прямоугольники. Все вроде правильно за исключением: нужно проверять исходные данные, что бы узнать возможно ли пересечь эти прямоугольники или нет, чего я не сделал. Поэтому из рекурсии в некоторых случаях можем и не выйти. В принципе переделка минимальная. следующая задача:
я не понял что требуется: написать класс, рекурсивность которого проявляется только во время считывания элементов списка? при других операциях работы со списком (добавление элемента и удаление элемента) я рекурсии не наблюдаю. при удалении рекурсию можно сделать только что бы установить указатель на удаляемый элемент. а при добавлении - если список делаем упорядоченным. Однако в задании сказано про рекурсивный список а не упорядоченный. |
Автор: Чoо 23.11.2010, 17:30 | ||
вобщем сделал класс только с рекурсивным выводом списка. непонятно что требовалось в задании.
|
Автор: Чoо 25.11.2010, 19:56 | ||||
прокомментируйте, если не трудно ![]() |
Автор: baldina 26.11.2010, 10:23 | ||||||
1. используется protected, т.е. pos_x и pos_y доступны в производных классах. вроде бы класс предназначен для наследования. об этом говорит и наличие виртуальных функций. но в классах, которые могут быть базовыми, делают виртуальные деструкторы. для избежания проблем в будущем)) 2. что означает resize в применении к point?? 3. чего виртуального в функции set_pos? если у любой фигуры есть точка отсчета (origin), то его изменение не зависит от фигуры.
открытое наследование означает "является", "работает как". например, "ту134 является самолетом; самолет является летательным аппаратом". в данном случае прямоугольник не является точкой. в качестве базового класса надо выбрать что-то абстрактное - геом. фигуру.
|
Автор: Чoо 26.11.2010, 15:51 |
baldina, 1. - protected объявил для того, что бы можно было получить доступ к полям класса только из методов самого класса, а так же из производных классов. 2. resize в применении к поинт - ни чего не делает, т.к. точка - она точкА, ее невозможно масштабировать. 3. про точку отсчета немного недопонял: в 10 строке вашего класса получение точки отсчета. Метод будет вызываться из производных классов(как и move), однако точка отсчета представлена только координатами одной точки x и y. И теперь мне не понятно, если прямоугольник будет производным классом от shape, то как будет задано его положение на сетке координат, ведь координаты одной точки для него не достаточны. move так же меняет координаты одной точки. |
Автор: baldina 26.11.2010, 16:16 | ||||||||
говорю же. если класс должен быть базовым - деструктор объявляется виртуальным точка отсчета - одна, она не зависит от фигуры. это ноль в локальной системе координат фигуры
достаточно. вот что бы отобразить, помимо origin надо знать еще width и height, а что бы переместить и origin вполне хватит
Добавлено @ 16:21
Добавлено через 10 минут и 8 секунд кстати. функция resize, где factor - целое число, принимающее отрицательные значения (при уменьшении), выглядит несколько странно. проще factor иметь действительным (double) и использовать только операцию умножения. уменьшение будет при значениях от 0 до 1. а вообще - почитайте про аффинные преобразования, это простой и универсальный инструмент для перемещения, масштабирования, поворота и их комбинаций. все программы 2D и 3D графики используют их. |
Автор: baldina 26.11.2010, 16:36 | ||
конечно. вы вводите в интерфейс класса бесполезную функцию. вот если бы эта функция была в интерфейсе класса shape - другое дело. (опять кстати - при использовании аффинных преобразований потребуется переопределить в производных классах только функции отображения и др. специфичные для конкретных фигур. а геометрические преобразования выполняются универсально) |
Автор: Чoо 26.11.2010, 17:44 | ||||
да, понял. Спасибо. Затупил что-то ![]() вот что получилось:
Всё правильно понял? однако не получилось избваиться от метода resize для точки. Добавлено @ 17:46 и непонятно почему в объявлении метода draw константа. он же ни чего не принимает и ни чего не возвращает.. (а это нужно для того, что бы случайно не изменить содержимое полей объекта, что-то медленно все вспоминаю) |
Автор: baldina 29.11.2010, 09:41 | ||
Чoо, 1. добавьте в point конструктор и операторы +,+=,*,*= это позволит сделать код короче и яснее 2. можно resize не делать виртуальным. достаточно хранить коэф. масштабирования, а при рисовании (и прочих операциях) умножать на него координаты точек.
|
Автор: Чoо 30.11.2010, 20:38 | ||||||
baldina, спасибо, что помогаете ![]() переделал решение, вот результат:
Надеюсь, что в этот раз всё правильно ![]() на выходных решил еще одну задачу:
решал под линукс. Еще хотел отсортировать файлы по-имени, но это в задачу не входит. Хотя можно было бы ввести метод сортировки ![]() если для тренировки, такая система классов подойдет. Если писать реальную систему, то я бы писал не пару дней, что слишком лениво делать на этапе обучения. |
Автор: Чoо 2.12.2010, 19:48 | ||||
По последним задачам, там все правильно? Следующая задача.
вот тут не знаю. по идее я делаю копию, вроде результат есть ![]() ![]() |
Автор: Чoо 3.12.2010, 00:32 | ||||
Добавлено @ 00:32 решил с malloc потренироваться ![]() |
Автор: bsa 6.12.2010, 14:37 | ||
Чoо, ты на каком языке пишешь? На С++ это должно быть так:
хочешь ты того или не хочешь, но sizeof(char) == 1. |
Автор: Чoо 6.12.2010, 14:46 |
честно говоря не знаю, каша в голове ![]() не сопрю, но я так понял эта инструкция ни как не влияет на производительность, так как число определяется в процессе компилирования, а не иполнения. |
Автор: bsa 6.12.2010, 16:14 |
Чoо, а кто говорил про проблемы компиляции? Читать неудобно! |
Автор: Чoо 6.12.2010, 16:56 |
bsa, оК, учту в следующих задачах. Единственное что, по предыдущему замечанию, есть непонятки. Почему плохо использовать стандартные библиотеки Си в программах на с++ ? ![]() |
Автор: bsa 6.12.2010, 18:23 |
Чoо, потому что на С++ все это решается гораздо проще и оптимальней. |
Автор: Чoо 6.12.2010, 19:30 |
bsa, тоесть библиотеки типа cstring в принципе выполняют то же самое, что и string.h, только отличаются более эфективной реализацией? |
Автор: bsa 6.12.2010, 22:52 |
В С++ string.h зовется cstring. Отличий почти нет, разве что все стандартные символы (функции, переменные) помещены в пространство имен std. Это касается всех стандартных сишных хидеров (cstdio, cstdlib...) |
Автор: Чoо 7.12.2010, 13:12 | ||||||||
bsa, тогда не понимаю, почему если вместо
использовать
решение будет проще и оптимальней? *** решил еще одну задачу.
я так понял по условию, что вместо strcmp и getlng надо сделать свои функции. Ну а если их реализовывать самостоятельно, то значит не использовать cstring => придется реализовать и strcpy. Результат вроде правильынй ![]() |
Автор: Чoо 7.12.2010, 15:34 | ||||
как-то слишком просто...
|
Автор: Чoо 7.12.2010, 18:03 | ||||
тоже все просто. Память решил выделять так, как советовали ранее: каждый раз в 2 раза больше от имеющегося.
|
Автор: Чoо 7.12.2010, 18:39 | ||||
все так же просто |
Автор: mimik 7.12.2010, 19:00 |
почему for а не while? |
Автор: Чoо 7.12.2010, 20:23 |
mimik, для разнообразия ![]() |
Автор: Чoо 7.12.2010, 21:36 | ||||
честно говоря, я не смог унаследовать класс el :(. Убил пару часов времени - ни как. Наверное надо было изначально проектировать приложение иначе.. но в задании говорили только о наследовании класса "очередь". Вобщем вопрос: можно было как-то унаследовать el? (единственный вариант, который вижу, это наследование, с переопределением поля next. потом бы пришлось бы наследовать очередь с переопределением поля head, но так кажется, что этот вариант будет через одно место...
|
Автор: bsa 8.12.2010, 12:53 | ||||||
Нет. Только из-за этого не будет. Но если ты всякие strcmp, strcpy и пр. заменишь на std::string, то будет. |
Автор: Чoо 8.12.2010, 13:00 |
ааа... Ну до этого я еще не дошел ![]() Добавлено через 59 секунд пол книжки уже осилил. Правда небольшая каша, но это временно. |
Автор: Чoо 11.12.2010, 23:30 | ||||
пока что перегрузил только сложение и приравнивание. Что-то на решение понадобилось больше времени, чем планировал. Решил еще вместо двоичного числа, сделать класс для любой системы счисления вплоть до 16чной. ну складывает пока корректно. Потом перегружу извлечение и помещение в поток, что бы не мучаться с тестированием. Если не устану, сделаю деление, умножение, вычитание, сравнение. на всякий случай опубликовал результат, вдруг есть где грубые косяки. Лучше их сейчас исправлю, вместо того, что бы иметь кучу головной боли "почему не работает" ![]() *** пару косяков нашел, потому редактирую сообщение (косяки касались выделения памяти для копируемых элементов) |
Автор: Чoо 12.12.2010, 02:01 | ||
перегрузил операторы извлечения и помещения в поток. К сожалению криво:
кривость помещения в том, что происходит утечка памяти. Не знаю как сделать правильно :(. кривость извлечения в том, что не знаю как выделить память для строки динамически, поэтому максимальное число может содержать не > 100 символов. На сегодня наверное хватит. |
Автор: bsa 12.12.2010, 12:06 |
у тебя два варианта: 1. переписать _get_value() и get_value() с использованием std::string 2. удалить указанные методы вообще и включить их функциональность в operator<<. Кому надо будет получить строку, будут использовать std::stringstream. |
Автор: Чoо 12.12.2010, 14:24 | ||
bsa, а если я сделаю так?
или это уже костыли? 1й вариант - пока исключаю, так как не дошел до std::string а вот второй, в принципе решение вижу. память тогда выделять не надо, а можно сразу выводить данные в поток (поэлементно), да? |
Автор: Чoо 14.12.2010, 23:06 | ||
вобщем подумал я чуть и атк и не сделал вычитание и все из-за знака числа. Что-то слишком много и долго кодить. Простого решения не вижу. Вопщем из всего задания сделал только: извлечение и помещение в поток, операции сравнения (только < > ==), не полностью операцию сложения (только сложение чисел с одинаковым знаком) и вообще ни как не реализовал вычитание. Умножение и деление - даже не думал делать. Намного проще бы было, если бы я преобразовывал введенную строку в число, производил вычисления, а потом бы выдавал результат. Что-то слишком сложным путем пошел. Вопщем сдаюсь я ![]() ![]()
|
Автор: bsa 15.12.2010, 14:34 |
Хорошего программиста именно лень и отличает. По поводу программы, поле basis абсолютно лишнее - оно только путает код. Нет никакого смысла хранить данных в неудобном для работы виде. Функции сложения и вычитания одинаковые - определение фактической операции для работы с модулем, выравнивание модулей (т.е. чтобы число элементов было одинаковым), выполнение ее, выставление нужного знака и оптимизация модуля (убирание лишних элементов) у результата. |
Автор: Чoо 15.12.2010, 15:12 |
![]() ** тоесть работать именно с двоичным числом, как работает сам компьютер? (ну применять добавочные и обратные коды тоесть) только в нашем случае роль разрядной сетки выполняет массив. |
Автор: Чoо 15.12.2010, 22:22 | ||
во чо получилось:
![]() Всё, кроме сложения, вычитания и вывода в поток придется перегружать заново. Но это уже не трудно будет. Есть сомнения в коде: Добавлено @ 22:23 на 157 строке. Я там еще прокоментировал. Не уверен, правильно ли я складываю 2 отрицательных числа. |
Автор: Чoо 16.12.2010, 00:01 |
ан нет. где-то накасячил. не правильно считает, если от отрицательного отнять отрицательное |
Автор: bsa 16.12.2010, 13:21 |
Чoо, в дополнительном коде считать не стоит - он используется тогда, когда количество разрядов постоянно. А в нашем случае нет. Более того, следует использовать не int, а uint32_t. Так как в результате умножения у тебя будет uint64_t. В случае int ты это жестко проконтролировать не сможешь. |
Автор: Чoо 16.12.2010, 13:36 | ||
а как тогда считать в прямом? обратный код же, по сути, тоже зависит от количества разрядов. Да и отличается от дополнительного лишь тем, что единица не прибавлена. Просто я пока не вижу, как по-другому свести операцию вычитания к сложению. спасибо, что предупредили ![]() |
Автор: bsa 16.12.2010, 14:06 |
Чoо, очень просто - не своди. Вычитание делай через вычитание. Посмотри как сделано здесь: http://www.di-mgt.com.au/bigdigits.html. |
Автор: Чoо 16.12.2010, 14:16 |
bsa, я кстати сейчас прикинул вычисления в обратном коде. там если выходим за границы разрядной сетки, надо эту единиц, которая вышла, прибавить к результату. если единица уходит - значит число положительное. Если нет - отрицательное и нужно инвертировать все разряды кроме знакового - и получим число в прямом коде. Единственное что, число 0 будет представлено двумя числами (если 8 разрядов, то: +0 = 0000 0000; -0 = 1111 1111). ** смотрю ссылку |
Автор: Чoо 16.12.2010, 16:21 |
глянул. что-то вообще ни чего не понял. В функции вычитания увидел ссылку на книгу Кнута, в трех томах. Глянул что там написано. Вопщем вычитание сделано на основе алгоритма, в котором не предусмотрены операции с отрицательными значениями. Далее Кнут пишет по поводу обратного и добавочного кода, которые можно использовать при работе с отрицательными числами. Может я что-то не понял? |
Автор: Чoо 16.12.2010, 20:42 | ||
во.. сделал почти.. Пока еще с обратными кодами. Все работает, за исключением: 1. Есть положительные нули и отрицательные ![]() 2. в строке 169 я рассчитываю, что два раза вызовится конструктор копирования (для tmp1 и tmp2). Он так и вызвается, в отладчике если смотреть, в нем происходит копирование данных при двух вызовах. Однако содержимое tmp1 совсем не меняется, что приводит к краху программы. Что я не правильно написал?
Добавлено через 1 минуту и 36 секунд да, умножение и деление не делал |
Автор: bsa 16.12.2010, 23:27 |
Чoо, вообще-то обратный код из прямого (и обратно) получается путем инвертирования всех битов и добавления единицы. Таким образом,0b11111111 == -1 |
Автор: Чoо 17.12.2010, 00:18 | ||||||
bsa, обратный код получается инвертированием всех битов: 0b0000 0011 = 3 0b1111 1100 = -3 При сложении бит переноса (если он есть) добавляется к результату сложения.
для перехода от обратного кода, если он показывает отрицательное число, к прямому, надо инвертировать все биты, кроме знакового:
обратный код положительного числа соответствует прямому коду. ни чего менять не надо. Дополнительный же код получается в 2 этапа: 1. Инверсия всех бит. 2. Дополнение до двух (тот же +1) При сложении, если получаем перенос в старший разряд, то это просто игнорируется. При сложении чисел в дополнительном коде мы получаем число в прямом коде, если я правильно понял.. а в 169 строке, что может быть не так? |
Автор: bsa 19.12.2010, 10:57 | ||||
-3 + 3 == 0 - сомнений не вызывает? 0b1111 1100 + 0b0000 0011 = 0b1111 1111, а это уже код -1. Таким образом, -3 == 0b1111 1101. Ты не путай инверсию битов и инверсию знака. Отрицательное число - это дополнительный код и есть. Добавлено через 11 минут и 21 секунду
0b1111 1101 + 0b1111 1111 = 0b1111 1100 <=> -3 + -1 = -4 Переполнение можно определить через знаки исходных данных и результата, если переполнения нет, то знак результата должен совпадать со знаком одного из слагаемых. |
Автор: Чoо 19.12.2010, 16:19 |
ну.. это -3 в дополнительном коде. Так как есть дополнение до двух. Тогда, что бы прояснить ситуацию, как будет выглядить число 3 в обратном и дополнительном коде, и как будет выглядеть число -3 (тоже в обратном и дополнительном коде). Я так думаю, что так(по порядку как перечислял: прямой, обратный, дополнительный): 3: 0000 0011 0000 0011 0000 0011 -3: 1000 0011 1111 1100 1111 1101 тоесть я руководствовался таким представлением об обратном и дополнительном кодах. Правила сложения одинаковые, только по разному обрабатывается выход за пределы "разрядной сетки". Добавлено через 2 минуты и 38 секунд немножко ошибся ![]() |
Автор: bsa 19.12.2010, 19:07 |
почитай пожалуйста про двоичную арифметику. |
Автор: Чoо 19.12.2010, 20:02 |
Ну у меня в конспекте по вычислительной технике написано именно так, как я пишу. Сейчас погуглил, по поводу обратного кода и сложения в обратном коде (не в дополнительном) и вот что нашел: http://www.ref.by/refs/67/15151/1.html пункт 1.4.1. Представление чисел со знаками ну вроде я всё правильно понял, по поводу сложения.. |
Автор: bsa 19.12.2010, 22:35 |
Чoо, ладно. я понял, о чем речь. Мне и в голову не могло придти, что кто-то будет подобные теоретические изыски вдалбливать в головы новичков. Имхо, "обратный код" вообще смысла не имеет. Лично я не вижу никакого применения для него. Дополнительный код актуален для чисел с фиксированной точностью. А вот прямой код имеет смысл применять для чисел с неограниченной точностью. Вот только знак не следует хранить в старшем бите. Посмотри на BigDigits, там для знака используется переменная, способная иметь три значения: положительно, нуль и отрицательно. Это сильно упрощает работу с числами. |
Автор: Чoо 19.12.2010, 23:24 | ||
оК ![]() Трудно разбираться в чужом коде, но что ж делать... попробую осилить |
Автор: bsa 20.12.2010, 14:35 |
Чoо, там код очень хороший. А разбираться в чужом коде полезно - не всегда ты будешь только свой писать. А потом, через пару лет свой же код вызывает возглас негодования: "Кто же так пишет?!?". |
Автор: александра1987 3.5.2015, 12:16 |
Модератор: Сообщение скрыто. |