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

Сформировать очеред содержащую весенние даты, упорядоченные только по месяцу и числу. - C++

Восстановить пароль Регистрация
 
mary_fly
0 / 0 / 0
Регистрация: 14.04.2010
Сообщений: 8
14.07.2010, 09:34     Сформировать очеред содержащую весенние даты, упорядоченные только по месяцу и числу. #1
Здравствуйте. Помогите пожалуйста дорешать задачу:
Дан текстовый файл, содержащий даты в формате «день/месяц/год», причем под день месяц отводится по две позиции, а под год – четыре (например, «16/04/2001»). Сформировать очередь содержащую весенние даты, упорядоченные только по месяцу и числу.

Задача почти решена:
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
#include <stdio.h>
#include <stdlib.h> 
#include <string.h> 
int Put(int, int, int);   
int Get(int*, int*, int*);
 
int main()
{
    int day, month, year;
    char filename[50] = "data.txt";
    char str[50];
    FILE *f;
 
    if((f = fopen(filename, "r")) == NULL)
    {
        puts("Nevozmozhno otkrit fail!");
        return 0;
    }
 
    printf("Soderhimoe faila:\n");
    while(!feof(f))
    {
        if(fgets(str,100,f) == NULL) break;
        if(str[strlen(str)-1] == '\n') str[strlen(str)-1] = 0;
        printf("%s\n", str);
 
        sscanf(str, "%d/%d/%d", &day, &month, &year);
 
        if(month > 2 && month < 6)
        {
            if(Put(day, month, year))
            {   
                //Помещение в очередь
                //и проверка результата
                puts("Nehvataet pamyati!");
                break;
            }
        }
    }
    fclose(f);
 
    printf("\nRezultat:\n");
    //Цикл пока в очереди есть значения
    while(!Get(&day, &month, &year)) 
        (day < 10 && month < 10) ? printf("0%d/0%d/%d\n", day, month, year) : (day < 10 && month > 9) ? printf("0%d/%d/%d\n", day, month, year) : printf("%d/0%d/%d\n", day, month, year);
 
    return 0;
}
 
/* ----- Описание структуры и указателей на очередь ---- */
typedef struct _Element{
    int day;
    int month;
    int year;
    struct _Element *next;
} Element;
Element *head = NULL, *tail = NULL;
 
 
/* --------- Функция помещения значения в очередь --------- */
int Put(int day, int month, int year)
{
    //Выделение памяти под новый элемент
    Element *tmp = (Element *)malloc(sizeof(Element));
    if(!tmp) return 1; //Если память не выделилась, то выход
    //Инициализация ссылки на следующий элемент в очереди 
    tmp->next = NULL;                //нулевым значением
 
    tmp->day = day; //Запись значения в новый элемент
    tmp->month = month; //Запись значения в новый элемент
    tmp->year = year; //Запись значения в новый элемент
 
    //Связывание последнего элемента в очереди с новым 
    if(tail) tail->next = tmp;           //элементом
    tail = tmp; //Установка указателя на конец очереди
    //Если это первый элемент,  то установка указателя
    if(!head) head = tmp;         //на начало очереди
    return 0;  //Успешное завершение
}
 
/* --------- Функция получения значения из очереди --------*/
int Get(int* day, int* month, int* year)
{
    if(!head) return 1;  //Если очередь пуста, то выход
 
    Element *tmp = head; //Установка локального указателя
 
    *day = tmp->day;//Запись значения в параметр
    *month = tmp->month;//Запись значения в параметр
    *year = tmp->year;//Запись значения в параметр
 
    head = head->next;   //Установка нового начала очереди
    free(tmp);
    //Если это последний элемент,  то инициализация указателя 
    if(!head) tail=NULL; //на конец очереди нулевым значением
 
    return 0;   //Успешное завершение
}
Из условия не могу понять, вот этот фрагмент Сформировать очеред содержащую весенние даты, упорядоченные только по месяцу и числу.
Насколько я знаю над очередью можно выполнять три операции: добавление элементов, удаление элемент и очищать её.
А как реализовать упорядочивание элементов очереди по месяцу и числу?

спасибо за ответы!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.07.2010, 09:34     Сформировать очеред содержащую весенние даты, упорядоченные только по месяцу и числу.
Посмотрите здесь:

По введеному числу сформировать... C++
C++ Найти все весенние даты.
Упорядочить массив так, чтобы сначала иши упорядоченные положительные члены а потом упорядоченные отрицательные члены C++
C++ По числу и месяцу вывести знак зодиака
Установить порядковый номер дня в году по вводимому числу и месяцу (Переписать со структурой) C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
15.07.2010, 03:20     Сформировать очеред содержащую весенние даты, упорядоченные только по месяцу и числу. #2
Цитата Сообщение от mary_fly
Сформировать очеред содержащую весенние даты
у тебя сделано так, что очередь может быть только одна
очередь, которая создаётся локально

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
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
struct node {
    char *p;
    struct node *next;
};
 
struct queue {
    struct node *head, *tail;
};
 
void CreateQueue(struct queue *pq);
void ClearQueue(struct queue *pq);
int PutQueue(struct queue *pq, struct node *pn);
int GetQueue(struct queue *pq, struct node *pn);
 
/* creates a queue, puts there some elements
   reads the queue and prints every element */
int main(void)
{
    struct queue q;
    struct node n = { "one", NULL };
    struct node m = { "two", NULL };
    
    CreateQueue(&q);
    
    PutQueue(&q, &n);
    PutQueue(&q, &m);
    PutQueue(&q, &n);
    PutQueue(&q, &m);
    PutQueue(&q, &n);
    PutQueue(&q, &m);
        
    while (GetQueue(&q, &n) != 0)
        printf("%s" "\n", n.p);
    
    exit(EXIT_SUCCESS);
}
 
/* CreateQueue:  creates a clear queue pq */
void CreateQueue(struct queue *pq)
{
    pq->head = pq->tail = NULL;
}
 
/* ClearQueue:  clears a queue pq */
void ClearQueue(struct queue *pq)
{
    struct node *tmp;
    
    while ((tmp = pq->head) != NULL) {
        pq->head = tmp->next;
        free(tmp);
    }
    pq->tail = NULL;
}
 
/* PutQueue:  puts to a queue pq a node pn;
              returns 1 or 0 */
int PutQueue(struct queue *pq, struct node *pn)
{
    struct node *tmp;
    
    tmp = (struct node *) malloc(sizeof(struct node));
    
    if (tmp == NULL)
        return 0;
    
    *tmp = *pn;
    tmp->next = NULL;
    
    if (pq->head == NULL)
        pq->head = pq->tail = tmp;
    else {
        pq->tail->next = tmp;
        pq->tail = tmp;
    }
    
    return 1;
}
 
/* GetQueue:  gets from a queue pq a node pn;
              returns 1 or 0 */
int GetQueue(struct queue *pq, struct node *pn)
{
    struct node *tmp;
    
    if (pq->head == NULL) {
        pq->tail = NULL;
        return 0;
    }
    
    tmp = pq->head;
    *pn = *tmp;
    pq->head = tmp->next;    
    free(tmp);
    
    return 1;
}
(лучше возвращать: 0 - успех, остальное - сбой)

сделай вторую очередь, туда выберешь из первой очереди весенние даты
(можешь из первой удалить не весенние даты, а вдруг другие нужны будут потом)

Цитата Сообщение от mary_fly
упорядоченные только по месяцу и числу
отсортировать новую очередь
(можно первую отсортировать, прикинь, у тебя дат на целый год, ты будешь сортировать все даты, а потом большую часть удалять, а зачем)

Цитата Сообщение от mary_fly
можно выполнять три операции: добавление элементов, удаление элемент и очищать её.
можно ещё делать peek() - это просмотр без извлечения
сортировку свою писать надо, так как это список, то и делать можно всё, что можно со списком делать, сохраняя очередь (её функции, свойства)
mary_fly
0 / 0 / 0
Регистрация: 14.04.2010
Сообщений: 8
15.07.2010, 09:19  [ТС]     Сформировать очеред содержащую весенние даты, упорядоченные только по месяцу и числу. #3
даты хранятся в текстовом файле, и я при считывании файла выбираю весенние даты в очередь. поэтому создавать вторую очередь не вижу смысла.

может есть примерчик как отсортировать очередь?
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
15.07.2010, 10:28     Сформировать очеред содержащую весенние даты, упорядоченные только по месяцу и числу. #4
можно сортировать очередь (тебе придётся менять head и tail, так как они могут переместиться), а можно сортировать массив через qsort()
это нужно функцию Sort(), которая принимает указатель на head, на tail и указатель на функцию, которая определяет что должно быть слева, а что справа

Добавлено через 1 минуту
при сортировке массива, вытаскиваешь из очереди в массив, потом сортируешь его, а потом обратно в очередь

Добавлено через 7 минут
попробуй printf("%02d/%02d/%04d", ...)

Добавлено через 1 минуту
C
1
char str[50];
C
1
if(fgets(str,100,f) == NULL) break;
надо
C
1
while (fgets(str, sizeof str, f) != NULL)
Добавлено через 1 минуту
C
1
2
3
4
5
        if((f = fopen(filename, "r")) == NULL)
        {
                puts("Nevozmozhno otkrit fail!");
                return 0;
        }
C
1
2
3
4
    if((f = fopen(filename, "r")) == NULL) {
        fprintf(stderr, "error: Nevozmozhno otkrit fail!" "\n");
        return 1;
    }
или так
C
1
2
3
4
    if((f = fopen(filename, "r")) == NULL) {
        fputs("error: Nevozmozhno otkrit fail!" "\n", stderr);
        return 1;
    }
Добавлено через 5 минут
под виндовсом переменная %errorlevel%, её можно проверить на 0 или 1 (в .bat'нике) и сделать соответствующее действие
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9373 / 5423 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
15.07.2010, 14:37     Сформировать очеред содержащую весенние даты, упорядоченные только по месяцу и числу. #5
mary_fly, вот вся програмка, вроде работает...
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <stdio.h>
#include <stdlib.h>
 
typedef struct tagDATE {
    int day;
    int month;
    int year;
    struct tagDATE * prev;
    struct tagDATE * next;
} date_t;
 
typedef struct tagDATEQUEUE {
    date_t * first;
    date_t * last;
} datequeue_t;
 
void clear_queue(datequeue_t * queue){
    date_t * tmp;
    while ( queue->first ){
        tmp = queue->first->next;
        free(queue->first);
        queue->first = tmp;
    }
}
 
int cmp_dates(const date_t * a, const date_t * b){
    if ( a->month == b->month )
        return a->day - b->day;
    return a->month - b->month;
}
 
date_t * dup_date(const date_t * od){
    date_t * nd;
    if ( ( nd = (date_t*)malloc(sizeof(date_t)) ) == NULL )
        return NULL;
    nd->day = od->day;
    nd->month = od->month;
    nd->year = od->year;
    nd->prev = nd->next = NULL;
    return nd;
}
 
date_t * insert_before(date_t * existing, const date_t * newone){
    date_t * toAdd;
    if ( ( toAdd = dup_date(newone) ) == NULL )
        return NULL;
    if ( existing->prev )
        existing->prev->next = toAdd;
    toAdd->prev = existing->prev;
    toAdd->next = existing;
    existing->prev = toAdd;
    return toAdd;
}
 
int add_to_queue(datequeue_t * dq, const date_t * date){
    date_t * curDate;
    if ( dq->first == NULL ){
        if ( ( dq->first = dup_date(date) ) == NULL )
            return -1;
        dq->last = dq->first;
        return 0;
    }
    else {
        for ( curDate = dq->first; curDate != NULL && cmp_dates(curDate, date) < 0; curDate = curDate->next )
            ;
        if ( curDate == NULL ){
            if ( ( curDate = dup_date(date) ) == NULL )
                return -1;
            curDate->prev = dq->last;
            dq->last->next = curDate;
            dq->last = curDate;
            return 0;
        }
        else if ( curDate == dq->first ){
            if  ( ( dq->first = insert_before(dq->first, date) ) == NULL )
                return -1;
            return 0;
        }
        else
            return ( insert_before(curDate, date) ) ? 0 : -1;
    }
}
 
void print_dates(const datequeue_t * dq){
    const date_t * curDate;
    for ( curDate = dq->first; curDate != NULL; curDate = curDate->next )
        printf("%02d/%02d/%04d\n", curDate->day, curDate->month, curDate->year);
}
 
int date_from_file(FILE * fin, date_t * date){
    return fscanf(fin, "%d/%d/%d", &date->day, &date->month, &date->year) - 3;
}
 
#define FILE_NAME "dates.txt"
#define LO_MONTH 3
#define HI_MONTH 5
 
int main(void){
    FILE * fin;
    date_t oneDate;
    datequeue_t dq;
 
    dq.first = dq.last = NULL;
 
    if ( ( fin = fopen(FILE_NAME, "r") ) == NULL ){
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    while ( date_from_file(fin, &oneDate) == 0 ){
        if ( oneDate.month >= LO_MONTH && oneDate.month <= HI_MONTH ){
            if ( add_to_queue(&dq, &oneDate) ){
                fprintf(stderr, "Can't insert date in queue!\n");
                exit(EXIT_FAILURE);
            }
        }
    }
    fclose(fin);
 
    if ( dq.first == NULL ){
        fprintf(stderr, "No dates in queue!\n");
        exit(EXIT_FAILURE);
    }
 
    print_dates(&dq);
 
    clear_queue(&dq);
    exit(EXIT_SUCCESS);
}
Yandex
Объявления
15.07.2010, 14:37     Сформировать очеред содержащую весенние даты, упорядоченные только по месяцу и числу.
Ответ Создать тему
Опции темы

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