25-Comp-A4 Program Design and Data Structures · December 2014
Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)
Paper format. 98-Comp-A4 Program Design and Data Structures, December 2014 — 3 hours, closed book, no calculator permitted. Nine questions, each of equal weight (20 marks); candidates answer any six, so a complete paper is 120 marks. Pseudocode or any high-level language is accepted, and the examiner's note states explicitly that marking emphasises the operation of the program, not syntactic details. All nine questions are answered below, because the whole set is the more useful revision resource. Answers are given in C or C++ as the question dictates; each is compilable as written, but a clear, correctly reasoned pseudocode answer would earn the same marks.
Reference texts for this subject.
The Computer Engineering citation list is built around architecture and networking texts (Patterson & Hennessy, Tanenbaum, Mano); this subject is programming and data structures, so the works above are cited instead.
Question text not reproduced: the examination questions are © Engineers and Geoscientists BC. Open the official past paper (linked at the top of this page) to read the question, then follow the worked solution below.
Given. For (a), lines typed at a terminal, the session ending on an empty line, with three worked examples of the required output format. For (b), twenty coordinate pairs to be presented in three different orders.
Find. Two programs: one that echoes each line reversed until an empty line arrives; one that reads twenty points and prints them sorted by increasing $x$, by decreasing $y$, and by increasing distance from the origin.
Approach. Read whole lines with fgets, strip the
newline, and walk the string backwards with an index; for the sorting, define one
comparator per criterion and call the library qsort three times.
scanf("%s", ...) stops at the first space, so
“Computer programming is fun.” would arrive as four separate tokens
and the spaces would be lost. fgets takes the whole line including
its terminating newline, and bounds the read to the buffer size, which
gets famously does not.fgets succeeds, the newline is still in the buffer, so a bare
carriage return arrives as the two-character string containing only a newline.
Overwriting that newline with a terminator —
line[strcspn(line, "\n")] = '\0'; — turns it into the empty
string, which is then the loop's stopping condition. A NULL return
means the input stream itself ended, which must also stop the loop.#include <stdio.h>
#include <string.h>
#define MAXLINE 1024
int main(void)
{
char line[MAXLINE];
int i;
for (;;) {
printf("enter a line of text: ");
if (fgets(line, sizeof line, stdin) == NULL)
break; /* end of input */
line[strcspn(line, "\n")] = '\0'; /* drop the newline fgets kept */
if (line[0] == '\0') /* an empty line ends the run */
break;
printf("the reversed line is: ");
for (i = (int)strlen(line) - 1; i >= 0; i--)
putchar(line[i]);
putchar('\n');
}
return 0;
}x and y
in parallel arrays would require every sort to permute both arrays in step,
which is where such programs usually go wrong. One
Point array lets the library move whole points.qsort comparator on floating-point data is
return (int)(a-b);, which truncates every difference of magnitude
less than 1 to zero and reports unequal points as equal. The idiom
(d > 0) - (d < 0) yields exactly −1, 0 or +1.
#include <stdio.h>
#include <stdlib.h>
#define N 20
typedef struct { double x, y; } Point;
static Point pts[N];
/* Comparators return the SIGN of a difference. Never write
"return (int)(a->x - b->x);" -- truncation makes 0.5 compare equal to 0. */
static int cmp_x_asc(const void *a, const void *b)
{
double d = ((const Point *)a)->x - ((const Point *)b)->x;
return (d > 0) - (d < 0);
}
static int cmp_y_desc(const void *a, const void *b)
{
double d = ((const Point *)b)->y - ((const Point *)a)->y; /* b - a: descending */
return (d > 0) - (d < 0);
}
static double dist2(const Point *p) { return p->x * p->x + p->y * p->y; }
static int cmp_dist_asc(const void *a, const void *b)
{
double d = dist2((const Point *)a) - dist2((const Point *)b);
return (d > 0) - (d < 0);
}
static void show(const char *heading)
{
int i;
printf("%s\n", heading);
for (i = 0; i < N; i++)
printf(" (%g, %g)\n", pts[i].x, pts[i].y);
}
int main(void)
{
int i;
for (i = 0; i < N; i++)
if (scanf("%lf %lf", &pts[i].x, &pts[i].y) != 2) {
fprintf(stderr, "expected %d coordinate pairs\n", N);
return 1;
}
qsort(pts, N, sizeof pts[0], cmp_x_asc);
show("i. increasing x");
qsort(pts, N, sizeof pts[0], cmp_y_desc);
show("ii. decreasing y");
qsort(pts, N, sizeof pts[0], cmp_dist_asc);
show("iii. increasing distance from the origin");
return 0;
}| Point | x | y | Distance from (0,0) |
|---|---|---|---|
| P1 | 3 | 4 | 5.000 |
| P2 | −6 | 8 | 10.000 |
| P3 | 1 | −1 | 1.414 |
| P4 | 0 | 7 | 7.000 |
| P5 | −2 | −3 | 3.606 |
| P6 | 9 | 2 | 9.220 |
| P7 | 4 | −8 | 8.944 |
| P8 | −5 | 1 | 5.099 |
| Item | Result |
|---|---|
| (a) “Computer programming is fun.” | .nuf si gnimmargorp retupmoC |
| (a) “CN Tower” | rewoT NC |
| (a) “hello” | olleh |
| (a) Loop terminates on | an empty line, or end of input |
| (b) i. increasing x | P2, P8, P5, P4, P3, P1, P7, P6 |
| (b) ii. decreasing y | P2, P4, P1, P6, P8, P3, P5, P7 |
| (b) iii. increasing distance from (0,0) | P3, P5, P1, P8, P4, P7, P6, P2 |
| (b) Cost of all three sorts | $O(n \log n)$, no square roots required |