25-Comp-A4 Program Design and Data Structures · December 2019
Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)
Paper format. 17-Comp-A4 Program Design and Data Structures, December 2019 — 3 hours, closed book, no calculator permitted. Nine questions, each of equal weight (Questions 1, 2, 7 and 8 are split 10+10; Questions 3–6 and 9 are 20 marks each), so 180 marks are printed in total. The cover page directs candidates to answer any six of the nine, and only the first six as they appear in the answer book are marked — so a complete paper is $6\times 20 = 120$ marks, which is the "total mark is out of 120" the paper's Note 6 states. Pseudocode or any high-level language (e.g. C or C++) 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.
Check: the printed
typedef struct { ... polynomial_node *next; } polynomial_node;
does not compile — inside an anonymous struct, the name
polynomial_node is not yet in scope for the next
field to refer to. Corrected below to a tagged
struct polynomial_node, which is in scope for its own
next pointer immediately.
Given. (a) A stream of (coefficient, exponent) pairs, sorted by descending exponent, terminated by a sentinel (0,0) pair that is not itself part of the polynomial. (b) Two such lists, $p_1$ and $p_2$, each already sorted by descending exponent.
Find. (a) The head pointer of a new list holding exactly the pairs read before the (0,0) sentinel. (b) The head pointer of a new list representing $p_1(x)+p_2(x)$, still sorted by descending exponent, with matching-exponent terms combined (and any that sum to zero dropped, since $c_i>0$ is required for every stored term).
Note on the worked example below. The question states $c_1,\dots,c_n>0$, so under that convention two matching exponents can never cancel and the “drop a zero sum” branch would be unreachable. The trace therefore relaxes the positivity convention for the second operand only (allowing a negative coefficient) so that the cancellation case the function must handle is actually exercised; every other aspect of the representation — strictly descending exponents, no stored zero coefficients — is kept exactly as the question specifies.
Approach. (a) Read (c,e) pairs in a loop, appending each to the tail of a growing list, and stop (without appending) the moment a (0,0) pair is read. (b) Walk $p_1$ and $p_2$ together like a merge: at matching exponents, add the coefficients and keep the term only if the sum is nonzero; otherwise copy whichever term has the larger exponent (it cannot be matched by anything left in the other, still-descending list) and advance only that pointer.
#include <stdio.h>
#include <stdlib.h>
struct polynomial_node {
int coefficient;
int exponent;
struct polynomial_node *next;
};
typedef struct polynomial_node polynomial_node;
polynomial_node *get_polynomial(void)
{
polynomial_node *head = NULL, *tail = NULL, *node;
int c, e;
while (scanf("%d %d", &c, &e) == 2 && !(c == 0 && e == 0)) {
node = (polynomial_node *) malloc(sizeof(polynomial_node));
node->coefficient = c;
node->exponent = e;
node->next = NULL;
if (head == NULL) head = node;
else tail->next = node;
tail = node;
}
return head;
}3 4 5 2 2 0 0 0,
representing $p_1(x) = 3x^4+5x^2+2$. The loop appends nodes $(3,4)$,
$(5,2)$, $(2,0)$ in order and stops before appending anything for the
$(0,0)$ terminator.
$$\boxed{\text{list} = (3,4)\to(5,2)\to(2,0)\to\text{NULL}}$$polynomial_node *add_polynomials(polynomial_node *p1, polynomial_node *p2)
{
polynomial_node dummy; dummy.next = NULL;
polynomial_node *tail = &dummy, *node;
while (p1 != NULL && p2 != NULL) {
if (p1->exponent == p2->exponent) {
int sum = p1->coefficient + p2->coefficient;
if (sum != 0) { /* drop terms that cancel */
node = (polynomial_node *) malloc(sizeof(polynomial_node));
node->coefficient = sum;
node->exponent = p1->exponent;
node->next = NULL;
tail->next = node; tail = node;
}
p1 = p1->next; p2 = p2->next;
} else if (p1->exponent > p2->exponent) {
node = (polynomial_node *) malloc(sizeof(polynomial_node));
*node = *p1; node->next = NULL;
tail->next = node; tail = node;
p1 = p1->next;
} else {
node = (polynomial_node *) malloc(sizeof(polynomial_node));
*node = *p2; node->next = NULL;
tail->next = node; tail = node;
p2 = p2->next;
}
}
/* copy whichever list still has terms left (already sorted correctly) */
for (; p1 != NULL; p1 = p1->next) {
node = (polynomial_node *) malloc(sizeof(polynomial_node));
*node = *p1; node->next = NULL;
tail->next = node; tail = node;
}
for (; p2 != NULL; p2 = p2->next) {
node = (polynomial_node *) malloc(sizeof(polynomial_node));
*node = *p2; node->next = NULL;
tail->next = node; tail = node;
}
return dummy.next;
}| Part | Input | Result |
|---|---|---|
| (a) | pairs (3,4)(5,2)(2,0)(0,0) | list $(3,4)\to(5,2)\to(2,0)$, i.e. $3x^4+5x^2+2$ |
| (b) | $3x^4{+}5x^2{+}2$ and $-3x^4{+}2x^3{+}x^2{+}7$ | $2x^3+6x^2+9$ (the $x^4$ terms cancel and are dropped) |