Консультация № 186334
06.06.2012, 23:29
116.38 руб.
0 12 1
Здравствуйте, уважаемые эксперты! Прошу помочь с последней работой в семестре!

Требуется составить программу на языке Си с использованием процедур и функций для сортировки таблицы заданным методом и двоичного поиска по ключу в таблице.
Программа должна вводить значения элементов неупорядоченной таблицы и проверять работу процедуры сортировки в 3х случаях - 1)элементы табл. с самого начала упорядочены, 2) элементы таблицы расставлены в обр порядке, 3) элементы таблицы не успорядочены.

Для каждого вызова процедуры сортировки необходимо печатать исходное состояние таблицы и результаты сортировки. После выполнения сортировки программа должна вводить ключи и для каждого из них выполнять поиск в упоряд. таблице с помощью процедуры двоичного поиска и печатать найденные элементы, если они не присутствуют в таблице.

Ниже приведена программа, полностью функционирующая.

Хотелось бы попросить экспертов вот о чем:

1) Вместо сортировки, приведенной в программе, сделать пузырьковую сортировку.
2) По возможности прокомментировать код.

table_element.h

Код:
#ifndef _TABLE_ELEMENT_H_
#define _TABLE_ELEMENT_H_

struct s_table_element {
char key[3];
int val_size;
char* val;
};

typedef struct s_table_element TableElement;


int cmp_elements(TableElement, TableElement);

int read_element(TableElement*);
int read_key(TableElement*);

void print_element(TableElement);
void print_key(TableElement e);

void clone_element(TableElement, TableElement*);

#endif


table_element.c

Код:
#include "table_element.h"
#include <stdio.h>
#include <stdlib.h>

int cmp_elements(TableElement a, TableElement b) {
int i;
for (i = 0; i < 3; i++) {
if (a.key[i] < b.key[i]) {
return -1;
} else if (a.key[i] > b.key[i]) {
return 1;
}
}
return 0;
}

int is_space(char c) {
return c == ' ' || c == '\n';
}

int read_key(TableElement* e) {
int i;
char c;

/* key does not begin with space */
do {
if (scanf("%c", &c) != 1) {
return 0;
}
} while (is_space(c));

e->key[0] = c;
/* read rest of key's symbols */
for (i = 1; i < 3; i++) {
if (scanf("%c", &(e->key[i])) != 1) {
return 0;
}
}
return 1;
}


int read_value(TableElement* e) {
int i;
char c;

e->val_size = 8;
e->val = malloc(sizeof(char)*e->val_size);

/* value can begin with anything */
i = 0;
while (1) {
c = getchar();
if (i == e->val_size) {
e->val_size *= 2;
e->val = realloc(e->val, sizeof(char)*e->val_size);
}
if (c == EOF || c == '\n' || c == '\0') {
e->val[i] = '\0';
e->val_size = i + 1;
e->val = realloc(e->val, sizeof(char)*e->val_size);
return i;
}
e->val[i] = c;
i++;
}
}

int read_element(TableElement* e) {
/*Expect that key and value are divided with
some space simbol, but only one*/
return read_key(e) && getchar() && read_value(e);
}

void print_key(TableElement e) {
int i;
for (i = 0; i < 3; i++) {
printf("%c", e.key[i]);
}
}
void print_value(TableElement e) {
printf("%s", e.val);
}
void print_element(TableElement e) {
print_key(e);
putchar(' ');
print_value(e);
printf("\n");
}


void clone_element(TableElement e, TableElement* new) {
int i;
for (i = 0; i < 3; i++) {
new->key[i] = e.key[i];
}
new->val_size = e.val_size;
new->val = malloc(sizeof(char)*new->val_size);
for (i = 0; i < new->val_size; i++) {
new->val[i] = e.val[i];
}
}


table.h

Код:
#ifndef _TABLE_H_
#define _TABLE_H_

#include "table_element.h"

struct s_table {
TableElement* elements;
int size;
};

typedef struct s_table Table;

int read_table(Table*);
void print_table(Table);

int search_binary(Table, TableElement, TableElement*);

int sort_table(Table*, int* n_swaps, int* n_cmps);

#endif


table.c

Код:
#include "table.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int read_table(Table* t) {
int i;
if (scanf("%d", &(t->size)) != 1) {
return 0;
}
if (t->size < 0) {
return 0;
}
t->elements = malloc(sizeof(TableElement)*t->size);
for (i = 0; i < t->size; i++) {
read_element(&(t->elements[i]));
}
return t->size;
}

void print_table(Table t) {
int i;
for (i = 0; i < t.size; i++) {
print_element(t.elements[i]);
}
}


int search_binary(Table t, TableElement key, TableElement* result) {
int l = 0;
int r = t.size - 1;
int m;
int cmp;

if (t.size < 1) {
return 0;
}

while (l <= r) {
m = (r + l) / 2;
cmp = cmp_elements(key, t.elements[m]);
if (cmp == 0) {
clone_element(t.elements[m], result);
return 1;
} else if (cmp > 0) {
l = m + 1;
} else {
r = m - 1;
}
}
return 0;
}

int is_sorted(Table* t, int* n_cmps) {
int i;
for (i = 0; i < t->size - 1; i++) {
(*n_cmps)++;
if (cmp_elements(t->elements[i], t->elements[i + 1]) == 1) {
return 0;
}
}
return 1;
}

int sort_table(Table* t, int* n_swaps, int* n_cmps) {
srand ( time(NULL) );
while (!is_sorted(t, n_cmps)) {
int i1 = rand() % t->size;
int i2 = rand() % t->size;
TableElement e;
(*n_swaps)++;
/* swap random elements */
clone_element(t->elements[i1], &e);
clone_element(t->elements[i2], &(t->elements[i1]));
clone_element(e, &(t->elements[i2]));
}
return 1;
}


main.c

Код:
#include "table.h"
#include "table_element.h"
#include <stdio.h>

int main() {
Table t;
int res;
TableElement e;
TableElement key;

int swaps, cmps;
swaps = cmps = 0;

read_table(&t);
printf("===Считанная таблица===\n");
print_table(t);
sort_table(&t, &swaps, &cmps);
printf("===Отсортированная таблица===\n");
print_table(t);
printf("Sorted in %d cmps and %d swaps\n", cmps, swaps);
printf("===Поиск ключей===\n");
while (1) {
res = read_key(&key);
if (!res) {
break;
}
res = search_binary(t, key, &e);
if (res) {
print_element(e);
} else {
printf("err\n");
}
}
return 0;
}


Makefile

Код:
CC = gcc
LD = gcc
CFLAGS = -ansi -Wall -pedantic -c
LFLAGS = -o $(PROGRAMM)

PROGRAMM = prog
FILES = main.o table.o table_element.o

all: $(PROGRAMM)

$(PROGRAMM): $(FILES)
$(LD) $(LFLAGS) $(FILES)

clean:
rm -f *.o $(PROGRAMM)

.c.o:
$(CC) $(CFLAGS) $<

test: all
./$(PROGRAMM) < test1
./$(PROGRAMM) < test2

table.o: table.h table_element.h
table_element.o: table_element.h
main.o: table.h table_element.h


test1

Код:
7                                       
123 ---
234 | |
345 ---
456 | |
567 ---
678 факультет
789 МЭИ
1__
123
234
345
456
567
678
789
890
346


test2

Код:
7                                       
234 | |
235 ---
456 факультет
123 ---
125 ---
789 МЭИ
124 | |
1__
123
234
345
456
567
678
789
890
346


Уважаемые эксперты, я уже много раз обращался с помощью на Ваш портал в тему программированния.Но не потому, что я ленивый бездарь, а потому, что я многое упустил и запустил, я понимаю программы, но для меня затруднительно их писать.
Этот вопрос - последний, который я собираюсь задавать, и ответ на него напрямую влияет на допуск к экзамену, который будет через 2 дня. Прошу еще раз выручить меня, как вы неоднократно уже это делали.

Заранее огромное спасибо тем экспертам, которые отреагируют на этот вопрос!

С уважением,
Иван.

Обсуждение

Неизвестный
07.06.2012, 11:25
общий
Ответ нужен до ночи (максимум до 02-00)!
Требуется просто изменить функцию int sort_table на пузырьковую сортировку
Неизвестный
07.06.2012, 14:04
общий
Обратите, пожалуйста, внимание на вопрос.
Неизвестный
07.06.2012, 14:05
общий
Вообще у меня туго со временем, но если никто не отзовётся, постараюсь сделать вечером.
давно
Профессор
230118
3054
07.06.2012, 14:35
общий
Займусь, когда закончу другой вопрос.
Неизвестный
07.06.2012, 15:03
общий
Уважаемые Киселёва Алёна aka Verena, Асмик Гаряка, спасибо вам огромное!Я понимаю, что бесконечные "спасибо" на форумах уже потеряли свой вес, но я действительно буду вам очень благодарен!Вы меня спасете!
Неизвестный
07.06.2012, 21:12
общий
07.06.2012, 21:13
Адресаты:
Главное сортировку написать применительно к этой программе, прокомментировать уже второстепенное дело ... Здесь вроде бы реализация реализация

Первая цифра в текстовых файлах(7) - размер таблицы

Если кто-нибудь взялся за задачу, пожалуйста, отпишитесь
Неизвестный
07.06.2012, 22:27
общий
Вероятно, как-то так:
Код:
int sort_table(Table* t, int* n_swaps, int* n_cmps) {
for(i = 0 ; i < t->size ; i++) {
// сравниваем два соседних элемента.
for(j = 0 ; j < t->size - i - 1 ; j++) {
if(cmp_elements(t->elements[j], t->elements[j + 1]) == 1) {
// если они идут в неправильном порядке, то
// меняем их местами.
TableElement e;
(*n_swaps)++;
clone_element(t->elements[j], &e);
clone_element(t->elements[j+1], &(t->elements[j]));
clone_element(e, &(t->elements[j+1]));
}
}
}
return 1;
}

Но не проверяла. Позже проверю, или сами пока попробуйте.
Неизвестный
07.06.2012, 22:47
общий
У меня не работает... может быть, я что-то не так делаю
Неизвестный
07.06.2012, 23:02
общий
Все, перепутал, все отлично функционирует!Просто я код скопировал, а из-за этого невидимые символы распознавались!От руки ввел и все!

Алёна, знали бы Вы, что у меня внутри! Огроменнейшее Вам спасибище!!!!!!!!Вы серьезно меня выручили!!!!!!!!!!!!!!
Неизвестный
07.06.2012, 23:04
общий
Проверила, работает. Переменные i и j просто надо было дообъявить, забыла.
Код:
int sort_table(Table* t, int* n_swaps, int* n_cmps) {
int i, j;
for(i = 0 ; i < t->size ; i++) {
// сравниваем два соседних элемента.
for(j = 0 ; j < t->size - i - 1 ; j++) {
(*n_cmps)++;
if(cmp_elements(t->elements[j], t->elements[j + 1]) == 1) {
// если они идут в неправильном порядке, то
// меняем их местами.
TableElement e;
(*n_swaps)++;
clone_element(t->elements[j], &e);
clone_element(t->elements[j+1], &(t->elements[j]));
clone_element(e, &(t->elements[j+1]));
}
}
}
return 1;
}
Неизвестный
07.06.2012, 23:05
общий
ПонятноПожалуйста.
Неизвестный
08.06.2012, 03:43
общий
это ответ
Здравствуйте, Барс Иван!
1. Сортировка
Код:
int sort_table(Table* t, int* n_swaps, int* n_cmps) {
int i, j;
for(i = 0 ; i < t->size ; i++) {
// сравниваем два соседних элемента.
for(j = 0 ; j < t->size - i - 1 ; j++) {
(*n_cmps)++;//увеличиваем число сравнений
if(cmp_elements(t->elements[j], t->elements[j + 1]) == 1) {
// если они идут в неправильном порядке, то
// меняем их местами.
TableElement e;
(*n_swaps)++;//увеличиваем число обменов
clone_element(t->elements[j], &e);
clone_element(t->elements[j+1], &(t->elements[j]));
clone_element(e, &(t->elements[j+1]));
}
}
}
return 1;
}

2. Комментарии, немножко.
[code h=300]int cmp_elements(TableElement a, TableElement b) { //сравнение двух эл-в таблицы
int i;
for (i = 0; i < 3; i++) { //посимвольнок сравнение ключа
if (a.key[i] < b.key[i]) {
return -1; //если а меньше
} else if (a.key[i] > b.key[i]) {
return 1; //если а больше
}
}
return 0; //если ключи совпали
}

int is_space(char c) { //проверка символа на пробел или перенос строки
return c == ' ' || c == '\n';
}

int read_key(TableElement* e) {//заполнение ключа элемента с клавиатуры
int i;
char c;

/* key does not begin with space */
do {
if (scanf("%c", &c) != 1) {
return 0;
}
} while (is_space(c));

e->key[0] = c;
/* read rest of key's symbols */
for (i = 1; i < 3; i++) {
if (scanf("%c", &(e->key[i])) != 1) {
return 0;
}
}
return 1;
}


int read_value(TableElement* e) { //заполнение значения элемента с клавиатуры
int i;
char c;

e->val_size = 8;
e->val = malloc(sizeof(char)*e->val_size); //выделение памяти

/* value can begin with anything */
i = 0;
while (1) {
c = getchar();
if (i == e->val_size) {
e->val_size *= 2;
e->val = realloc(e->val, sizeof(char)*e->val_size); //перевыделение памяти
}
if (c == EOF || c == '\n' || c == '\0') {
e->val[i] = '\0';
e->val_size = i + 1;
e->val = realloc(e->val, sizeof(char)*e->val_size);
return i;
}
e->val[i] = c;
i++;
}
}

int read_element(TableElement* e) { //чтение всего элемента
/*Expect that key and value are divided with
some space simbol, but only one*/
return read_key(e) && getchar() && read_value(e);
}

void print_key(TableElement e) { //печать ключа
int i;
for (i = 0; i < 3; i++) { //посимвольно, потому что у него нет 0 на конце
printf("%c", e.key[i]);
}
}
void print_value(TableElement e) { //печать значения
printf("%s", e.val);
}
void print_element(TableElement e) { //печать элемента
print_key(e);
putchar(' ');
print_value(e);
printf("\n");
}


void clone_element(TableElement e, TableElement* new) {//копирование элемента
int i;
for (i = 0; i < 3; i++) {
new->key[i] = e.key[i];
}
new->val_size = e.val_size;
new->val = malloc(sizeof(char)*new->val_size);
for (i = 0; i < new->val_size; i++) {
new->val[i] = e.val[i];
}
}[/code]
[code h=300]int read_table(Table* t) { //чтение таблицы
int i;
if (scanf("%d", &(t->size)) != 1) {//получаем размер
return 0;
}
if (t->size < 0) {
return 0;
}
t->elements = malloc(sizeof(TableElement)*t->size); //выделяем память
for (i = 0; i < t->size; i++) {
read_element(&(t->elements[i]));
}
return t->size;
}

void print_table(Table t) { //вывод таблицы в консоль
int i;
for (i = 0; i < t.size; i++) {
print_element(t.elements[i]);
}
}


int search_binary(Table t, TableElement key, TableElement* result) { //бинарный поиск
int l = 0; //левая граница
int r = t.size - 1; //правая
int m;
int cmp;

if (t.size < 1) {
return 0;
}

while (l <= r) { //пока не дойдём до правой
m = (r + l) / 2; //находим середину
cmp = cmp_elements(key, t.elements[m]); //сравниваем с ключом
if (cmp == 0) { //нашли
clone_element(t.elements[m], result); //копируем
return 1; //выходим
} else if (cmp > 0) { //не нашли и ключ больше
l = m + 1; //сдвигаем левую границу в середину
} else { //ключ меньше
r = m - 1; //правую границу
}
}
return 0;
}

int is_sorted(Table* t, int* n_cmps) { //проверка на упорядоченность
int i;
for (i = 0; i < t->size - 1; i++) {
(*n_cmps)++;
if (cmp_elements(t->elements[i], t->elements[i + 1]) == 1) { //если хоть одна пара не упорядочена
return 0;
}
}
return 1;
}

[/code]
Удачи!
Форма ответа