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

Телефонный справочник - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 22, средняя оценка - 4.59
Kir555
0 / 0 / 0
Регистрация: 27.05.2012
Сообщений: 21
27.10.2013, 10:34     Телефонный справочник #1
Всем привет!
Задачка в двух словах такова. Надо сделать телефонный справочник, чтоб можно было добавлять ФИО №телефона, затем отсортировать (быстрой сортировочкой) и вывести на экран.
А теперь куча вопросов. QuickSort неправильно сделал, что очевидно. Так как, собственно, организовать сортировку? Возможно ли это сделать с помощью <algorithm> ?
Стоит ли считывать структуры с помощью указателя? Не лучше ли использовать vector? А если и лучше, то как использовать его конкретно в данной ситуации?..
Преподают нам пока что Си, но случайно открыл на себя эти интересненькие потоки, так что писал на них. А раз уж начал использовать синтаксис Си++, то надо довести эту прогу до конца. Но сам уже запутался. Хотя бы подскажите направление для мыслей. На большее не рассчитываю).. Собственно, сам код:

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
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdlib>
 
using namespace std;
 
struct reg{
    char number[20];
    char name[20];
    char naame[20];
    char naaame[20];
    struct reg *next;
};
 
template<class T>
void quickSort(T* a,long N) {
    long i=0, j=N;                  //установка указателей на исходные места
    T temp, p;
    p = a[N>>1].name;                   //центральный элемент
    //разделение
    do {
        while (a[i].name < p) i++;
        while (a[j].name > p) j--;
        
        if (i <= j) {
            temp = a[i];
            a[i] = a[j];
            a[j] = temp;
            i++;
            j--;
        }
    } while (i<=j);
    
    //если еще осталось, что сортировать
    if (j>0) quickSort(a,j);
    if (N>i) quickSort(a+i,N-i);
}
 
int main(){
    int i=1;
    struct reg *r= new reg;
    setlocale(LC_ALL,"Russian");
    ifstream fin("/home/kirill/Рабочий стол/phone.txt");
    if (!fin.is_open()){
        cout<<"Не могу открыть файл!";
        return 0;
    }
    fin>>r->name>>r->naame>>r->naaame>>r->number;
    cout<<r->name<<' '<<r->naame<<' '<<r->naaame<<' '<<r->number<<endl;
    reg *tmp=r;
    while (true){
        tmp->next=new reg;
        tmp=tmp->next;
        fin>>tmp->name>>tmp->naame>>tmp->naaame>>tmp->number;
        if (fin.eof()) break;
        cout<<tmp->name<<' '<<tmp->naame<<' '<<tmp->naaame<<' '<<tmp->number<<endl;
        i++;
    }
    
 
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.10.2013, 10:34     Телефонный справочник
Посмотрите здесь:

телефонный справочник C++
C++ Телефонный справочник.
телефонный справочник C++
Телефонный справочник C++
Телефонный справочник C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Max Dark
В поиске работы
 Аватар для Max Dark
1546 / 1399 / 501
Регистрация: 09.10.2013
Сообщений: 3,185
Записей в блоге: 8
Завершенные тесты: 2
27.10.2013, 10:41     Телефонный справочник #2
Вы сравниваете указатели на строки, а не сами строки
Используйте strcmp
Kir555
0 / 0 / 0
Регистрация: 27.05.2012
Сообщений: 21
27.10.2013, 10:45  [ТС]     Телефонный справочник #3
Strcmp в быстрой сортировке использовать? А, собственно, как? Уж извините, очень скудное представление... обо всем этом)
Max Dark
В поиске работы
 Аватар для Max Dark
1546 / 1399 / 501
Регистрация: 09.10.2013
Сообщений: 3,185
Записей в блоге: 8
Завершенные тесты: 2
27.10.2013, 11:00     Телефонный справочник #4
строки 23-24 замените на
C++
1
2
while (strcmp(a[i].name , p.name) < 0) i++;
while (strcmp(a[j].name , p.name) > 0) j--;
и добавьте #include <cstring>

Добавлено через 4 минуты
Кроме того, у вас использован односвязный список, а не массив
Поэтому работать с ним как с массивом нельзя
Kir555
0 / 0 / 0
Регистрация: 27.05.2012
Сообщений: 21
27.10.2013, 11:01  [ТС]     Телефонный справочник #5
Так, это понятно. Но реализовать надо сортировку, в случае совпадения фамилии, еще и по имени, а потом и по отчеству, ну и для номера, чтоб уж наверняка. Для этого надо сам quickSort расширять, добавив пару if'ов, или делать отдельную функцию сравнения?..

Добавлено через 1 минуту
То есть отсортировать у меня его не получится таким образом? Может, сортировать тогда по указателям надо...
Zig_Stas
8 / 8 / 1
Регистрация: 26.10.2013
Сообщений: 55
27.10.2013, 11:21     Телефонный справочник #6
Цитата Сообщение от Kir555 Посмотреть сообщение
Так, это понятно. Но реализовать надо сортировку, в случае совпадения фамилии, еще и по имени, а потом и по отчеству, ну и для номера, чтоб уж наверняка. Для этого надо сам quickSort расширять, добавив пару if'ов, или делать отдельную функцию сравнения?..

Добавлено через 1 минуту
То есть отсортировать у меня его не получится таким образом? Может, сортировать тогда по указателям надо...
Не нужно кучу ИФ-ов и расширять квиксорт. Просто сравнивайте строки посимвольно. Как раз через strcmp.
если совпадут фамилии, сразу же открывайте условие по совпадению имени и так далее
Kir555
0 / 0 / 0
Регистрация: 27.05.2012
Сообщений: 21
27.10.2013, 11:29  [ТС]     Телефонный справочник #7
Ну, это я уже понял) Дело в том, что я плохо представляю, как это реализовать. Тут ведь еще и односвязный список. Иначе realloc, ну или вектор. Последний симпатичней, но непонятен в данном случае. Сделать цикл, в котором и будет идти сравнение? А, собственно, как уже применить и quickSort... Еще больше вопросов. Ну да ладно, буду что-то придумывать. Всем спасибо
Zig_Stas
8 / 8 / 1
Регистрация: 26.10.2013
Сообщений: 55
27.10.2013, 11:38     Телефонный справочник #8
Цитата Сообщение от Kir555 Посмотреть сообщение
Ну, это я уже понял) Дело в том, что я плохо представляю, как это реализовать. Тут ведь еще и односвязный список. Иначе realloc, ну или вектор. Последний симпатичней, но непонятен в данном случае. Сделать цикл, в котором и будет идти сравнение? А, собственно, как уже применить и quickSort... Еще больше вопросов. Ну да ладно, буду что-то придумывать. Всем спасибо
Как уже выше говорили, использовать цикл для односвязного списка нельзя. Тебе лучше создать массив структур и сравнивать структурки по полям(опять же через strcmp)
Kir555
0 / 0 / 0
Регистрация: 27.05.2012
Сообщений: 21
27.10.2013, 11:44  [ТС]     Телефонный справочник #9
Я не знаю наверняка, сколько будет в массиве структур элементов. Для "расширения" массива подходят, как я знаю, realloc и vector. Vector вроде лучше, но не знаю я, как им пользоваться. Да разберусь уж как-то, тут уж такие рядовые вопросы порядком поднадоели всем)
Zig_Stas
8 / 8 / 1
Регистрация: 26.10.2013
Сообщений: 55
27.10.2013, 11:49     Телефонный справочник #10
Цитата Сообщение от Kir555 Посмотреть сообщение
Я не знаю наверняка, сколько будет в массиве структур элементов. Для "расширения" массива подходят, как я знаю, realloc и vector. Vector вроде лучше, но не знаю я, как им пользоваться. Да разберусь уж как-то, тут уж такие рядовые вопросы порядком поднадоели всем)
Не знаете, сколько будет структурок в массиве? В помощь вам динамический массив=)
Kir555
0 / 0 / 0
Регистрация: 27.05.2012
Сообщений: 21
27.10.2013, 11:54  [ТС]     Телефонный справочник #11
Так вот в нем-то и надо реализовать постепенное добавление к массиву, чтоб не выделять наперед памяти со 100500 элементами. Мне, в качестве решения, предложили поработать с указателями... А вот насчет сортировки... Буду переставлять указатели. Пофиг на quickSort, как-то должна все-таки работать эта прога. Ну снизят немного, пусть)
Max Dark
В поиске работы
 Аватар для Max Dark
1546 / 1399 / 501
Регистрация: 09.10.2013
Сообщений: 3,185
Записей в блоге: 8
Завершенные тесты: 2
27.10.2013, 12:33     Телефонный справочник #12
накалякал небольшого монстра %)
strsort.h
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef STRSORT_H
#define STRSORT_H
 
#include <cstring>
typedef enum {
    NAME, SUBNAME,
    FAMILY, NUMBER
    }sortby;
typedef struct {
    char name[20];
    char subname[20];
    char family[20];
    char number[20];
} record;
 
int compare(record* first,
    record* second,
    sortby by);
#endif // STRSORT_H
srtsort.cpp
Кликните здесь для просмотра всего текста
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
#include "strsort.h"
 
int compare(record* first,
    record* second,
    sortby by) {
    int result = 0;
    switch(by) {
    case NAME:
        result = strcmp(first->name, second->name);
        if (result == 0)
            result = strcmp(first->subname, second->subname);
        if (result == 0)
            result = strcmp(first->family, second->family);
        if (result == 0)
            result = strcmp(first->number, second->number);
        break;
    case SUBNAME:
        result = strcmp(first->subname, second->subname);
        if (result == 0)
            result = strcmp(first->name, second->name);
        if (result == 0)
            result = strcmp(first->family, second->family);
        if (result == 0)
            result = strcmp(first->number, second->number);
        break;
    case FAMILY:
        result = strcmp(first->family, second->family);
        if (result == 0)
            result = strcmp(first->name, second->name);
        if (result == 0)
            result = strcmp(first->subname, second->subname);
        if (result == 0)
            result = strcmp(first->number, second->number);
        break;
    default: // NUMBER
        result = strcmp(first->number, second->number);
        if (result == 0)
            result = strcmp(first->name, second->name);
        if (result == 0)
            result = strcmp(first->subname, second->subname);
        if (result == 0)
            result = strcmp(first->family, second->family);
        break;
    }
    return result;
}
strmain.cpp
Кликните здесь для просмотра всего текста
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
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include "strsort.h"
 
inline int cmpname(record first, record second)
{ return compare(&first, &second, NAME); }
 
inline int cmpsubname(record first, record second)
{ return compare(&first, &second, SUBNAME); }
 
inline int cmpfamyly(record first, record second)
{ return compare(&first, &second, FAMILY); }
 
inline int cmpnumber(record first, record second)
{ return compare(&first, &second, NUMBER); }
 
void printbase(std::vector<record> base) {
    for(int i=0;i<base.size(); i++)
        std::cout<<base[i].name<<'\t'
                <<base[i].subname<<'\t'
                <<base[i].family<<'\t'
                <<base[i].number<<std::endl;
}
 
int main(int argc, char** argv) {
    std::vector<record> base;
    record temp;
    if (argc != 2) {
        std::cerr<<"usage: "<< argv[0] <<" <fileneme>"<<std::endl;
        return -1;
    }
    std::ifstream fin(argv[1]);
    if(!fin.is_open()) {
        std::cerr<<"Cant open file: "<<argv[1]<<std::endl;
        return -2;
    }
    while(!fin.eof()) {
        fin>>temp.name>>temp.subname>>temp.family>>temp.number;
        base.push_back(temp);
    }
    std::cout<<"Total records in file: "<<base.size()<<std::endl;
    std::cout<<"Unsorted records:"<<std::endl;
    printbase(base);
    std::cout<<"Sorted by name records:"<<std::endl;
    std::sort(base.begin(), base.end(), cmpname);
    printbase(base);
    return 0;
}
Kir555
0 / 0 / 0
Регистрация: 27.05.2012
Сообщений: 21
27.10.2013, 12:49  [ТС]     Телефонный справочник #13
Вообще молодец)) Монстрик реально хорош Заодно познакомился с inline)) Только еще вопрос) Библиотеку эту первую STRSORT_H можно написать в самом коде?)
Max Dark
В поиске работы
 Аватар для Max Dark
1546 / 1399 / 501
Регистрация: 09.10.2013
Сообщений: 3,185
Записей в блоге: 8
Завершенные тесты: 2
27.10.2013, 12:54     Телефонный справочник #14
вот одним файлом
Кликните здесь для просмотра всего текста
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
 
typedef enum {
    NAME, SUBNAME,
    FAMILY, NUMBER
    }sortby;
typedef struct {
    char name[20];
    char subname[20];
    char family[20];
    char number[20];
} record;
 
 
int compare(record* first,
    record* second,
    sortby by) {
    int result = 0;
    switch(by) {
    case NAME:
        result = strcmp(first->name, second->name);
        if (result == 0)
            result = strcmp(first->subname, second->subname);
        if (result == 0)
            result = strcmp(first->family, second->family);
        if (result == 0)
            result = strcmp(first->number, second->number);
        break;
    case SUBNAME:
        result = strcmp(first->subname, second->subname);
        if (result == 0)
            result = strcmp(first->name, second->name);
        if (result == 0)
            result = strcmp(first->family, second->family);
        if (result == 0)
            result = strcmp(first->number, second->number);
        break;
    case FAMILY:
        result = strcmp(first->family, second->family);
        if (result == 0)
            result = strcmp(first->name, second->name);
        if (result == 0)
            result = strcmp(first->subname, second->subname);
        if (result == 0)
            result = strcmp(first->number, second->number);
        break;
    default: // NUMBER
        result = strcmp(first->number, second->number);
        if (result == 0)
            result = strcmp(first->name, second->name);
        if (result == 0)
            result = strcmp(first->subname, second->subname);
        if (result == 0)
            result = strcmp(first->family, second->family);
        break;
    }
    return result;
}
 
inline int cmpname(record first, record second)
{ return compare(&first, &second, NAME); }
 
inline int cmpsubname(record first, record second)
{ return compare(&first, &second, SUBNAME); }
 
inline int cmpfamyly(record first, record second)
{ return compare(&first, &second, FAMILY); }
 
inline int cmpnumber(record first, record second)
{ return compare(&first, &second, NUMBER); }
 
void printbase(std::vector<record> base) {
    for(int i=0;i<base.size(); i++)
        std::cout<<base[i].name<<'\t'
                <<base[i].subname<<'\t'
                <<base[i].family<<'\t'
                <<base[i].number<<std::endl;
}
 
int main(int argc, char** argv) {
    std::vector<record> base;
    record temp;
    if (argc != 2) {
        std::cerr<<"usage: "<< argv[0] <<" <fileneme>"<<std::endl;
        return -1;
    }
    std::ifstream fin(argv[1]);
    if(!fin.is_open()) {
        std::cerr<<"Cant open file: "<<argv[1]<<std::endl;
        return -2;
    }
    while(!fin.eof()) {
        fin>>temp.name>>temp.subname>>temp.family>>temp.number;
        base.push_back(temp);
    }
    std::cout<<"Total records in file: "<<base.size()<<std::endl;
    std::cout<<"Unsorted records:"<<std::endl;
    printbase(base);
    std::cout<<"Sorted by name records:"<<std::endl;
    std::sort(base.begin(), base.end(), cmpname);
    printbase(base);
    return 0;
}
Kir555
0 / 0 / 0
Регистрация: 27.05.2012
Сообщений: 21
27.10.2013, 13:58  [ТС]     Телефонный справочник #15
Ну, в принципе, да, что эт я)... Все откликнувшимся большое спасибо, особенно Cra3y! Задача уже решена, причем хорошо так решена)))

Добавлено через 57 минут
Кстати, сортировка все равно неадекватно работает. Так что печаль-беда таковой и осталась)
Max Dark
В поиске работы
 Аватар для Max Dark
1546 / 1399 / 501
Регистрация: 09.10.2013
Сообщений: 3,185
Записей в блоге: 8
Завершенные тесты: 2
27.10.2013, 14:32     Телефонный справочник #16
Замените функции
C++
1
2
3
4
5
6
7
8
9
10
11
inline bool cmpname(record first, record second)
{ return compare(&first, &second, NAME)>0; }
 
inline bool cmpsubname(record first, record second)
{ return compare(&first, &second, SUBNAME)>0; }
 
inline bool cmpfamyly(record first, record second)
{ return compare(&first, &second, FAMILY)>0; }
 
inline bool cmpnumber(record first, record second)
{ return compare(&first, &second, NUMBER)>0; }
справка по std::sort
Kir555
0 / 0 / 0
Регистрация: 27.05.2012
Сообщений: 21
27.10.2013, 16:47  [ТС]     Телефонный справочник #17
Заменил... Но sort работает так, как в той справке на примере, которую вы скинули)..

Добавлено через 54 секунды
То есть берет и меняет список в обратном порядке...
Max Dark
В поиске работы
 Аватар для Max Dark
1546 / 1399 / 501
Регистрация: 09.10.2013
Сообщений: 3,185
Записей в блоге: 8
Завершенные тесты: 2
27.10.2013, 16:49     Телефонный справочник #18
Скинте пример файла, посмотрю
Kir555
0 / 0 / 0
Регистрация: 27.05.2012
Сообщений: 21
27.10.2013, 16:56  [ТС]     Телефонный справочник #19
phone.txt

Например)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.10.2013, 17:45     Телефонный справочник
Еще ссылки по теме:

C++ Телефонный справочник.
C++ Телефонный справочник
C++ телефонный справочник

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Max Dark
В поиске работы
 Аватар для Max Dark
1546 / 1399 / 501
Регистрация: 09.10.2013
Сообщений: 3,185
Записей в блоге: 8
Завершенные тесты: 2
27.10.2013, 17:45     Телефонный справочник #20
record.cpp.txt
phone.txt
Сейчас сортирует по алфавиту
из багов - программа не обрабатывает двойные имена фамилии
Yandex
Объявления
27.10.2013, 17:45     Телефонный справочник
Ответ Создать тему
Опции темы

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