Пример оформления тестового задания.
//--------------------------------------------------------
struct list { void *data; xxx *next; };
void *F( list *p[], void (*pf)(void*,void*))
{ list *q; void *pmin=p[0]->data;
for (int i=0; p[i] != NULL; i++)
for (q = *p; q != NULL; q = q->next)
if (*pf)(q->data,pmin) <0 pmin=q->data;
return pmin; }
Анализ этого теста производится по формальным признакам. Наличие вложенных циклов говорит о двухуровневой структуре данных. Структурированный тип list с единственным указателем на переменную такого же типа и внешний вид внутреннего цикла говорят о том, что нижний уровень представляет собой односвязный список. Структура данных верхнего уровня – массив указателей на переменные типа list, каждый элемент его является заголовком списка – указателем на первый элемент. Соответственно, внешний цикл перемещается по массиву заголовков, выбирая эти указатели.
Элемент списка содержит указатель на переменную неопределенного типа void*. Сама функция является итератором, тип объектов, хранимых в структуре данных, ей неизвестен. В качестве второго параметра он получает указатель на ту функцию, которая учитывает конкретный вид этих объектов. Выберем в качестве хранимых объектов строки, тогда при инициализации элементов списка их можно заполнить строковыми константами – указателями на эти строки, размещенные в памяти самим транслятором. Сначала определяются переменных – элементы списка, причем список задается «хвостом вперед», а затем массив указателей инициализируется указателями на переменные – начальные элементы списков.
list a1={“aaa”,NULL}, a2={“bb”,&a1}, a3={“cccc”,&a2};
list b1={“a”,NULL}, b2={“bbbb”,&b1}, b3={“ccc”,&b2};
list *pp[]={&a3,&b3,NULL};
Алгоритм итератора содержит стандартный контекст поиска минимума. Естественно это производится итератором во всей структуре данных, однако сам способ сравнения элементов определяется внешней функцией, которая получает 2 указателя на текущий минимальный объект и объект, извлеченный из структуры данных. Для строк выберем функцию сравнения их по длине, которая возвращает разность этих длин. Сама функция получает указатели на объекты типа void*, но, поскольку она «знает, что это строки», то преобразует их к типу char*.
int cmp(void *p1,void *p2){
return strlen((char*)p1) - strlen((char*)p2); }
Таким образом, итератор возвратит указатель на строку минимальной длины. Последнее, что нужно сделать, преобразовать результат функции от типа void* к типу char*, опять-таки потому, что итератор возвращает указатель на объект «вообще», то есть произвольного типа, а мы «знаем», что он является строкой.
void main(){ cout << (char*)F(pp,cmp) << endl; }
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.