Opened 5 years ago
Closed 5 years ago
#313 closed ожидаются исправления (задача НЕ сдана)
WW #4
Reported by: | Шиповалов Артем | Owned by: | Шиповалов Артем |
---|---|---|---|
Component: | WW_mergesort | Version: | 2.0 |
Keywords: | Cc: |
Description
Change History (8)
comment:1 Changed 5 years ago by
Owner: | changed from Egor Suvorov to Шиповалов Артем |
---|---|
Type: | ожидается проверка → ожидаются исправления |
comment:2 Changed 5 years ago by
Owner: | changed from Шиповалов Артем to Egor Suvorov |
---|---|
Type: | ожидаются исправления → ожидается проверка |
Я понимаю что я не правильно делаю, но я не до конца понимаю как это можно исправить
comment:3 Changed 5 years ago by
Owner: | changed from Egor Suvorov to Шиповалов Артем |
---|---|
Type: | ожидается проверка → ожидаются исправления |
Кажется, пока что основная проблема — вы не обращаетесь к данным, которые лежат по указателю void *a
, а просто делаете арифметику указателей.
Напишите сначала обычный merge sort для int'ов и убедитесь, что он работает.
А дальше потихоньку переписывайте на void*
, можно ориентироваться на работу с указателями тут: https://github.com/yeputons/hse-2019-cpp/blob/master/05-191004p/02-lab/05b-print-generic.c (см. файлы с названием 04-*
, 03-*
).
Думаю, будет эффективнее либо в личке разобраться, либо в чатике оперативной помощи, либо завтра лично между 15 и 17.
comment:4 Changed 5 years ago by
Owner: | changed from Шиповалов Артем to Egor Suvorov |
---|---|
Type: | ожидаются исправления → ожидается проверка |
Version: | 1.0 → 2.0 |
Пока что только int, а то вдруг не успею всю доделать и оправить вовремя
comment:5 Changed 5 years ago by
Теперь работает и с char, но со string не работает, меняет только перую букву, я понимаю почему, но не понимаю как это исправить, не меняя mergeSort. Скорее всего надо отдельный компаратор для стрингов, а что делать дальше не знаю
comment:6 Changed 5 years ago by
Owner: | changed from Egor Suvorov to Шиповалов Артем |
---|---|
Type: | ожидается проверка → ожидаются исправления |
Нерекурсивный merge sort O_O. Прикольно. Но почему бы и нет :)
Рекомендации по багам в merge sort:
- Очень странно, что у вас переменные для внутренних циклов объявлены вне цикла, который увеличивает размер блока. Например, из-за этого вы их не обнуляете.
- В строчках 23, 28, 34, 39 вы перемещаете только первый байт. Это будет работать только с типами размера 1 (например,
char
). Чтобы работало с произвольными типами, надо для присваивания элемента написал цикл, который по очереди скопирует всеelement_size
байтов. То, что у вас при этом работает со строчками — счастливое совпадение (потому что вы сейчас перемещаете младшие байты у указателей, что странное действие). - Напоминаю, что баллы за корректность получает только реализация, которая соответствует условию (берёт произвольный массив из
argv
и всё такое). Если вы хотите сделать свои тесты — без проблем, только сделайте их лучше в отдельном файлеtest.c
, который компилируется в./test
вместо./lab_04
. А в./lab_04
оставьте основное решение. Тогда можно будет и баллов заработать и параллельно тесты свои иметь.
По корректности:
- В
mergesort.h
не хватает#include <stddef.h>
, потому что там объявленsize_t
, нужный для объявленияmy_mergesort
.
По стилю:
- Поехавшие отступы: то табы, то пробелы. Пройдитесь автоформаттером.
- Вынесите лучше тесты в отдельные функции. Тогда не потребуется выдумывать новые имена массивам, можно будет везде назвать их
data
. - Непонятно, зачем делать
if (elements % 2 == 1) mid++
, должно работать и без этого.
comment:7 Changed 5 years ago by
А, да, со строчками у вас происходит следующее:
- Вы передаёте в
mergesort
указатель на двумерный массивd
. Он размера3 * 4 * sizeof char = 12
байт. Элементd[0]
массиваd
— это одна строчка, она размера4
байта. Соответственно,mergesort
пытается переставлять элементыd
, то есть строчки целиком. Но он умеет переставлять только первый байт, действительно, а должен всеelement_size
. - Вы вызываете компаратор, который читает первый байт из каждого
char*
(именно из значения указателя) и сравнивает их. То есть сортирует строчки по их адресам в памяти. Они исходно лежат последовательно => компаратор их так и должен оставить. А вообще да: компараторы для разных типов должны быть разные, в этом вся идея: сортировка одинаковая для всех типов, а вот компаратор тип знает.
Дальше у вас будут проблемы, когда строчки разного размера, причём неизвестного на этапе компиляции. Там вы не можете разумно расположить строчки разной длины в одном массиве (ну разве что куча пустого места будет). Поэтому более удобной стратегией будет положить в массив указатели на строчки и сортировать их специальным компаратором.
comment:8 Changed 5 years ago by
Resolution: | → задача НЕ сдана |
---|---|
Status: | assigned → closed |
Кажется, неуспех :(
Захотите дорешать — переоткрывайте тикет.
Корректность на 1/10 есть, попытка засчитана.