SE250:lab-4:jham005
Jump to navigation
Jump to search
/* File: lab-4-soln.c Date: 1 April 2008 Author: John Hamer Purpose: Sample solution to SOFTENG lab #4, 2008 */ #include <assert.h> #include <stdlib.h> #include <stdio.h> typedef int element_t; typedef struct Cons { element_t head; struct Cons* tail; } Cons; static Cons NIL = { 0, &NIL }; Cons* nil = &NIL; Cons* cons( element_t elt, Cons* tail ) { Cons* cell = malloc( sizeof(Cons) ); assert( cell != 0 ); cell->head = elt; cell->tail = tail; return cell; } void print_list( Cons* list ) { char* sep = ""; printf( "List[" ); for( ; list != nil; list = list->tail ) { printf( "%s%d", sep, list->head ); sep = ","; } printf( "]\n" ); } int length( Cons* list ) { int len = 0; for( ; list != nil; list = list->tail ) len++; return len; } element_t first( Cons* list ) { return list->head; } element_t second( Cons* list ) { return list->tail->head; } element_t third( Cons* list ) { return list->tail->tail->head; } element_t fourth( Cons* list ) { return list->tail->tail->tail->head; } element_t nth( int i, Cons* list ) { while( i-- > 0 ) list = list->tail; return list->head; } int equal( Cons* xs, Cons* ys ) { while( xs != nil && ys != nil ) { if( xs->head != ys->head ) return 0; xs = xs->tail; ys = ys->tail; } return xs == ys; } Cons* find( element_t elt, Cons* list ) { for( ; list != nil; list = list->tail ) if( list->head == elt ) break; return list; } Cons* append( Cons* xs, Cons* ys ) { Cons* result; /* deliberately left uninitialised */ Cons** cpp = &result; /* pointer to the last uninitialised list pointer */ for( ; xs != nil; xs = xs->tail ) { *cpp = cons(xs->head, (Cons*)0); /* nil would be misleading; this list is incomplete */ cpp = &(*cpp)->tail; } *cpp = ys; return result; } Cons* copy_list( Cons* list ) { return append( list, nil ); } Cons* nappend( Cons* xs, Cons* ys ) { if( xs == nil ) return ys; else { Cons* cp = xs; while( cp->tail != nil ) cp = cp->tail; cp->tail = ys; } return xs; } Cons* reverse( Cons* list ) { Cons* rev = nil; for( ; list != nil; list = list->tail ) rev = cons( list->head, rev ); return rev; } Cons* nreverse( Cons* list ) { Cons* prev = nil; Cons* next; for( ; list != nil; list = next ) { next = list->tail; list->tail = prev; prev = list; } return prev; } int main( ) { print_list( nil ); /* List[] */ print_list( cons(10,cons(20,cons(30,nil))) ); /* List[10,20,30] */ assert( length( nil ) == 0 ); assert( length( cons(10,cons(20,cons(30,nil))) ) == 3 ); assert( first( nil ) == 0 ); assert( first( cons(10,cons(20,nil)) ) == 10 ); assert( second( nil ) == 0 ); assert( second( cons(10,cons(20,nil)) ) == 20 ); assert( third( nil ) == 0 ); assert( third( cons(10,cons(20,nil)) ) == 0 ); assert( third( cons(10,cons(20,cons(30,nil))) ) == 30 ); assert( fourth( nil ) == 0 ); assert( fourth( cons(10,cons(20,nil)) ) == 0 ); assert( fourth( cons(10,cons(20,cons(30,nil))) ) == 0 ); assert( fourth( cons(10,cons(20,cons(30,cons(40,nil)))) ) == 40 ); assert( nth(0,nil) == 0 ); assert( nth(1,nil) == 0 ); assert( nth(0,cons(10,nil)) == 10 ); assert( nth(1,cons(10,nil)) == 0 ); assert( equal(nil,nil) ); assert( ! equal(nil,cons(10,nil)) ); assert( ! equal(cons(10,nil),nil) ); assert( equal(cons(10,nil),cons(10,nil)) ); assert( ! equal(cons(10,nil),cons(20,nil)) ); print_list( find(10,nil) ); /* List[] */ print_list( find(20,cons(10,nil)) ); /* List[] */ print_list( find(10,cons(10,nil)) ); /* List[10] */ print_list( append(nil,nil) ); /* List[] */ print_list( append(nil,cons(10,nil)) ); /* List[10] */ print_list( append(cons(10,nil),nil) ); /* List[10] */ print_list( append(cons(10,nil),cons(20,nil)) ); /* List[10,20] */ print_list( copy_list(nil) ); /* List[] */ print_list( copy_list(cons(10,nil)) ); /* List[10] */ print_list( copy_list(cons(10,cons(20,nil))) ); /* List[10,20] */ print_list( nappend(nil,nil) ); /* List[] */ print_list( nappend(nil,cons(10,nil)) ); /* List[10] */ print_list( nappend(cons(10,nil),nil) ); /* List[10] */ print_list( nappend(cons(10,nil),cons(20,nil)) ); /* List[10,20] */ print_list( reverse(nil) ); /* List[] */ print_list( reverse(cons(10,nil)) ); /* List[10] */ print_list( reverse(cons(10,cons(20,nil))) ); /* List[20,10] */ print_list( nreverse(nil) ); /* List[] */ print_list( nreverse(cons(10,nil)) ); /* List[10] */ print_list( nreverse(cons(10,cons(20,nil))) ); /* List[20,10] */ return 0; } /* Local Variables: compile-command: "gcc -Wall lab-4-soln.c -o lab-4-soln && ./lab-4-soln" End: */