-
Notifications
You must be signed in to change notification settings - Fork 1
/
7.c
148 lines (120 loc) · 3.5 KB
/
7.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/**
* The time results are about the same as in v1.
*/
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000 /* Maximum number of lines to be sorted */
#define MAXLEN 1000 /* Maximum length of a input line */
/**
* @brief Read and store lines from input
*
* @param lineptr Array of pointers to lines
* @param lines 2D array to store lines values at
* @param maxlines Maximum number of lines to be read
*
* @return int Number of read lines (success) or -1 (failure)
*/
int readlines(char *lineptr[], char lines[MAXLINES][MAXLEN], int maxlines);
/**
* @brief Write sorted lines to output.
*
* @param lineptr Array of pointer to sorted lines
* @param nlines Number of lines to be printed
*/
void writelines(char *lineptr[], int nlines);
/**
* @brief Sort an array of text lines.
*
* @param lineptr Input array to be sorted
* @param left Index of first position to start sorting
* @param right Index of last position to sort
*/
void qsort(char *lineptr[], int left, int right);
/* Sort input lines */
main()
{
char *lineptr[MAXLINES]; /* Array of pointers to lines */
char lines[MAXLINES][MAXLEN]; /* 2D Array of text lines */
int nlines; /* Number of read lines */
if ((nlines = readlines(lineptr, lines, MAXLINES)) >= 0) {
qsort(lineptr, 0, nlines-1);
writelines(lineptr, nlines);
} else {
printf("[*]\tError:\tInput too big to sort!\n");
return -1;
}
return 0;
}
/**
* @brief Read a line into s
*
* @param s Pointer to character array where line will be saved
* @param lim Max number of characters read per line
*
* @return int Length of s
*/
int getline(char *s, int lim)
{
char *aux = s;
int c, n = 0;
while (n < lim && (c = getchar()) != EOF && c != '\n') {
*s++ = c;
n += 1;
}
*s = '\0';
return s - aux;
}
/**
* HINT: 'lines' is declared like this because we know its size at compile time.
* 'lineptr', at the other hand, is an array of pointers where each
* position points to an char array of unknown size (dinamically
* allocated). In this exercise we are not allocating dinamically, we use
* 'lines' to hold our read lines and 'lineptr' points to it. Sorting
* is easier this way.
*/
int readlines(char *lineptr[], char lines[MAXLINES][MAXLEN], int maxlines)
{
int len, nlines = 0;
char line[MAXLEN];
while ((len = getline(line, MAXLEN)) > 0) {
if (nlines >= maxlines)
return -1;
strcpy(lines[nlines], line); /* Copy to permanent storage */
lineptr[nlines++] = lines[nlines]; /* Assign its pointer */
}
return nlines;
}
void writelines (char *lineptr[], int nlines)
{
int i = 0;
while (nlines-- > 0)
printf("[%4d]\t=>\t\"%s\"\n", i++, *lineptr++);
}
void qsort(char *v[], int left, int right)
{
int i, last;
/**
* Forward declaration in old C style (pre-C90). We could just define swap
* function before qsort.
*/
void swap(char *v[], int i, int j);
/* Do nothing if there are less than two elements */
if (left >= right)
return;
swap(v, left, (left + right)/2);
last = left;
for (i = left + 1; i <= right; i++) {
if (strcmp(v[i], v[left]) < 0)
swap(v, ++last, i);
}
swap(v, left, last);
qsort(v, left, last-1);
qsort(v, last+1, right);
}
void swap(char *v[], int i, int j)
{
char *temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}