· The complete arithmetic expression will be read from a input file. An equation will not cover more than one line and may be assumed to be entirely valid.

The input file will contain a single equation
For example the file might contain the following:
56 – 12/3 + 1 * 5
· Operator precedence must be taken into account as well as the bracketing of expressions.
Your program MUST use one linked list as the storage medium for the equation
· Every time an intermediate result is calculated the corresponding components of that calculation are removed from the list and replaced with a single element containing the correct answer.

For example: the second step for the first equation would the equation stored as 56 – 4 + 1 * 5

Thats basically what I need to do for this assignment, I just started learning about linked lists so go easy on me :D I started writing the program. Here it is (nothing much). Just wondering if I am going in the right direction

``````program Assignment7(input, output);

Type
pEquation = ^tequation;
tequation = record
num      : integer;
oper     : char;
next     : pEquation;
end;``````

## All 14 Replies

Yes, good job. The only question is: how can you tell the difference between a node that contains a number and a node that contains an operator?

(Have you learned about variant records?)

Also, is it possible that the numbers in the equation will ever have fractional parts? (Say, what if it were "56 - 12/5 +1 * 5" ?)

I don't think we learnt about variant records. As for the division. I think we are suppose to keep the division simple (no decimals).

I am not exactly sure how to get the numbers and operators from my equation into the linked lists? Can I use the function I had from my previous attempt at an assignment to get the numbers out of the file?

``````function find_digits(var my_char : char; var  my_file : text): integer;

Var
num : integer;

begin
num := 0;
while (ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9')) do
begin
num := num * 10 + (ord(my_char) - ord('0'));
find_digits := num;
end;
end; { find_digits }``````

Absolutely. In fact, I'm pleased you remembered it.

You'll still have to know how to tell a number from an operator. How about:

``````tequation = record
kind     : (i_am_a_number, i_am_an_operator);
num      : integer;
oper     : char;
next     : pEquation;
end;``````

Thereafter, you can know whether or not your tEquation contains a number `if node^.kind = i_am_a_number then ...` or an operator.

When you are reading your equation into the linked list, you can set a node's type similarly: `new_node^.kind := i_am_an_operator;` Hope this helps.

Thats good to know. Am I still heading in the right direction to get all the digits out of the equation?

``````program Assignment7(input, output);

Type
pEquation = ^tequation;
tequation = record
kind : (i_am_a_number, i_am_an_operator);
numb : integer;
oper : char;
next : pEquation;
end;

function find_digits(var my_char : char; var my_file : text) : integer;

Var
num : integer;

begin
num := 0;
while (ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9')) do
begin
num := num * 10 + (ord(my_char) - ord('0'));
find_digits := num;
end;
end; { find_digits }

Var
my_file         : text;
my_char         : char;
ptr 1, ptr2     : pEquation;
num1            : integer;

BEGIN
assign(my_file, 'input.txt');
reset(my_file);
num1 := find_digits(my_char, my_file);

while (my_char <> '=') and (not eoln(my_file)) do
begin
If (ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9')) then

end.``````

I am a bit confused on how to set up the linked lists. Do I need to use "nil" anywhere?

You are close.

A linked list always has three things:
1. a record with a "next" pointer.
2. a "head" pointer pointing to the first record in the linked list.
3. the last record in the linked list's "next" pointer is nil.

Your main loop should look something like this:

``````read( my_file, my_char );
while not eof( my_file ) do[/inlinecode]
while c is a space do skip spaces
if c is in '0'..'9' then
read the number and stick it in a new node
which you append to the end of the linked list.
else if c is an operator then
read the operator and stick it in a new node
which you append to the end of the linked list
else error (because it's not a number, space, or valid operator)
loop to 2
``````

I would make a couple of functions that create a new node. They might be named:

``````function new_number_node( num: integer ): pEquation;

function new_operator_node( oper: char ): pEquation;
``````

Then in your loop all you have to do is call the appropriate function to make life easy.

That should be enough for you to think about for now...

Ugh. I am having troubles with "read the number and stick it in a new node" I can't seem to get it. Also, when you sau "c" is that the same as "my_char"

``````program Assignment7(input, output);

Type
pEquation = ^tequation;
tequation = record
kind : (i_am_a_number, i_am_an_operator);
numb : integer;
oper : char;
next : pEquation;
end;

function find_digits(var my_char : char; var my_file : text) : integer;

Var
num : integer;

begin
num := 0;
while (ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9')) do
begin
num := num * 10 + (ord(my_char) - ord('0'));
find_digits := num;
end;
end; { find_digits }

function new_number_node(num : integer) : pEquation;

function new_operator_node(oper : char) : pEquation;

Var
my_file         : text;
my_char         : char;
head, tail      : pEquation;
num1            : integer;

BEGIN
assign(my_file, 'input.txt');
reset(my_file);
while (my_char = ' ') do
If (ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9')) then

end.``````

Did I do the right thing when you said "while c is a space do skip spaces"

in order:
1.

``````if isDigit( my_char ) then
begin
curr.next := new_number_node( find_digits( my_char, my_file ) );
curr := curr.next
end;``````

2. Yes, "c" is the same as "my_char". (Sorry)

3. No. Pay attention to how I indented in my pseudo. You actually already wrote yourself a function to skip spaces (in your other thread).

Hope this helps.

This is what I got

``````program Assignment7(input, output);

Type
pEquation = ^tequation;
tequation = record
kind : (i_am_a_number, i_am_an_operator);
numb : integer;
oper : char;
next : pEquation;
end;

function find_digits(var my_char : char; var my_file : text) : integer;

Var
num : integer;

begin
num := 0;
while (ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9')) do
begin
num := num * 10 + (ord(my_char) - ord('0'));
find_digits := num;
end;
end; { find_digits }

function new_number_node(num : integer) : pEquation;

function new_operator_node(oper : char) : pEquation;

procedure ignorespaces(var f : text; var c : char);
begin
while c = ' ' do
end; { ignorespaces }

Var
my_file         : text;
my_char         : char;
head, curr      : pEquation;
num1            : integer;

BEGIN
assign(my_file, 'input.txt');
reset(my_file);
while (my_char <> '=') and (not eoln(my_file)) do
begin
while (my_char = ' ') do
begin
ignorespaces(my_file, my_char);
If (ord(my_char >= ord('0')) and (ord(my_char) <= ord('9')) then
begin
curr.next := new_number_node(find_digits(my_char, my_file));
curr := curr.next;
else If (my_char = '+' or '-' or '/' or '*') then
curr.next := new_operator_node(find_digits(my_char, my_file));
curr := curr.next;

end.``````

Something doesn't seem right though.

Ive taken a new approach to this assignment.

``````program Assignment7(input, output);

Type
pEquation = ^node;
node      = record
numb : integer;
oper : char;
next : pEquation;
end;

function find_digits(var my_char : char; var my_file : text) : integer;

Var
num : integer;

begin
num := 0;
while (ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9')) do
begin
num := num * 10 + (ord(my_char) - ord('0'));
find_digits := num;
end;
end; { find_digits }

procedure ignorespaces(var f : text; var c : char);
begin
while c = ' ' do
end; { ignorespaces }

Var
my_file        : text;
my_char        : char;
currentPointer : pEquation;
num1, num2     : integer;
firstnode      : node;

BEGIN
assign(my_file, 'input.txt');
reset(my_file);

num1 := find_digits(my_char, my_file);
firstnode.numb := num1;
ignorespaces(my_file, my_char);
currentPointer := @firstnode;

end.``````

So this right now will put my first digit into the first node. But I am not sure how to put the rest of the equation into other nodes.

This is where it is time to get out the construction paper and crayons. You need to draw yourself adding nodes to a linked list. Be sure to draw lots of little arrows: one from each pointer to the node it references.

There is the node type itself (which you defined), containing a "next" pointer (which you also did a good job of defining)

Then there is a "head" or "first" pointer, say: `var my_equation: pEquation = nil;` The head pointer always points to the first node in the list. You can then write procedures and functions (which take this pointer as argument) to add, remove, move, find, count, etc. specific nodes in the list. Routines that modify the list should be functions that return the new head node, or should take the head node as a var parameter (that is, as a reference parameter) so it can be modified directly --(just in case it changes).

Good luck.

I am not sure If I am heading in the right direction, but this is what I got.

``````program Assignment7(input, output);

Type
pEquation = ^node;
node      = record
numb : integer;
oper : char;
next : pEquation;
end;

function find_digits(var my_char : char; var my_file : text) : integer;

Var
num : integer;

begin
num := 0;
while (ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9')) do
begin
num := num * 10 + (ord(my_char) - ord('0'));
find_digits := num;
end;
end; { find_digits }

procedure ignorespaces(var f : text; var c : char);
begin
while c = ' ' do
end; { ignorespaces }

Var
my_file        : text;
my_char        : char;
currentPointer : pEquation;
num1, num2     : integer;
firstnode      : node;

BEGIN
assign(my_file, 'input.txt');
reset(my_file);

num1 := find_digits(my_char, my_file);
firstnode.numb := num1;
ignorespaces(my_file, my_char);
currentPointer := @firstnode;
currentPointer := currentPointer^.next;

new(currentPointer);
currentPointer^.oper := my_char;

while (my_char <> '=') and (not eoln(my_file)) do
begin
If (ord(my_char) >= ord('0') and (ord(my_char) <= ord('9')) then
begin
ignorespaces(my_file, my_char);
num1 := num1 + 1;
end;
end;

end.``````

Man whatever I do I can not get my loop to read all the numbers.

Sorry to respond so late.

Your code to read things in should look something like this (remember: this is how to do it in your head):

``````function read_equation( var head: pEquation; var f: textFile ): boolean;
var c: char;
begin
result := false;
c := ' ';
while not eoln( f ) do
begin
result := true;
if is_digit( c )
else
if is_operator( c )
else
if is_space( c )
then skip_spaces( f, c )
else begin
writeln( 'Invalid equation at ''', c, '''' );
result := false;
break
end
end
end;``````

You will, of course, have to define is_digit, is_operator, is_space, read_digits, read_operator, skip_spaces, add_new_number_node, and add_new_operator_node.

Also, make sure that your head points to an empty or nil equation each time before calling this function.

Hope this helps.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, learning, and sharing knowledge.