class Dlist; // Forward reference to a Dlist
class Dlnode {
friend class Dlist; // Dlist should be able to use and inspect
// Dlist_node's protected members and methods
protected:
Dlnode(char val);
~Dlnode();
char value;
Dlnode *flink; // pointer to the next node in the list
Dlnode *blink; // pointer to the previous node in the list
};
class Dlist {
public:
Dlist(); // initializes the dlist
~Dlist(); // destroys the dlist's nodes
// After insertBeforeCursor and insertAfterCursor are executed,
// the list cursor should point to the newly created node
void insertBeforeCursor(char value); // inserts the value before the node
// pointed to by the list cursor
void insertAfterCursor(char value); // inserts the value after the node
// pointed to by the list cursor
void append(char value); // appends the value to the end of the list
void prepend(char value); // appends the value to the front of the list
void next(); // moves the list cursor to the next
// element in the list
void prev(); // moves the list cursor to the previous
// element in the list
bool endOfList(); // true if the list cursor points to the
// sentinel node; false otherwise
// If the list is empty, the following two operations make the
// list cursor point to the list's sentinel node
void first(); // resets the list cursor to the first
// element in the list.
void last(); // resets the list cursor to the last
// element in the list
char get(); // returns the value of the node pointed to
// by the list cursor
void deleteNode(); // deletes the node pointed to by the list cursor
// and advances the list cursor to the next
// list element
bool isEmpty(); // returns whether the list is empty
protected:
Dlnode *cursor; // the list cursor
Dlnode *sentinel_node; // a pointer to the sentinel node
};
To illustrate how the Dlist class might be used, consider the following three problems and their solutions:
for (mylist.first(); !mylist.endOfList(); mylist.next())
printf("%c\n", mylist.get());
char first_element = mylist.first().get();
mylist.delete();
for (mylist.first(); !mylist.endOfList(); mylist.next()) {
if (value < mylist.get())
break;
}
mylist.insertBeforeCursor(value);
void Dlist::insertBeforeCursor(char v)
{
Dlnode *last_node, *new_node; // since new is a reserved keyword in C++,
// I've replaced new with new_node
new_node = new Dlnode(v);
last_node = cursor->blink;
cursor->blink = new_node;
last_node->flink = new_node;
new_node->blink = last_node;
new_node->flink = cursor;
cursor = new_node; // make the cursor point to the newly created node
}
{}[ ( ) ] {{ [ []() ] }} {
}
Each of the following four lines is unbalanced:
{ (} - left paren and right curly bracket don't match
[ () } - left square brace and right curly bracket don't match
} - no left curly bracket
() ( [] ) ( - no right paren
If standard input is balanced,
the program should print out the number of each pair seen.
If not, the program should print out what the error is.
For example, look at the files input1, input2, input3, and input4.
Input1 is a C program where everything is balanced. When you run abalance on it, the output should look like:
UNIX> abalance < input1
Parentheses (): 26
Square braces []: 3
Curly brackets {}: 5
UNIX>
Almost all C programs are balanced -- try a few:
UNIX> abalance < ~cs140/www-home/notes/Stacks/stackrev.c
Parentheses (): 12
Square braces []: 0
Curly brackets {}: 3
UNIX> abalance < ~cs140/src/fields/fields.c
Parentheses (): 41
Square braces []: 7
Curly brackets {}: 21
The other three input files have the three types of unbalances that your program needs to catch -- unmatched '(', '[' or '}', unmatched ')', ']' or '}', and mismatches. For example, input2 has three unmatched characters (read the file to see which ones):
UNIX> abalance < input2 Unmatched symbols UNIX>Input3 has an unmatched right paren:
UNIX> abalance < input3 abalance < input3 Unmatched ) UNIX>and input4 has a mismatch on lines 1 and 2
UNIX> abalance < input4 Unmatched ] UNIX>Obviously, the TA's will test more than just these input files. So should you.
You need to use stacks to write abalance. The concept is simple -- when you see a left paren, square brace or curly bracket, you push the character on the stack. When you see a right paren, square brace or curly bracket, you first see if the stack is empty. If so, you have an unmatched character that you flag and then exit. Next, you pop a character off the stack. If the character matches the current character (for example the character from the stack is a left paren and the current character is a right paren), then you have a match, and everything is fine -- go ahead and read the next character from standard input. If they don't match, then you have discovered a mismatch and can print it out and exit. When you are done reading standard input, if there are any characters left on the stack, then they are unmatched. If the stack is empty, you can conclude that the input was balanced.
Part a:Write abalance using a class called StackArray. StackArray should implement its stack using the dynamic CharArray class you've been given for this lab. CharArray is just like the StringArray class from lab1, except that it stores chars rather than strings. CharArray.h can be found in /ruby/homes/ftp/pub/bvz/classes/cs302/include and CharArray.o can be found in the cs302 objs directory.
Part b: Write dbalance using a class called StackList. StackList should implement its stack using your Dlist class.
class Stack[Array/List] {
public:
void Push(char);
char Pop();
bool IsEmpty()
}
You will also have to add declarations for the constructor and destructor for each class.
string a = "Hi there";
printf("string length = %d\n", a.length());