· 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;

Recommended Answers

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'));
   read(my_file, my_char);
   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'));
      read(my_file, my_char);
      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);
   read(my_file, my_char);
   num1 := find_digits(my_char, my_file);

   while (my_char <> '=') and (not eoln(my_file)) do
   begin
      read(my_file, my_char);
      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'));
      read(my_file, my_char);
      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);
   read(my_file, my_char);
   while (my_char = ' ') do
      If (ord(my_char) >= ord('0')) and (ord(my_char) <= ord('9')) then
         read(my_file, my_char);
         

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'));
      read(my_file, my_char);
      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
     read(f, c);
 end; { ignorespaces }




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

BEGIN
   assign(my_file, 'input.txt');
   reset(my_file);
   read(my_file, my_char);
   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'));
      read(my_file, my_char);
      find_digits := num;
   end;
end; { find_digits }


procedure ignorespaces(var f : text; var c : char);
 begin
   while c = ' ' do
     read(f, c);
 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);
   read(my_file, my_char);

   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'));
      read(my_file, my_char);
      find_digits := num;
   end;
end; { find_digits }


procedure ignorespaces(var f : text; var c : char);
 begin
   while c = ' ' do
     read(f, c);
 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);
   read(my_file, my_char);

   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 )
      then add_new_number_node( head, read_digits( f, c ) )
      else
    if is_operator( c )
      then add_new_operator_node( head, read_operator( f, 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, networking, learning, and sharing knowledge.