Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Сортировка структуры  (Прочитано 22755 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« : 08-12-2010 14:51 » 

Я написал вот такой код:
Код:
#include <windows.h>
#include <iostream.h>
#include <string.h>
#include <conio.h>

int main(void)
{
char *str1 = "Введите количество сотрудников: ";
char *str2 = "Введите Ф.И.О. сотрудника: ";
char *str3 = "Введите номер отдела: ";
char *str4 = "Введите должность сотрудника: ";
char *str5 = "Введите дату с которого сотрудник начал работу в формате дд.мм.гггг: ";
char *str6 = "Введите номер отдела что бы увидеть информацию о сотрудниках данного отдела: ";

struct sotrudniki
{
       char fio[40];
       char nomerotdela[2];
       char dolshnost[20];
       char data[14];
} msotrudniki[100];

// Количество сотрудников
int n;
// Переменные для итерации цикла
int i, j;

// Переменная для указания номера отдела
int numotdel;

sotrudniki temp;

    CharToOem(str1, str1);
    CharToOem(str2, str2);
    CharToOem(str3, str3);
    CharToOem(str4, str4);
    CharToOem(str5, str5);
    CharToOem(str6, str6);
   
    cout << str1;
    cin >> n;
   
    // Заполняем структуру
    for (i = 0; i < n; i++)
    {
        cout << str2;
        cin >> msotrudniki[i].fio;
       
        cout << str3;
        cin >> msotrudniki[i].nomerotdela;
       
        cout << str4;
        cin >> msotrudniki[i].dolshnost;
       
        cout << str5;
        cin >> msotrudniki[i].data;
    }

    // Сортировка
    for (i = 0; i < n; i++)
    {
        for (j = i + 1; j < n; j++)
        {
if (atoi(msotrudniki[i].data) > atoi(msotrudniki[j].data))
{
           temp = msotrudniki[j];
           msotrudniki[j] = msotrudniki[i];
           msotrudniki[i] = temp;
            }
        }
    }
   
    cout << str6;
    cin >> numotdel;
   
    // Вывод
    for (i = 0; i < n; i++)
    {
        if (atoi(msotrudniki[i].nomerotdela) == numotdel)
           cout << msotrudniki[i].fio << " " << msotrudniki[i].dolshnost << " " <<  msotrudniki[i].data << endl;
    }
   
    getch();
    return 0;
}

И если я ввожу следующие:
Введите количество сотрудников: 3
Введите Ф.И.О. сотрудника: ivan
Введите номер отдела: 1
Введите должность сотрудника: admin
Введите дату с которого сотрудник начал работу в формате дд.мм.гггг: 10.12.1981
Введите Ф.И.О. сотрудника: dima
Введите номер отдела: 1
Введите должность сотрудника: admin
Введите дату с которого сотрудник начал работу в формате дд.мм.гггг: 10.11.1981
Введите Ф.И.О. сотрудника: ola
Введите номер отдела: 1
Введите должность сотрудника: admin
Введите дату с которого сотрудник начал работу в формате дд.мм.гггг: 10.11.1982
Введите номер отдела что бы увидеть информацию о сотрудниках данного отдела: 1

И должны выводится в порядке уменьшения рабочего стажа, то есть так:
dima admin 10.11.1981
ivan admin 10.12.1981
ola admin 10.11.1982

А выводится так:
ivan admin 10.12.1981
dima admin 10.11.1981
ola admin 10.11.1982

Как поправить код, подскажите пожалуйста.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 08-12-2010 15:06 » 

zuze, скажи, что по-твоему мнению делает функция atoi?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #2 : 08-12-2010 16:06 » 

Dimka, функция atoi переводит строку в число. И действительно получается так что значение 10.12.1981 больше чем значение 10.11.1981.
Но как же мне тогда отсортировать участок в обратном порядке?
Ведь если я сделаю по возрастанию сортировку, то эта сортировка зацепит и значение 10.11.1982, а это не правильно.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 08-12-2010 16:59 » 

zuze,

#include <algorithm>

//сортируем
std::sort(msotrudniki,msotrudniki+n, <предикат сам напишешь? Улыбаюсь >)
Записан

npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 08-12-2010 18:48 » 

zuze,

для того, чтобы порядок по алфавиту совпадал с хронологическим порядком, нужно использовать формат ггггммдд
то есть даты нужно писать как 20101208
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 08-12-2010 19:31 » 

Цитата: zuze
функция atoi переводит строку в число. И действительно получается так что значение 10.12.1981 больше чем значение 10.11.1981.
Вот я лично не знаю, что такое число "10.11.1981" - это явно не целое, но и не вещественное (не бывает в числе двух запятых, отделяющих целую и дробную части). Функция atoi тоже этого не знает, как и я. Какой из этого следует вывод?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #6 : 09-12-2010 11:43 » new

Dimka, это будет целое число, atoi заменит точку на 46.
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 09-12-2010 11:47 » 

А почему именно на 46? Чем это число лучше любого другого?
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #8 : 09-12-2010 11:51 » 

Dale, по таблице кодов ASCII точке соответствует десятичное значение 46.
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 09-12-2010 11:56 » 

И что, функция atoi преобразует литеру в код ASCII?
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #10 : 09-12-2010 12:07 » 

Dale, я думал да, но как я понял из Ваших постов это не так и там может быть абсолютно любое значение.
Тогда надо удалять сначала точки наверно или atoi убрать и сравнивать строки функцией strcmp.
« Последнее редактирование: 09-12-2010 12:10 от zuze » Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 09-12-2010 12:26 » 

Dale, я думал да, но как я понял из Ваших постов это не так и там может быть абсолютно любое значение.

Когда дело касается библиотечных функций, тут не нужно ничего придумывать. И уж тем более не стоит изучать программирование по нашим постам.

Почитайте хотя бы здесь:

Цитата
Функция atoi (ASCII to integer, из ASCII в целое число) в языке программирования Си используется для приведения (конвертации) строки в числовой вид.

Код: (C)
int atoi(const char *str)

Аргумент str означает строку, представленную в виде массива символов, содержащего символы знакового целого (тип int) числа. Строка должна быть нуль-терминированной, то есть оканчиваться символом «\0». Когда atoi() получает строку без числовых последовательностей, то в этом случае возвращает ноль (0). Если строка содержит корректную последовательность цифр, представляющих число 0, то также возвращается 0, при этом по возвращаемому числу невозможно определить содержит ли строка корректное число или нет. Более новая функция strtol не имеет подобного недостатка.

Если заменить "символы" на "литеры", то будет вполне правдоподобно.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #12 : 10-12-2010 04:59 » 

если даты записать в формате YYYY.MM.DD или YYYYMMDD, то можно их сравнивать как обычнаяе строки, даже в число не надо переводить.
если говорить об atoi, то она перевдить строку в число до тех пор пока не встретить конец строки или символ, который нельзя интерпретировать, как число и т.к. atoi переводитстроку в целое, то она останавливается на первом знаке '.'
собствено, то что уже написал Dale
« Последнее редактирование: 10-12-2010 05:03 от Антон (LogRus) » Записан

Странно всё это....
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #13 : 20-12-2010 12:03 » 

Я решил эту проблему, вот код:

Код:
#include <iostream.h>
#include <windows.h>
#include <string.h>
#include <conio.h>

int main(void)
{
char *str1 = "Введите количество сотрудников: ";
char *str2 = "Введите Ф.И.О. сотрудника: ";
char *str3 = "Введите номер отдела: ";
char *str4 = "Введите должность сотрудника: ";
char *str5 = "Введите день с которого сотрудник начал работу: ";
char *str6 = "Введите месяц с которого сотрудник начал работу: ";
char *str7 = "Введите год с которого сотрудник начал работу в формате гггг: ";
char *str8 = "Введите номер отдела что бы увидеть информацию о сотрудниках данного отдела: ";

struct sotrudniki
{
       char fio[40];
       char nomerotdela[2];
       char dolshnost[20];
       int date[3];
} msotrudniki[100];

// Количество сотрудников
int n;
// Переменные для итерации цикла
int i, j, k;

int date1, date2;

// Переменная для указания номера отдела
int numotdel;

sotrudniki temp;

    CharToOem(str1, str1);
    CharToOem(str2, str2);
    CharToOem(str3, str3);
    CharToOem(str4, str4);
    CharToOem(str5, str5);
    CharToOem(str6, str6);
    CharToOem(str7, str7);
    CharToOem(str8, str8);
   
    cout << str1;
    cin >> n;
   
    // Заполняем структуру
    for (i = 0; i < n; i++)
    {
        cout << str2;
        cin >> msotrudniki[i].fio;
       
        cout << str3;
        cin >> msotrudniki[i].nomerotdela;
       
        cout << str4;
        cin >> msotrudniki[i].dolshnost;
       
        cout << str5;
        cin >> msotrudniki[i].date[0];
       
        cout << str6;
        cin >> msotrudniki[i].date[1];
       
        cout << str7;
        cin >> msotrudniki[i].date[2];
    }

    // Сортировка
    k = n-1;
    bool flag = true;

    while (flag)
    {
        flag = false;
        for (i = 0; i < k; i++)
        {
            date1 = msotrudniki[i].date[2]*10000 + msotrudniki[i].date[1]*100 + msotrudniki[i].date[0];
            date2 = msotrudniki[i+1].date[2]*10000 + msotrudniki[i+1].date[1]*100 + msotrudniki[i+1].date[0];

            if (date1 > date2)
{

           temp = msotrudniki[i];
           msotrudniki[i] = msotrudniki[i+1];
           msotrudniki[i+1] = temp;
           flag = true;
            }
        }
        k--;
        if (k < 0)
           flag = false;
    }
   
    cout << str8;
    cin >> numotdel;
   
    // Вывод
    for (i = 0; i < n; i++)
    {
        if (atoi(msotrudniki[i].nomerotdela) == numotdel)
           cout << msotrudniki[i].fio << " " << msotrudniki[i].dolshnost << " " <<  msotrudniki[i].date[0] << "." << msotrudniki[i].date[1] << "." << msotrudniki[i].date[2] << endl;
    }
   
    getch();
    return 0;
}

Всем спасибо за помощь.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines