Commit 7c3386bc authored by Christophe Rhodes's avatar Christophe Rhodes
Browse files

updates to 04

parent fb1954ae
#+TITLE: Algorithms & Data Structures: Lab 04
#+SUBTITLE: week of 22nd October 2018
#+include: ../labsheet.org
* Setup
** Saving your work from last week
As with previous weeks, you will use =git= to download a bundle of
lab code. You might have made modifications in your downloaded
copy; if you have not already done so, you need to save those
modifications. First examine the changes present in your
downloaded copy by issuing the following commands from the labs
directory:
#+begin_example
git status
git diff
#+end_example
and if you are satisfied with the changes, store them in the git
version control system by doing
#+begin_example
git commit -a
#+end_example
and writing a suitable commit message
** Downloading this week's distribution
Once you have successfully saved your changes from last week, you
can get my updates by doing
#+begin_example
git pull
#+end_example
which /should/ automatically merge in new content. After the =git
pull= command, you should have a new directory containing this
week's material (named =04/=) alongside the existing directories.
* Linked Lists
** Basic implementation
Implement a ~SLList~ linked-list class, whose basic methods are:
~first()~, ~rest()~, ~setFirst()~, and ~setRest()~. The class must
be able to store /at least/ the default integer range in your
programming language; the “rest” must be a reference or pointer to
another ~SLList~, including the special ~SLList~ object ~NIL~.
You should also provide a two-argument constructor, which
initializes the instance with the first argument as the first, and
the second argument as the rest, of the resulting ~SLList~.
I have provided skeleton code under =04/= to help you structure
your work, and tests for this functionality which can be run using
~make test~ as usual.
** Derived methods
Extend your implementation of linked lists to support three
additional methods, which you should be able to implement in terms
of the existing ones or directly:
- ~nth()~ :: return the n^{th} item stored in the list, counting from
0 (so ~nth(0)~ should return the first item)
- ~nthRest()~ :: return the n^{th} rest of the list, counting from
0 (so ~nthRest(0)~ should return the given list
itself)
- ~length()~ :: return the length of the list.
I have provided tests for ~nth()~ and ~nthRest()~; you are
responsible for testing your own implementation of ~length()~. How
can you assure yourself that your implementation is correct? How
can you convince the person working next to you?
** More derived methods
You might wish to work through the [[http://www.doc.gold.ac.uk/~mas01cr/teaching/is52038b/2018-19/ListAlgorithms.html][interactive exercise]] related to
recursively-expressed algorithms on linked lists, available from
the [[https://learn.gold.ac.uk/course/view.php?id=11491][module VLE page]].
** Submission
There will be a submission related to this lab in two weeks
(deadline *16:00 9th November 2018*); you will be asked to submit
work based on your implementation of the ~SLList~ class. Make sure
you save your work, and that you understand what is going on.
#include <cppunit/extensions/HelperMacros.h>
#include "SLList.hpp"
class BasicSLListTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(BasicSLListTest);
CPPUNIT_TEST(testConstructor);
CPPUNIT_TEST(testGetFirst);
CPPUNIT_TEST(testSetFirst);
CPPUNIT_TEST(testSetRest);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() { };
void tearDown() { };
void testConstructor();
void testGetFirst();
void testSetFirst();
void testSetRest();
};
void BasicSLListTest::testConstructor() {
SLList *n = new SLList(0, SLList::NIL);
CPPUNIT_ASSERT_MESSAGE("The SLList constructor must never return NULL", n != NULL);
CPPUNIT_ASSERT_EQUAL_MESSAGE("The SLList constrctor must treat its first argument as the item (or first() isn't working yet)", 0, n->first());
CPPUNIT_ASSERT_EQUAL_MESSAGE("The SLList constructor must treat its second argument as the next SLList (or rest() isn't working yet)", SLList::NIL, n->rest());
SLList *nn = new SLList(104, n);
CPPUNIT_ASSERT_MESSAGE("The SLList constructor must never return NULL", nn != NULL);
CPPUNIT_ASSERT_EQUAL_MESSAGE("The SLList constrctor must treat its first argument as the item (or first() isn't working yet); something might be defaulting to 0", 104, nn->first());
CPPUNIT_ASSERT_EQUAL_MESSAGE("The SLList constructor must treat its second argument as the next SLList (or rest() isn't working yet); something might be defaulting to SLList::NIL", n, nn->rest());
delete n;
delete nn;
}
#include <cstdlib>
void BasicSLListTest::testGetFirst() {
for (int k = 0; k < 100; k++) {
int i = rand();
SLList *n = new SLList(i, SLList::NIL);
CPPUNIT_ASSERT_EQUAL_MESSAGE("first() returned something unexpected after a constructor", i, n->first());
delete n;
}
}
void BasicSLListTest::testSetFirst() {
SLList *n = new SLList(0, SLList::NIL);
for (int k = 0; k < 100; k++) {
int i = rand();
n->setFirst(i);
CPPUNIT_ASSERT_EQUAL_MESSAGE("first() returned something unexpected after setFirst()", i, n->first());
}
delete n;
}
void BasicSLListTest::testSetRest() {
SLList *n = new SLList(1, SLList::NIL);
SLList *nn = new SLList(2, SLList::NIL);
n->setRest(nn);
CPPUNIT_ASSERT_EQUAL_MESSAGE("rest() returned something unexpected after setRest()", nn, n->rest());
nn->setRest(nn);
CPPUNIT_ASSERT_EQUAL_MESSAGE("rest() returned something unexpected after setRest()", nn, nn->rest());
delete nn;
delete n;
}
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BasicSLListTest, "Basic");
CPPUNIT_REGISTRY_ADD_TO_DEFAULT("Basic");
#include <cppunit/extensions/HelperMacros.h>
#include "SLList.hpp"
class ExtendedSLListTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ExtendedSLListTest);
CPPUNIT_TEST(testNth);
CPPUNIT_TEST(testNthRest);
CPPUNIT_TEST_SUITE_END();
SLList *n;
SLList *ncirc;
public:
void setUp() {
n = new SLList(17, new SLList(34, new SLList(3, SLList::NIL)));
ncirc = new SLList(2, new SLList(3, SLList::NIL));
ncirc->rest()->setRest(ncirc);
};
void tearDown() {
SLList *tmp;
while (n != SLList::NIL && n != NULL) {
tmp = n->rest();
delete n;
n = tmp;
}
delete ncirc->rest();
delete ncirc;
};
void testNth();
void testNthRest();
};
#include <cstdlib>
void ExtendedSLListTest::testNth() {
CPPUNIT_ASSERT_EQUAL_MESSAGE("Not getting the right first (index 0) item from nth()", 17, n->nth(0));
CPPUNIT_ASSERT_EQUAL_MESSAGE("Not getting the right second (index 1) item from nth()", 34, n->nth(1));
CPPUNIT_ASSERT_EQUAL_MESSAGE("Not getting the right third (index 2) item from nth()", 3, n->nth(2));
for (int k = 0; k < 100; k++) {
int i = rand() % 1000;
CPPUNIT_ASSERT_EQUAL(ncirc->nth(i % 2), ncirc->nth(i));
}
}
void ExtendedSLListTest::testNthRest() {
CPPUNIT_ASSERT_EQUAL_MESSAGE("Not getting the right rest (index 0) from nthRest()", n, n->nthRest(0));
CPPUNIT_ASSERT_EQUAL_MESSAGE("Not getting the right rest (index 1) next from nthRest()", n->rest(), n->nthRest(1));
CPPUNIT_ASSERT_EQUAL_MESSAGE("Not getting the right rest (index 2) next from nthRest()", n->rest()->rest(), n->nthRest(2));
CPPUNIT_ASSERT_EQUAL_MESSAGE("Not getting the right rest (index 3) next from nthRest()", SLList::NIL, n->nthRest(3));
for (int k = 0; k < 100; k++) {
int i = rand() % 1000;
CPPUNIT_ASSERT_EQUAL(ncirc->nthRest(i % 2), ncirc->nthRest(i));
}
}
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ExtendedSLListTest, "Extended");
CPPUNIT_REGISTRY_ADD_TO_DEFAULT("Extended");
include ../../cpp.mk
SLListTest: SLList.o BasicSLListTest.o ExtendedSLListTest.o ../../00/cpp/RunTests.o
$(CC) -o $@ $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS)
test: SLListTest
./SLListTest
.PHONY: test all
#include <cstdlib>
#include <climits>
#include "SLList.hpp"
using namespace std;
SLList * const SLList::NIL = new SLList(0, NULL);
SLList::SLList(int i, SLList *n) {
}
int SLList::first() {
return 0;
}
SLList *SLList::rest() {
return NULL;
}
void SLList::setFirst(int i) {
}
void SLList::setRest(SLList *n) {
}
int SLList::nth(unsigned int i) {
return 0;
}
SLList *SLList::nthRest(unsigned int i) {
return NULL;
}
unsigned int SLList::length() {
return UINT_MAX;
}
SLList *SLList::remove(int i) {
return NULL;
}
SLList *SLList::reverse() {
return NULL;
}
#ifndef SLLIST_HPP
#define SLLIST_HPP
class SLList {
public:
SLList(int, SLList *);
static SLList * const NIL;
SLList *rest();
int first();
void setFirst(int);
void setRest(SLList *);
int nth(unsigned int);
SLList *nthRest(unsigned int);
unsigned int length();
SLList *remove(int i);
SLList *reverse();
};
#endif
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import java.util.Random;
import org.junit.Test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
public class BasicSLListTest {
@Test
public void testConstructor() {
SLList n = new SLList(0, SLList.NIL);
assertNotEquals("The SLList constructor must never return null", null, n);
assertEquals("The SLList constructor must treat its first argument as the item (or first() isn't working yet)", 0, n.first());
assertEquals("The SLList constructor must treat its second argument as the next node (or rest() isn't working yet)", SLList.NIL, n.rest());
SLList nn = new SLList(104, n);
assertNotEquals("The SLList constructor must never return null", null, nn);
assertEquals("The SLList constructor must treat its first argument as the item (or first() isn't working yet); something might be defaulting to 0", 104, nn.first());
assertEquals("The SLList constructor must treat its second argument as the next node (or rest() isn't working yet); something might be defaulting to SLList.NIL", n, nn.rest());
}
@Test
public void testFirst() {
Random r = new Random();
for (int k = 0; k < 100; k++) {
int i = r.nextInt(Integer.MAX_VALUE);
SLList n = new SLList(i, SLList.NIL);
assertEquals("first() returned something unexpected after a constructor", i, n.first());
}
}
@Test
public void testSetFirst() {
Random r = new Random();
SLList n = new SLList(0, SLList.NIL);
for (int k = 0; k < 100; k++) {
int i = r.nextInt(Integer.MAX_VALUE);
n.setFirst(i);
assertEquals("first() returned something unexpected after setFirst()", i, n.first());
}
}
@Test
public void testSetRest() {
SLList n = new SLList(1, SLList.NIL);
SLList nn = new SLList(2, SLList.NIL);
n.setRest(nn);
assertEquals("rest() returned something unexpected after setRest()", nn, n.rest());
nn.setRest(nn);
assertEquals("rest() returned something unexpected after setRest()", nn, nn.rest());
}
}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import java.util.Random;
import org.junit.Test;
import org.junit.Before;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
public class ExtendedSLListTest {
private SLList n;
private SLList ncirc;
@Test
public void testNth() {
assertEquals("Not getting the right first (index 0) item from nth", 17, n.nth(0));
assertEquals("Not getting the right second (index 1) item from nth", 34, n.nth(1));
assertEquals("Not getting the right third (index 2) item from nth", 3, n.nth(2));
Random r = new Random();
for (int k = 0; k < 100; k++) {
int i = r.nextInt(1000);
assertEquals(ncirc.nth(i % 2), ncirc.nth(i));
}
}
@Test
public void testNthRest() {
assertEquals("Not getting the right rest (index 0) from nthRest", n, n.nthRest(0));
assertEquals("Not getting the right rest (index 1) from nthRest", n.rest(), n.nthRest(1));
assertEquals("Not getting the right rest (index 2) from nthRest", n.rest().rest(), n.nthRest(2));
assertEquals("Not getting the right rest (index 3) from nthRest", SLList.NIL, n.nthRest(3));
Random r = new Random();
for (int k = 0; k < 100; k++) {
int i = r.nextInt(1000);
assertEquals(ncirc.nthRest(i % 2), ncirc.nthRest(i));
}
}
@Before
public void setUp() {
n = new SLList(17, new SLList(34, new SLList(3, SLList.NIL)));
ncirc = new SLList(2, new SLList (3, SLList.NIL));
ncirc.rest().setRest(ncirc);
}
}
include ../../java.mk
TESTCLASSFILES = BasicSLListTest.class ExtendedSLListTest.class
CLASSFILES = SLList.class $(TESTCLASSFILES)
all: $(CLASSFILES)
test: all
(((($(JAVA) $(CP) $(CLASSPATH) org.junit.runner.JUnitCore $(subst .class,,$(TESTCLASSFILES)); echo $$? >&3) | egrep -v \(org.junit\|sun.reflect\|java.lang.reflect\) >&4) 3>&1) | (read xs; exit $$xs)) 4>&1
clean:
-rm -f $(CLASSFILES) test.xml
.PHONY: test all clean
class SLList {
public SLList(Object f, SLList r) { }
public static final SLList NIL = new SLList(0, null);
public Object first() {
return null;
}
public SLList rest() {
return null;
}
public void setFirst(Object f) {
}
public void setRest(SLList r) {
}
public Object nth(int i) {
return null;
}
public SLList nthRest(int i) {
return null;
}
// no such thing as `unsigned' in Java
public int length() {
return -1;
}
public SLList remove(Object o) {
return null;
}
public SLList reverse() {
return null;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment