Форум программистов, компьютерный форум CyberForum.ru

Создания однонаправленного списка и сохранения в типизированный файл. - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.83
kilik
5 / 5 / 1
Регистрация: 15.11.2010
Сообщений: 58
03.04.2011, 20:24     Создания однонаправленного списка и сохранения в типизированный файл. #1
Доброе время суток. Прошу помощь в решении задачи.
Я совсем запутался с однонаправленным списком. И вторая проблема состоит в том что не могу понять что из себя представляет типизированный файл. Вот условия задачи.

В файле хранятся данные в виде записей формата:
АВТОМОБИЛЬ
Тип
Фирма-изготов.
Объем двигат.
Пробег – М
Цена

Содержимое файла переписать в память в однонаправленный список.
Перестроить список так, чтобы значения поля М записей уменьшались от головы списка к его концу.
Выдать значение трех элементов списка с наибольшим значением поля М.
Выдать значение трех элементов списка с наибольшим значением поля М.
Результирующий список (списки) переписать в результирующий типизированный файл.
выполнить с обязательным использованием типа class

Буду благодарен за любую помощь.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.04.2011, 20:24     Создания однонаправленного списка и сохранения в типизированный файл.
Посмотрите здесь:

C++ Сортировка однонаправленного линейного списка
Сдвиг элементов однонаправленного списка C++
C++ Создание однонаправленного списка
C++ Сортировка однонаправленного списка
Шаблон однонаправленного кольцевого списка C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Vladimir.
155 / 155 / 10
Регистрация: 24.11.2009
Сообщений: 375
04.04.2011, 19:42     Создания однонаправленного списка и сохранения в типизированный файл. #2
в сmd:
  • >car.exe datafile.txt resultfile.txt

nodes
C++
1
2
3
4
5
6
7
8
9
struct nodes{
    char category[str_size];    //категория (тип)
    char company[str_size];     //компания-производитель
    float swept;                //от "swept volume" - литраж
    float mileage;              //пробег(в милях, но нам не важно)
    float price;                //цена автомобиля
    
    nodes* tail;                //тут будет адресс следующего элемента. 
};

my_linked_list
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class my_linked_lists{
    public:
        int add(nodes* node);   //будет добавлять узлы в начало списка
        int gsort(void);        //сортирует список по убыванию пробега
        const nodes* get_node(int i); 
                                //возвращает указатель на i-тый узел.
        
        int size(void)
            {return count;};    //возвращает количество элементов списка
        
        my_linked_lists()   :head(NULL), count(0) {};
        ~my_linked_lists()  {free();};
    private:
        int free();             //освобождает память.
        nodes* head;            //указатель на голову.
        int count;              //количество узлов в списке.
};

его функционал
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
const nodes* my_linked_lists::get_node(int i){
    assert(i>0);
//возвращает указатель на i-тый узел списка, 
// либо NULL если i-того узла не существует
    if(i>count) return NULL;
    nodes* tmp = head;
    for(int j=1;j<i;j++) tmp = tmp->tail;
 
return tmp; 
}
int my_linked_lists::gsort(void){
    if(head == NULL) return 0;      //пустой список отсортирован изначально
    if(head->tail == NULL) return 0;//список из одного элемента - тоже.
    
    nodes** array = new nodes*[count];
    nodes* tmp = head;
    for(int i = 0;i<count;i++){
        array[i] = tmp;
        tmp = tmp->tail;
    }
    //сортировка выбором:
    //1. находим минимальное значение в текущем списке
    //2. производим обмен этого значения со значением на первой неотсортированной позиции
    //3. сортируем хвост списка, исключив из рассмотрения уже отсортированные элементы
    //4.повторяем шаги 1-3, пока массив не будет отсортирован.
    
    for(int sorted = 0;sorted < count-1;sorted++){
        //ищем индекс максимального элемента подстроки:
        int imax = sorted;          
        for(int i = 0;i<count;i++)
            if (array[imax]->mileage < array[i]->mileage)
                imax = i;
        //производим обмен индексов максимального и 
        //первого не отсортированного:
        tmp = array[0]; 
        array[0] = array[imax]; 
        array[imax] = tmp;
    }
    
    //выстраиваем связи в списке согласно упорядоченому массиву:
    head = array[0];
    for(int i = 0;i<count-1;i++)
        array[i]->tail = array[i+1];
    
    array[count-1]->tail = NULL; //последний элемент в массиве.
    //массив больше не нужен - освобождаем память:
    delete array;
    
return 0;
}
int my_linked_lists::add(nodes* node){
// добавляет узел в наш список.
 
    //создадим объект-копию node (для этого копируем все поля node в tmp)
    nodes* tmp = new nodes;
    strcpy(tmp->category,node->category);
    strcpy(tmp->company,node->company);
    tmp->swept      =   node->swept;
    tmp->mileage    =   node->mileage;
    tmp->price      =   node->price;
    
    // теперь добавим объет-копию к нашему связному списку:
    tmp->tail = head;
    head = tmp;
    count++;
    
return 0;
}
int my_linked_lists::free(){
//вызывается деструктором, удаляет узлы списка.
    nodes* tmp = head;      // итерирующий указатель
    while(tmp!=NULL){
        //исключаем из списка, потом удаляем:
        head = tmp->tail;
        delete tmp;
        tmp = head;
        
        count--;
    }
    //список пуст.
return 0;
}


main
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int get_fname(char* fname1, char* fname2, char** argv);
int load_data(char* fname, my_linked_lists* list);
int save_data(char* fname, my_linked_lists* list);
 
int main(int argc, char* argv[]){
 
    char fload[str_size];   //имя фаила из которого читаем
    char fsave[str_size];   //имя фаила в который пишем
    //перехватываем значения параметров командной строки:
    get_fname(fload,fsave,argv);
    //создаем объект класса связный список.
    my_linked_lists list;
    //заполняем его из фаила данных:
    load_data(fload,&list);
    //сортируем:
    list.gsort();
    //сохраняем в фаил результата:
    save_data(fsave,&list);
    
 
return 0;
};


функции чтения/записи через часик-полтора..
kilik
5 / 5 / 1
Регистрация: 15.11.2010
Сообщений: 58
04.04.2011, 20:11  [ТС]     Создания однонаправленного списка и сохранения в типизированный файл. #3
Огромное вам спасибо. Два дня не мог решить эту задачу. Сейчас буду разбираться.
Vladimir.
155 / 155 / 10
Регистрация: 24.11.2009
Сообщений: 375
04.04.2011, 22:21     Создания однонаправленного списка и сохранения в типизированный файл. #4
//в gsort - сортировка выбором с помощью вспомогательного массива.

чтение / запись и параметры командной строки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
int get_fname(char* fname1, char* fname2, char** argv){
//вытаскивает аргументы командной строки
 
    assert((fname1!=NULL) && (fname2!=NULL));
    assert((argv[1]!=NULL)&&(argv[2]!=NULL));
    
    strcpy (fname1,argv[1]);
    strcpy (fname2,argv[2]);
return 0;
}
int load_data(char* fname, my_linked_lists* list){
//считывает данные из фаила и помещает их в связный список.
    assert((list!=NULL) && (fname!=NULL));
    //связываем фаил с потоком:
    std::ifstream fin(fname);
    assert(fin != 0);
    
    //вытаскиваем содержимое фаила и записываем во временный объект:
    char fline[str_size];
    nodes tmp;
    while(fin.good()){ 
    //читаем построчно, записывая в соответсвующие поля tmp
    //здесь я предполагаю, что читается хорошо, и фаил составлен верно
    //так как проверки загромоздят код и снизят его читабельность.
    //должно быть что-то вроде
    //if(!fin.getline(fline,str_size)) <do something on error>..
    fin.getline(tmp.category,str_size);
    fin.getline(tmp.company,str_size);
    //ниже с приведением типа:
    fin.getline(fline,str_size);
    tmp.swept = atof(fline);
    fin.getline(fline,str_size);
    tmp.mileage = atof(fline);
    fin.getline(fline,str_size);
    tmp.price = atof(fline);
    
    //теперь добавим объект в наш список:
    list->add(&tmp);
    //закрываем поток:
    }
    fin.close();
    
    
return 0;
}
int save_data(char* fname, my_linked_lists* list){
//записывает данные связного списка в фаил.
    assert((list!=NULL) && (fname!=NULL));
 
    if (list->size() == 0) return 0; //список пуст.
 
    //связываем фаил с потоком:
    std::ofstream fout(fname);
    assert(fout != 0);  
    //пробегаем по нашему списку закидывая данные в поток:
    for(int i=1;i < list->size();i++){
        fout<<list->get_node(i)->category<<std::endl;
        fout<<list->get_node(i)->company<<std::endl;
        fout<<list->get_node(i)->swept<<std::endl;
        fout<<list->get_node(i)->mileage<<std::endl;
        fout<<list->get_node(i)->price<<std::endl;  
    }
    //последний узел придется закинуть "вручную"
    //дело в том, что продразумевается, что в конце фаила
    //нет пустой строки, т.е. после цены последнего
    //аввтомобиля не должно быть перевода каретки,
    //иначе result невозможно будет использовать в качестве
    //фаила данных
    //если будет желание - решается следующим образом: пишем циклом не в фаил, 
    //а в буфер, потом вытаскиваем последний символ (\n) и
    //отправляем буфер на запись.
    fout<<list->get_node(list->size())->category<<std::endl;
    fout<<list->get_node(list->size())->company<<std::endl;
    fout<<list->get_node(list->size())->swept<<std::endl;
    fout<<list->get_node(list->size())->mileage<<std::endl;
    fout<<list->get_node(list->size())->price;  
 
    fout.close();
    
return 0;
}


хидеры:
#include<assert.h>
#include<string.h>
#include<iostream>
#include<fstream>
#include<stdlib.h>

так же const int str_size =256; после хидеров, например пропишите.

зы: код проверен - работает.


data.txt 30(!) строк
  1. грузовик
  2. камаз
  3. 24.5
  4. 10234
  5. 60000
  6. легковой
  7. мерседес
  8. 4.5
  9. 65443
  10. 120000
  11. легковой
  12. лексус
  13. 5.6
  14. 143342
  15. 200000
  16. джип
  17. лендровер
  18. 7.4
  19. 34221
  20. 75000
  21. легковой
  22. майбах
  23. 4.6
  24. 23443
  25. 350000
  26. велосипед
  27. Витя-корпорейшн
  28. 0
  29. 123566
  30. 120
kilik
5 / 5 / 1
Регистрация: 15.11.2010
Сообщений: 58
04.04.2011, 22:58  [ТС]     Создания однонаправленного списка и сохранения в типизированный файл. #5
Вы просто волшебник. Правда я не все понял но сделано просто супер.
trancelife
1 / 1 / 0
Регистрация: 02.09.2012
Сообщений: 38
10.03.2013, 18:21     Создания однонаправленного списка и сохранения в типизированный файл. #6
Действительно, просто замечательный код!
Но кроме функции сортировки - она не работает. Я переделал вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
      .....
for(int sorted = 0;sorted < count;sorted++){
        int imax = sorted;
        tmp = array[sorted];
          for(int i = sorted + 1;i<count;i++)
             if (array[i]->mileage > tmp->mileage)
               {
                imax = i;
                tmp = array[i];
               }
        array[imax] = array[sorted];
        array[sorted] = tmp;
                .....
Yandex
Объявления
10.03.2013, 18:21     Создания однонаправленного списка и сохранения в типизированный файл.
Ответ Создать тему

Метки
односвязный список, чтение запись в фаил
Опции темы

Текущее время: 13:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru