Pascal

Moderators: None (Apply to moderate this forum)
Number of threads: 4106
Number of posts: 14016

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
Address Book Search Program Posted by gashhek on 11 Apr 2008 at 2:43 AM
I have been given a task to do for a college assignment. It is to find or create a program which allows entries of an address book to be displayed depending on a unique identifier entered (e.g. "PersonNumber") and write about how the program works.

The entries of the address book should be stored on a text file. The entries have to include a PersonNumber or ID, First Name, Surname, Address, Phone Number. The program has to use a binary search algorithm. The program does not need to add any entries to the text file or remove entries -- the program only needs to read from the text file using binary searches.

My problem is that I am rubbish when it comes to programming and I could not find such a program that does this in psacal. Will someone please build me a basic program (just reading from the text file - never mind about adding or removing data)
Report
Re: Address Book Search Program Posted by Actor on 11 Apr 2008 at 1:25 PM
: I have been given a task to do for a college assignment. It is to
: find or create a program which allows entries of an address book to
: be displayed depending on a unique identifier entered (e.g.
: "PersonNumber") and write about how the program works.
:
: The entries of the address book should be stored on a text file. The
: entries have to include a PersonNumber or ID, First Name, Surname,
: Address, Phone Number. The program has to use a binary search
: algorithm. The program does not need to add any entries to the text
: file or remove entries -- the program only needs to read from the
: text file using binary searches.
:
: My problem is that I am rubbish when it comes to programming and I
: could not find such a program that does this in psacal. Will someone
: please build me a basic program (just reading from the text file -
: never mind about adding or removing data)
:
A pretty tall order since it's next to impossible to do a binary search of a text file.


Report
Re: Address Book Search Program Posted by gashhek on 11 Apr 2008 at 3:11 PM
: A pretty tall order since it's next to impossible to do a binary
: search of a text file.

How about if all the data is read from the text file and put into elements of an array.
Report
Re: Address Book Search Program Posted by Actor on 11 Apr 2008 at 3:45 PM
: : A pretty tall order since it's next to impossible to do a binary
: : search of a text file.
:
: How about if all the data is read from the text file and put into
: elements of an array.
:
That would work. The problem is that the array would have to fit in memory. In Turbo Pascal the maximum number of records that you could fit in memory, given the data you specified, would be about 1000. And that's not leaving any room in memory for the program. If you settle for only 500 records there should be more than enough room for the program.

Report
Re: Address Book Search Program Posted by zibadian on 11 Apr 2008 at 11:23 PM
: : : A pretty tall order since it's next to impossible to do a binary
: : : search of a text file.
: :
: : How about if all the data is read from the text file and put into
: : elements of an array.
: :
: That would work. The problem is that the array would have to fit in
: memory. In Turbo Pascal the maximum number of records that you
: could fit in memory, given the data you specified, would be about
: 1000. And that's not leaving any room in memory for the program.
: If you settle for only 500 records there should be more than enough
: room for the program.
:
:
The story is a bit different. The maximum size of any variable is only 65535 bytes. Since a untruncated string is 256 bytes long, you can at most make a string array of 255 strings. If you truncate the string elements in your array, you can create more elements. The way to calculate the maximum number of elements is: 65535 / (length of string+1). Thus with strings of 20 characters, you are limited to 3120 (65535/(20+1)) elements.
This calculation also holds true for other variable types.
TP programs themselves have an upper limit of 640000 bytes of memory, minus any other in low memory running programs.
If you need more memory than that, then TP7 (and perhaps TP6) include a class to use the memory above the first MB as storage: TEMSStream. This can be used as an array of byte with a maximum size of the EMS memory. With some maths added to it, it can easily be converted into an array of any type, as long as the records have a fixed length. This allows for the array to become larger than the 64 kB limit, although the performance is slightly lower and the records are still limited to 64 kB.
Report
Re: Address Book Search Program Posted by Actor on 12 Apr 2008 at 2:43 AM
: : : : A pretty tall order since it's next to impossible to do a binary
: : : : search of a text file.
: : :
: : : How about if all the data is read from the text file and put into
: : : elements of an array.
: : :
: : That would work. The problem is that the array would have to fit in
: : memory. In Turbo Pascal the maximum number of records that you
: : could fit in memory, given the data you specified, would be about
: : 1000. And that's not leaving any room in memory for the program.
: : If you settle for only 500 records there should be more than enough
: : room for the program.
: :
: :
: The story is a bit different. The maximum size of any variable is
: only 65535 bytes. Since a untruncated string is 256 bytes long, you
: can at most make a string array of 255 strings. If you truncate the
: string elements in your array, you can create more elements. The way
: to calculate the maximum number of elements is: 65535 / (length of
: string+1). Thus with strings of 20 characters, you are limited to
: 3120 (65535/(20+1)) elements.
: This calculation also holds true for other variable types.
: TP programs themselves have an upper limit of 640000 bytes of
: memory, minus any other in low memory running programs.
: If you need more memory than that, then TP7 (and perhaps TP6)
: include a class to use the memory above the first MB as storage:
: TEMSStream. This can be used as an array of byte with a maximum size
: of the EMS memory. With some maths added to it, it can easily be
: converted into an array of any type, as long as the records have a
: fixed length. This allows for the array to become larger than the 64
: kB limit, although the performance is slightly lower and the records
: are still limited to 64 kB.

I was assuming that the information he specified could be held in a string[63], which would give 1000 records in a 64K array. I like to keep it simple meaning keep it all on the stack if you can. The K.I.S.S. principle.

Report
Re: Address Book Search Program Posted by zibadian on 12 Apr 2008 at 5:44 AM
: : : : : A pretty tall order since it's next to impossible to do a binary
: : : : : search of a text file.
: : : :
: : : : How about if all the data is read from the text file and put into
: : : : elements of an array.
: : : :
: : : That would work. The problem is that the array would have to fit in
: : : memory. In Turbo Pascal the maximum number of records that you
: : : could fit in memory, given the data you specified, would be about
: : : 1000. And that's not leaving any room in memory for the program.
: : : If you settle for only 500 records there should be more than enough
: : : room for the program.
: : :
: : :
: : The story is a bit different. The maximum size of any variable is
: : only 65535 bytes. Since a untruncated string is 256 bytes long, you
: : can at most make a string array of 255 strings. If you truncate the
: : string elements in your array, you can create more elements. The way
: : to calculate the maximum number of elements is: 65535 / (length of
: : string+1). Thus with strings of 20 characters, you are limited to
: : 3120 (65535/(20+1)) elements.
: : This calculation also holds true for other variable types.
: : TP programs themselves have an upper limit of 640000 bytes of
: : memory, minus any other in low memory running programs.
: : If you need more memory than that, then TP7 (and perhaps TP6)
: : include a class to use the memory above the first MB as storage:
: : TEMSStream. This can be used as an array of byte with a maximum size
: : of the EMS memory. With some maths added to it, it can easily be
: : converted into an array of any type, as long as the records have a
: : fixed length. This allows for the array to become larger than the 64
: : kB limit, although the performance is slightly lower and the records
: : are still limited to 64 kB.
:
: I was assuming that the information he specified could be held in a
: string[63], which would give 1000 records in a 64K array. I like to
: keep it simple meaning keep it all on the stack if you can. The
: K.I.S.S. principle.
:
:
With a 1000 element array of string[63], there is still enough room for the program. Especially when the array is declared as a global variable. That way it is stored on the heap, which is much larger than the stack.
Report
Re: Address Book Search Program Posted by gashhek on 12 Apr 2008 at 5:50 AM
I don't know if this helps, but I have not populated a text file yet and I know there are not going to be many records (20 Max). I just need a working program that uses a binary search so I can explain how it works. Any help would be greatly appreciated.
Report
Re: Address Book Search Program Posted by zibadian on 12 Apr 2008 at 8:22 AM
: I don't know if this helps, but I have not populated a text file yet
: and I know there are not going to be many records (20 Max). I just
: need a working program that uses a binary search so I can explain
: how it works. Any help would be greatly appreciated.
:
Here is a binary search through an array of string. This code assumes a 0-indexed array (i.e. array[0..SomeLength] of string).
  Low := 0;
  High := Length(StringArray)-1;
  Result := -1;
  if StringArray[Low] = SearchValue then
    Result := Low
  else if StringArray[High] = SearchValue then
    Result := High
  else while (Low <> High) and (Low+1 <> High) do
  begin
    Mid := (High-Low) div 2 + Low;
    if StringArray[Mid] = SearchValue then
    begin
      Result := Mid;
      Break;
    end else if StringArray[Mid] > SearchValue then
      High := Mid
    else
      Low := Mid;
  end;
  if StringArray[Low] = SearchValue then
    Result := Low
  else if StringArray[High] = SearchValue then
    Result := High;
  if Result = -1 then
    writeln(SearchValue+' not found!')
  else
    writeln(SearchValue+' has an index of '+Result);
Report
Re: Address Book Search Program Posted by gashhek on 12 Apr 2008 at 10:38 AM
Thank you very much. but can you provide a full program. I'm finding this very difficult. Also, how would I populate the text file. Would it be something like this:

1 Firstname Surname Address PhoneNo
2 Another Name Address PhoneNo

I am using Turbo Pascal 1.5 for Windows
Report
Re: Address Book Search Program Posted by zibadian on 12 Apr 2008 at 12:35 PM
: Thank you very much. but can you provide a full program. I'm finding
: this very difficult. Also, how would I populate the text file. Would
: it be something like this:
:
: 1 Firstname Surname Address PhoneNo
: 2 Another Name Address PhoneNo
:
: I am using Turbo Pascal 1.5 for Windows
:
I don't know. It depends on how much information is in the address, how the formatting of the data is, etc. Theoretically you can fill the text file with anything, as long as the read part of the program can handle the format.
Here's a simple reader, which fills the string array with the lines form the text file:
  Assign(f, 'filename.txt');
  reset(f);
  i := 0;
  while not eof(f) do
  begin
    readln(f, StringArray[i]);
    inc(i);
  end;
  Close(f);
  ArrayLength := i;
Report
Re: Address Book Search Program Posted by gashhek on 13 Apr 2008 at 5:40 AM
This task is proving I know very little about programming. What am I doing wrong?
I'm using Turbo Pascal 1.5 for Windows and I don't think the compilor I am using supports the Break command. When I remove the Break, the program runs but it doesn't do what it is supposed to. If I enter "1" as the Person ID, "1 not found!" is displayed and when I enter "2" or any number above 1, the program seems like it freezes (it takes up 99% CPU Usage).

At the moment, my text file is populated with the following data:

1 John Smith 123 Fake Street (11111) 111111
2 Pat Evans 31 Albert Square (22222) 222222



The code:
Program Search;

Uses
    WinCrt;

Var
    f: Text;
    i: Integer;
    StringArray: Array[0..20] of String;
    ArrayLength: Integer;
    Low, Mid, High: Integer;
    Result: Integer;
    SearchValue: String;

Begin
    assign(f, 'filename.txt');
    reset(f);
    i := 0;
    while not eof(f) do
    begin
        readln(f, StringArray[i]);

        write('Enter Person ID to see contact details: ');
        readln(SearchValue);

        inc(i);
        Low := 0;
        High := Length(StringArray[i])-1;
        Result := -1;
        if StringArray[Low] = SearchValue then
            Result := Low
        else if StringArray[High] = SearchValue then
            Result := High
        else while (Low <> High) and (Low+1 <> High) do
        begin
            Mid := (High-Low) div 2 + Low;
            if StringArray[Mid] = SearchValue then
            begin
                Result := Mid;
                Break;
            end else if StringArray[Mid] > SearchValue then
                High := Mid
            else
                Low := Mid;
            end;
            if StringArray[Low] = SearchValue then
                Result := Low
            else if StringArray[High] = SearchValue then
                Result := High;
            if Result = -1 then
                writeln(SearchValue+' not found!')
            else
                writeln(SearchValue+' has an index of ',Result);
    end;
    Close(f);
    ArrayLength := i;
End.

Report
Re: Address Book Search Program Posted by zibadian on 13 Apr 2008 at 6:18 AM
: This task is proving I know very little about programming. What am I
: doing wrong?
: I'm using Turbo Pascal 1.5 for Windows and I don't think the
: compilor I am using supports the Break command. When I remove the
: Break, the program runs but it doesn't do what it is supposed to. If
: I enter "1" as the Person ID, "1 not found!" is displayed and when I
: enter "2" or any number above 1, the program seems like it freezes
: (it takes up 99% CPU Usage).
:
: At the moment, my text file is populated with the following data:
:
:
: 1 John Smith 123 Fake Street (11111) 111111
: 2 Pat Evans 31 Albert Square (22222) 222222
:
:
:
: The code:
:
: Program Search;
: 
: Uses
:     WinCrt;
: 
: Var
:     f: Text;
:     i: Integer;
:     StringArray: Array[0..20] of String;
:     ArrayLength: Integer;
:     Low, Mid, High: Integer;
:     Result: Integer;
:     SearchValue: String;
: 
: Begin
:     assign(f, 'filename.txt');
:     reset(f);
:     i := 0;
:     while not eof(f) do
:     begin
:         readln(f, StringArray[i]);
: 
:         write('Enter Person ID to see contact details: ');
:         readln(SearchValue);
: 
:         inc(i);
:         Low := 0;
:         High := Length(StringArray[i])-1;
:         Result := -1;
:         if StringArray[Low] = SearchValue then
:             Result := Low
:         else if StringArray[High] = SearchValue then
:             Result := High
:         else while (Low <> High) and (Low+1 <> High) do
:         begin
:             Mid := (High-Low) div 2 + Low;
:             if StringArray[Mid] = SearchValue then
:             begin
:                 Result := Mid;
:                 Break;
:             end else if StringArray[Mid] > SearchValue then
:                 High := Mid
:             else
:                 Low := Mid;
:             end;
:             if StringArray[Low] = SearchValue then
:                 Result := Low
:             else if StringArray[High] = SearchValue then
:                 Result := High;
:             if Result = -1 then
:                 writeln(SearchValue+' not found!')
:             else
:                 writeln(SearchValue+' has an index of ',Result);
:     end;
:     Close(f);
:     ArrayLength := i;
: End.
:
:
The Break is necessary to speed up the algorithm. See http://www.programmersheaven.com/mb/pasprog/370952/371008/ReadMessage.aspx?S=B20000#371008 for an alternative.
Report
Re: Address Book Search Program Posted by gashhek on 13 Apr 2008 at 10:05 AM
: The Break is necessary to speed up the algorithm. See
: http://www.programmersheaven.com/mb/pasprog/370952/371008/ReadMessage
: .aspx?S=B20000#371008 for an alternative.

Using GoTo hasn't made any difference - the program behaves in the same way if the Break command was not used. And the program does not work. I can type any number equal to or below 1 and "n not found!" is displayed. If I type a number greater than 1 the program consumes a lot of CPU usage.

Here's teh code:

Program Search;

Uses
    WinCrt;

Var
    f: Text;
    i: Integer;
    StringArray: Array[0..20] of String;
    ArrayLength: Integer;
    Low, Mid, High: Integer;
    Result: Integer;
    SearchValue: String;

Label
    Break;

Begin
    assign(f, 'filename.txt');
    reset(f);
    i := 0;
    while not eof(f) do
    begin
        readln(f, StringArray[i]);

        write('Enter Person ID to see contact details: ');
        readln(SearchValue);

        inc(i);

        Low := 0;
        High := Length(StringArray[i])-1;
        Result := -1;
        if StringArray[Low] = SearchValue then
            Result := Low
        else if StringArray[High] = SearchValue then
            Result := High
        else while (Low <> High) and (Low+1 <> High) do
        begin
            Mid := (High-Low) div 2 + Low;
            if StringArray[Mid] = SearchValue then
            begin
                Result := Mid;
                Goto Break
            end else if StringArray[Mid] > SearchValue then
                High := Mid
            else
                Low := Mid;
            end;
            if StringArray[Low] = SearchValue then
                Result := Low
            else if StringArray[High] = SearchValue then
                Result := High;
            if Result = -1 then
                writeln(SearchValue+' not found!')
            else
                writeln(SearchValue+' has an index of ',Result);

    end;
    Break:
    Close(f);
    ArrayLength := i;
End.

Report
Re: Address Book Search Program Posted by zibadian on 13 Apr 2008 at 10:20 AM
: : The Break is necessary to speed up the algorithm. See
: : http://www.programmersheaven.com/mb/pasprog/370952/371008/ReadMessage
: : .aspx?S=B20000#371008 for an alternative.
:
: Using GoTo hasn't made any difference - the program behaves in the
: same way if the Break command was not used. And the program does not
: work. I can type any number equal to or below 1 and "n not found!"
: is displayed. If I type a number greater than 1 the program consumes
: a lot of CPU usage.
:
: Here's teh code:
:
:
: Program Search;
: 
: Uses
:     WinCrt;
: 
: Var
:     f: Text;
:     i: Integer;
:     StringArray: Array[0..20] of String;
:     ArrayLength: Integer;
:     Low, Mid, High: Integer;
:     Result: Integer;
:     SearchValue: String;
: 
: Label
:     Break;
: 
: Begin
:     assign(f, 'filename.txt');
:     reset(f);
:     i := 0;
:     while not eof(f) do
:     begin
:         readln(f, StringArray[i]);
: 
:         write('Enter Person ID to see contact details: ');
:         readln(SearchValue);
: 
:         inc(i);
: 
:         Low := 0;
:         High := Length(StringArray[i])-1;
:         Result := -1;
:         if StringArray[Low] = SearchValue then
:             Result := Low
:         else if StringArray[High] = SearchValue then
:             Result := High
:         else while (Low <> High) and (Low+1 <> High) do
:         begin
:             Mid := (High-Low) div 2 + Low;
:             if StringArray[Mid] = SearchValue then
:             begin
:                 Result := Mid;
:                 Goto Break
:             end else if StringArray[Mid] > SearchValue then
:                 High := Mid
:             else
:                 Low := Mid;
:             end;
:             if StringArray[Low] = SearchValue then
:                 Result := Low
:             else if StringArray[High] = SearchValue then
:                 Result := High;
:             if Result = -1 then
:                 writeln(SearchValue+' not found!')
:             else
:                 writeln(SearchValue+' has an index of ',Result);
: 
:     end;
:     Break:
:     Close(f);
:     ArrayLength := i;
: End.
:
:
Can you figure out why the program doesn't work? You should be able to since figuring out how the program works is your goal.
Report
Re: Address Book Search Program Posted by gashhek on 13 Apr 2008 at 10:45 AM
: Can you figure out why the program doesn't work? You should be able
: to since figuring out how the program works is your goal.

i'll try. thanks for all your help :)
Report
Re: Address Book Search Program Posted by Actor on 14 Apr 2008 at 1:26 AM
: : Can you figure out why the program doesn't work? You should be able
: : to since figuring out how the program works is your goal.
:
: i'll try. thanks for all your help :)
:
You need to read the entire file into your array before you begin the search.
Begin
    assign(f, 'filename.txt');
    reset(f);
        i := 0;
        while not eof(f) do
        begin
            if i > 20 then begin
                writeln ('File is too big to fit in memory.') ;
                close(f) ;
                halt
            end ;
            readln(f, StringArray[i]);
            i := i + 1
        end ;
    close(f) ;   { the entire file is now in memory }

    ArrayLength := i - 1 ;  { index of the last record }

    write('Enter Person ID to see contact details: ');
    readln(SearchValue);
    {
        now start your search
    }



Report
Re: Address Book Search Program Posted by Actor on 14 Apr 2008 at 3:38 PM
: : Can you figure out why the program doesn't work? You should be able
: : to since figuring out how the program works is your goal.
:
: i'll try. thanks for all your help :)
:

Database type records stored in text files are more than likely column sensitive, as in the following. The items in red are for reference only and are not part of the file.


            1         2         3         4         5
   12345678901234567890123456789012345678901234567890
 0 101 John      Smith     123 Fake Street     (11111) 111111
 1 102 Pat       Evans     31 Albert Square    (22222) 222222
 2 103 Annette   Funicello 125 Hollywood Blvd  (33333) 333333
 3 105 Sandra    Dee       501 Mulholland Road (44444) 444444
 4 107 Tuesday   Weld      777 Magnificent Ave (55555) 555555
 5 111 Carol     Lynley    123 Blue Demim      (66666) 666666
 6 113 Hayley    Mills     1001 Pollyanne Ave  (77777) 777777
 7 117 Deborah   Walley    2 Hawaiian          (88888) 888888
 8 123 Sally     Field     1 Smoky Road        (99999) 999999
 9 129 Frankie   Avalon    999 Beachfront      (11111) 222222
10 131 Fabian    Forte     500 Fileball        (22222) 333333
11 137 Elvis     Presley   1 Graceland         (33333) 444444
12 141 Troy      Donahue   9 Summer Place      (44444) 555555
13 147 Douglas   McClure   77 Sunset Strip     (55555) 666666
14 153 Salvatore Mineo     111 Drummer         (66666) 777777


The numbers in red on the left are the record numbers and, as I said, are not part of the file. PersonNumber is stored in columns 1 .. 3; FirstName is in columns 5 .. 14, etc. Make sure your data elements begin in the correct column.

When using binary search it is absolutely vital that the file be sorted in "key field order", the key field in this case being PersonNumber in columns 1 .. 3. Note that this is a substring and not actually a number. If the file is not sorted then the search will almost certainly fail.

Comparisons between SearchValue and StringArray[i] should be between the first three characters only. E.g.,

      if Copy(StringArray[i],1,3) = SearchValue  then


StringArray[i] will never equal SearchValue unless you type in an entire copy of the record you are searching for (tedious, error prone, and if you already have all that data why are you searching the file).

Report
Re: Address Book Search Program Posted by gashhek on 15 Apr 2008 at 3:05 PM
Thank you for replying. I think the program stops responding because a loop keeps running. I think I am using the goto incorrectly? I know the file is being read because I can call specific elements of the array and it works. It's just the binary search I'm having problems with.

I don't know what you meant by the comparison between SearchValue and StringArray[i].

Program Search;

Uses
    WinCrt;

Var
    f: Text;
    i: Integer;
    StringArray: Array[0..20] of String;
    ArrayLength: Integer;
    Low, Mid, High: Integer;
    Result: Integer;
    SearchValue: String;

Label
    Break;

Begin
    assign(f, 'filename.txt');
    reset(f);
        i := 0;
        while not eof(f) do
        begin
            if i > 20 then begin
                writeln ('File is too big to fit in memory.');
                close(f);
                halt
            end ;
            readln(f, StringArray[i]);
            i := i + 1;
        end;
    close(f);

    ArrayLength := i - 1;

    write('Enter Person ID to see contact details: ');
    readln(SearchValue);

    Low := 0;
    High := Length(StringArray[i])-1;
    Result := -1;

    if StringArray[Low] = SearchValue then
        Result := Low
    else
        if StringArray[High] = SearchValue then
            Result := High
    else
        while (Low <> High) and (Low+1 <> High) do
        begin
            Mid := (High-Low) div 2 + Low;
            if StringArray[Mid] = SearchValue then
            begin
                Result := Mid;
                Goto Break;
            end
            else if StringArray[Mid] > SearchValue then
                High := Mid
            else
                Low := Mid;
        end;

        Break:

        if StringArray[Low] = SearchValue then
            Result := Low
        else if StringArray[High] = SearchValue then
                Result := High;
        if Result = -1 then
            writeln(SearchValue+' not found!')
        else
            writeln(SearchValue+' has an index of ',Result);
End.

Report
Re: Address Book Search Program Posted by zibadian on 15 Apr 2008 at 9:28 PM
: Thank you for replying. I think the program stops responding because
: a loop keeps running. I think I am using the goto incorrectly? I
: know the file is being read because I can call specific elements of
: the array and it works. It's just the binary search I'm having
: problems with.
:
: I don't know what you meant by the comparison between SearchValue
: and StringArray[i].
:
:
: Program Search;
: 
: Uses
:     WinCrt;
: 
: Var
:     f: Text;
:     i: Integer;
:     StringArray: Array[0..20] of String;
:     ArrayLength: Integer;
:     Low, Mid, High: Integer;
:     Result: Integer;
:     SearchValue: String;
: 
: Label
:     Break;
: 
: Begin
:     assign(f, 'filename.txt');
:     reset(f);
:         i := 0;
:         while not eof(f) do
:         begin
:             if i > 20 then begin
:                 writeln ('File is too big to fit in memory.');
:                 close(f);
:                 halt
:             end ;
:             readln(f, StringArray[i]);
:             i := i + 1;
:         end;
:     close(f);
: 
:     ArrayLength := i - 1;
: 
:     write('Enter Person ID to see contact details: ');
:     readln(SearchValue);
: 
:     Low := 0;
:     High := Length(StringArray[i])-1;
:     Result := -1;
: 
:     if StringArray[Low] = SearchValue then
:         Result := Low
:     else
:         if StringArray[High] = SearchValue then
:             Result := High
:     else
:         while (Low <> High) and (Low+1 <> High) do
:         begin
:             Mid := (High-Low) div 2 + Low;
:             if StringArray[Mid] = SearchValue then
:             begin
:                 Result := Mid;
:                 Goto Break;
:             end
:             else if StringArray[Mid] < SearchValue then
:                 High := Mid
:             else
:                 Low := Mid;
:         end;
: 
:         Break:
: 
:         if StringArray[Low] = SearchValue then
:             Result := Low
:         else if StringArray[High] = SearchValue then
:                 Result := High;
:         if Result = -1 then
:             writeln(SearchValue+' not found!')
:         else
:             writeln(SearchValue+' has an index of ',Result);
: End.
:
:
One of the comparisons (in red above) was incorrect. That broke the binary search. The red one is the corrected one. With "the comparison between SearchValue and StringArray[i]" is meant, any statement which takes the value stored in SearchValue and takes the value stored in the i-th element of the StringArray; and then compares (using one of the =, <, <=, >, >=, <> operators) those values with eachother. There are several of those in the code above.
Report
Re: Address Book Search Program Posted by Actor on 20 Apr 2008 at 3:02 AM
Program Search ;

Uses
    WinCrt ;

Var
    f: Text ;
    i: Integer ;
    StringArray: Array[0..20] of String ;
    ArrayLength: Integer ;
    Low, Mid, High: Integer ;
    Result: Integer ;
    SearchValue: String ;

Label
    Break ;

Begin
    assign(f, 'filename.txt') ;
    reset(f) ;
        i := 0 ;
        while not eof(f) do
        begin
            if i > 20 then begin
                writeln ('File is too big to fit in memory.') ;
                close(f) ;
                halt
            end ;
            readln(f, StringArray[i]) ;
            i := i + 1
        end ;
    close(f) ;
    {
        Note that, if the file loads successfully and the program reaches
        this point, i points to the array member that immediately
        follows the last record loaded, i.e., i points to garbage. 
    }
    ArrayLength := i - 1 ;

    write('Enter Person ID to see contact details: ') ;
    readln(SearchValue) ;

    Low := 0 ;
    High := Length(StringArray[i]) - 1 ;
    {
        This is the first error in the program.  High should be
        set to ArrayLength.  Instead it is set to 1 less than the
        length of StringArray[i].  But StringArray[i], as 
        pointed out above, has not been initialized, and so is garbage.
        
        Actually, Borland Pascal will initialize the string to a nul
        string whose length is zero, meaning High will be -1
    }    
    Result := -1 ;

        {
            The programmer apparently does not expect his algorithm to
            handle boundary cases and so makes provision in the following
            to make them special cases.  Actually, the algorithm will
            handle the boundary cases, so the complexity of the program is
            increased needlessly.
        }
    if StringArray[Low] = SearchValue then
        {
            This expression is very unlikely to ever evaluate to TRUE.
            SearchValue is probably entered as the three character
            (or whatever length) string that makes up the searched for key.
            On the other hand StringArray is the entire record, not
            just the key.
        }
        Result := Low
    else
        if StringArray[High] = SearchValue then
        {
             Again the expression is unlikely to ever evaluate to TRUE.
             However, in addition we note that if High is initially
             equal to -1 then the index is outside its range.  If range
             checking is ON then we can expect a run time error.
        }
            Result := High
    else
        {
            note that, going into the loop, Low = 0 and High = -1
        }
        while (Low <> High) and (Low+1 <> High) do
        {
             A logical error!
             Both Low = High and Low+1 = High are valid
             conditions and should not terminate the loop.  The correct
             test is Low <= High
        }
        begin
            Mid := (High - Low) div 2 + Low ;  { Mid = 0 }
            if StringArray[Mid] = SearchValue then  { test fails }
            begin
                Result := Mid ;
                Goto Break ;
            end
            else if StringArray[Mid] < SearchValue then  { test fails }
                High := Mid
            else
                Low := Mid ;   { but Mid = 0 so the value of
                                 Low remains unchanged and we go
                                 into an infinite loop!!!
                               } 
        end ;

        Break:

        if StringArray[Low] = SearchValue then
            Result := Low
        else if StringArray[High] = SearchValue then
                Result := High ;
        if Result = -1 then
            writeln(SearchValue+' not found!')
        else
            writeln(SearchValue+' has an index of ',Result) ;
End.

Report
Re: Address Book Search Program Posted by zibadian on 20 Apr 2008 at 4:55 AM
:
: 
: Program Search ;
: 
: Uses
:     WinCrt ;
: 
: Var
:     f: Text ;
:     i: Integer ;
:     StringArray: Array[0..20] of String ;
:     ArrayLength: Integer ;
:     Low, Mid, High: Integer ;
:     Result: Integer ;
:     SearchValue: String ;
: 
: Label
:     Break ;
: 
: Begin
:     assign(f, 'filename.txt') ;
:     reset(f) ;
:         i := 0 ;
:         while not eof(f) do
:         begin
:             if i > 20 then begin
:                 writeln ('File is too big to fit in memory.') ;
:                 close(f) ;
:                 halt
:             end ;
:             readln(f, StringArray[i]) ;
:             i := i + 1
:         end ;
:     close(f) ;
:     {
:         Note that, if the file loads successfully and the program reaches
:         this point, i points to the array member that immediately
:         follows the last record loaded, i.e., i points to garbage. 
:     }
:     ArrayLength := i - 1 ;
: 
:     write('Enter Person ID to see contact details: ') ;
:     readln(SearchValue) ;
: 
:     Low := 0 ;
:     High := Length(StringArray[i]) - 1 ;
:     {
:         This is the first error in the program.  High should be
:         set to ArrayLength.  Instead it is set to 1 less than the
:         length of StringArray[i].  But StringArray[i], as 
:         pointed out above, has not been initialized, and so is garbage.
:         
:         Actually, Borland Pascal will initialize the string to a nul
:         string whose length is zero, meaning High will be -1
:     }

{  This line was changed from my original program. The original read:
High := Length(StringArray) - 1 ;
which points to the last valid index of the 0-indexed array. In that case
the High is the highest index the array can have: 20. }

:     Result := -1 ;
: 
:         {
:             The programmer apparently does not expect his algorithm to
:             handle boundary cases and so makes provision in the following
:             to make them special cases.  Actually, the algorithm will
:             handle the boundary cases, so the complexity of the program is
:             increased needlessly.
:         }

{ True: the algorithm handles the boundary cases. I've inserted these to
speed up the algorithm. This way you don't need to perform a large number
of iterations inside the loop if you search for the first or last element. }

:     if StringArray[Low] = SearchValue then
:         {
:             This expression is very unlikely to ever evaluate to TRUE.
:             SearchValue is probably entered as the three character
:             (or whatever length) string that makes up the searched for key.
:             On the other hand StringArray is the entire record, not
:             just the key.
:         }

{ Again true, but instead of having the algorithm's complexity increased
by handling a case-insensitive substring comparison, I just took a simple
string-comparison. Usually the comparison is done in a function and is
based on the data-structure. Since I didn't know the internal
data-structure (strings with substring keys, records, sql-statements, etc.)
I took the most basic comparison. }

:         Result := Low
:     else
:         if StringArray[High] = SearchValue then
:         {
:              Again the expression is unlikely to ever evaluate to TRUE.
:              However, in addition we note that if High is initially
:              equal to -1 then the index is outside its range.  If range
:              checking is ON then we can expect a run time error.
:         }
:             Result := High
:     else
:         {
:             note that, going into the loop, Low = 0 and High = -1
:         }
{ See note about High. In the original code: Low = 0 and High = 20, when going into the loop. }
:         while (Low <> High) and (Low+1 <> High) do
:         {
:              A logical error!
:              Both Low = High and Low+1 = High are valid
:              conditions and should not terminate the loop.  The correct
:              test is Low <= High
{
If Low = High, then Mid = Low = High. If the searchstring doesn't match
StringArray[mid], then you will have an infinite loop, because Mid will never change.
If Low+1 = High, then Mid = Low. If the searchstring doesn't match
StringArray[mid], then you will have an infinite loop, because Mid will never change.
Since Low can never be greater than High, the condition Low <= High will
create an infinite loop. Low will always be set to Mid, as will High. This
means that Mid will always be between Low and High. These two statements
will never cause Low to be raised above High.
}
:         }
:         begin
:             Mid := (High - Low) div 2 + Low ;  { Mid = 0 }
{ See note about Low and High} 
:             if StringArray[Mid] = SearchValue then  { test fails }
{ See note about Low and High} 
:             begin
:                 Result := Mid ;
:                 Goto Break ;
:             end
:             else if StringArray[Mid] < SearchValue then  { test fails }
{ See note about Low and High} 
:                 High := Mid
:             else
:                 Low := Mid ;   { but Mid = 0 so the value of
:                                  Low remains unchanged and we go
:                                  into an infinite loop!!!
:                                }
{ See note about Low and High} 
:         end ;
: 
:         Break:
: 
:         if StringArray[Low] = SearchValue then
:             Result := Low
:         else if StringArray[High] = SearchValue then
:                 Result := High ;
:         if Result = -1 then
:             writeln(SearchValue+' not found!')
:         else
:             writeln(SearchValue+' has an index of ',Result) ;
: End.
: 
:
:
Report
Re: Address Book Search Program Posted by Actor on 20 Apr 2008 at 4:22 PM
: :
: : 
: : Program Search ;
: : 
: : Uses
: :     WinCrt ;
: : 
: : Var
: :     f: Text ;
: :     i: Integer ;
: :     StringArray: Array[0..20] of String ;
: :     ArrayLength: Integer ;
: :     Low, Mid, High: Integer ;
: :     Result: Integer ;
: :     SearchValue: String ;
: : 
: : Label
: :     Break ;
: : 
: : Begin
: :     assign(f, 'filename.txt') ;
: :     reset(f) ;
: :         i := 0 ;
: :         while not eof(f) do
: :         begin
: :             if i > 20 then begin
: :                 writeln ('File is too big to fit in memory.') ;
: :                 close(f) ;
: :                 halt
: :             end ;
: :             readln(f, StringArray[i]) ;
: :             i := i + 1
: :         end ;
: :     close(f) ;
: :     {
: :         Note that, if the file loads successfully and the program reaches
: :         this point, i points to the array member that immediately
: :         follows the last record loaded, i.e., i points to garbage. 
: :     }
: :     ArrayLength := i - 1 ;
: : 
: :     write('Enter Person ID to see contact details: ') ;
: :     readln(SearchValue) ;
: : 
: :     Low := 0 ;
: :     High := Length(StringArray[i]) - 1 ;
: :     {
: :         This is the first error in the program.  High should be
: :         set to ArrayLength.  Instead it is set to 1 less than the
: :         length of StringArray[i].  But StringArray[i], as 
: :         pointed out above, has not been initialized, and so is garbage.
: :         
: :         Actually, Borland Pascal will initialize the string to a nul
: :         string whose length is zero, meaning High will be -1
: :     }
: 
: {  This line was changed from my original program. The original read:
: High := Length(StringArray) - 1 ;
: which points to the last valid index of the 0-indexed array. In that case
: the High is the highest index the array can have: 20. }
: 
              {
                  Who changed it?  And why?

                  This may be implementation dependent but, in Borland
                  Pascal, Length takes an argument of type
                  String and returns the length of that string.
                  StringArray without an index is not a string.
                  I suspect whoever changed it did so because they were
                  getting a compile time error (type mismatch).

                  Even if it worked as you say and High becomes
                  the highest index of the array, this is not what is
                  needed.  If the file does not fill the array then any
                  elements of the array beyond the last one loaded from
                  the file will be garbage.  An absolute requirement for
                  binary search to work is that the array be sorted.  If
                  any elements are garbage then the array is not sorted.
                  High needs to be set to the last index loaded,
                  not the last index possible.
              }
: :     Result := -1 ;
: : 
: :         {
: :             The programmer apparently does not expect his algorithm to
: :             handle boundary cases and so makes provision in the following
: :             to make them special cases.  Actually, the algorithm will
: :             handle the boundary cases, so the complexity of the program is
: :             increased needlessly.
: :         }
: 
: { True: the algorithm handles the boundary cases. I've inserted these to
: speed up the algorithm. This way you don't need to perform a large number
: of iterations inside the loop if you search for the first or last element. }
        {
             Make it correct before you make it faster.  Since the
             program is not correct at this point any attempt to
             "speed up the algorithm" is premature.  Furthermore, as
             Kernighan and Plauger point out in Elements of
             Programming Style, programmers' conceptions of 
             what will speed up the program often are not true.  Testing
             is the only reliable way to find out.  In this particular
             case the chance that the desired element will exist at the
             boundary is small, particularly if the program is later
             modified to handle large files, so any hoped for increase in 
             speed is elusive and the increased complexity not justified.

             K&P wrote Elements of Programming Style over
             30 years ago and it surprises me that today's programmers
             so often fail to heed their advise.  Correctness and
             readability (style) take a back seat to speed and size. 
             Every programmer should read and understand EOPS.  True, the 
             examples are in Fortran and PL/1, but the effort will pay
             dividends.
        }
: 
: :     if StringArray[Low] = SearchValue then
: :         {
: :             This expression is very unlikely to ever evaluate to TRUE.
: :             SearchValue is probably entered as the three character
: :             (or whatever length) string that makes up the searched for key.
: :             On the other hand StringArray is the entire record, not
: :             just the key.
: :         }
: 
: { Again true, but instead of having the algorithm's complexity increased
: by handling a case-insensitive substring comparison, I just took a simple
: string-comparison. Usually the comparison is done in a function and is
: based on the data-structure. Since I didn't know the internal
: data-structure (strings with substring keys, records, sql-statements, etc.)
: I took the most basic comparison. }
        { Unfortunately the most basic comparison does not work. }
: 
: :         Result := Low
: :     else
: :         if StringArray[High] = SearchValue then
: :         {
: :              Again the expression is unlikely to ever evaluate to TRUE.
: :              However, in addition we note that if High is initially
: :              equal to -1 then the index is outside its range.  If range
: :              checking is ON then we can expect a run time error.
: :         }
: :             Result := High
: :     else
: :         {
: :             note that, going into the loop, Low = 0 and High = -1
: :         }
: { See note about High. In the original code: Low = 0 and High = 20, when going into the loop. }
: :         while (Low <> High) and (Low+1 <> High) do
: :         {
: :              A logical error!
: :              Both Low = High and Low+1 = High are valid
: :              conditions and should not terminate the loop.  The correct
: :              test is Low <= High
: {
: If Low = High, then Mid = Low = High. If the searchstring doesn't match
: StringArray[mid], then you will have an infinite loop, because Mid will never change.
: If Low+1 = High, then Mid = Low. If the searchstring doesn't match
: StringArray[mid], then you will have an infinite loop, because Mid will never change.
: Since Low can never be greater than High, the condition Low <= High will
: create an infinite loop. Low will always be set to Mid, as will High. This
: means that Mid will always be between Low and High. These two statements
: will never cause Low to be raised above High.
: }
    { Oops!  I missed two additional errors in the code.  See below. }
: :         }
: :         begin
: :             Mid := (High - Low) div 2 + Low ;  { Mid = 0 }
: { See note about Low and High} 
: :             if StringArray[Mid] = SearchValue then  { test fails }
: { See note about Low and High} 
: :             begin
: :                 Result := Mid ;
: :                 Goto Break ;
: :             end
: :             else if StringArray[Mid] < SearchValue then  { test fails }
: { See note about Low and High} 
: :                 High := Mid   { should be High := Mid - 1 }
: :             else
: :                 Low := Mid ;  { should be Low := Mid + 1 
                                      with these two corrections my
                                      arguments concerning the tests
                                      for the while loop stand.
                                  }
                                   { but Mid = 0 so the value of
: :                                  Low remains unchanged and we go
: :                                  into an infinite loop!!!
: :                                }
: { See note about Low and High} 
: :         end ;
: : 
: :         Break:
: : 
: :         if StringArray[Low] = SearchValue then
: :             Result := Low
: :         else if StringArray[High] = SearchValue then
: :                 Result := High ;
: :         if Result = -1 then
: :             writeln(SearchValue+' not found!')
: :         else
: :             writeln(SearchValue+' has an index of ',Result) ;
: : End.
: : 
: :
: :
:

Report
Re: Address Book Search Program Posted by Actor on 15 Apr 2008 at 9:42 PM
: Thank you for replying. I think the program stops responding because
: a loop keeps running. I think I am using the goto incorrectly? I
: know the file is being read because I can call specific elements of
: the array and it works. It's just the binary search I'm having
: problems with.
:

I've gone over your program several times and I can't figure out how it is supposed to work. I believe that the problem is that your search algorithm is simply wrong. It's more complex than it needs to be and (sorry) it simply does not work. I think your attempt to use this code has lead to more confusion than enlightenment.

The following makes use of an algorithm in Knuth's THE ART OF COMPUTER PROGRAMMING.

: I don't know what you meant by the comparison between SearchValue
: and StringArray[i].
:

This program assumes that the first three characters in each record make up the "key", i.e., the sample of data that you are searching for. It also assumes that the operator will enter exactly three characters (SearchValue) when prompted, no more, no less. Anything else and the program will not work.

Once the operator has entered SearchValue, those three characters have to be compared with the first three characters of StringArray[i] that is being examined. We extract the first three characters and store them in the string "Key". This is done in the statement
        Key := Copy(StringArray[i], 1, 3) ;

SearchValue is then compared to key (twice) in the statement
        if SearchValue < Key then
            High := i - 1
        else if SearchValue > Key then
            Low := i + 1
        else begin
            writeln(StringArray[i]) ;
            Halt
        end

If each character in SearchValue is the same as the corresponding character in Key then the two are equal; if not then which is greatest is determined by the ascii representation of the first mismatched characters. The statement tests for SearchValue < Key, SearchValue > Key. The only other possibility, SearchValue = Key, becomes the else part (and signals a successful end of the search).
Program Search;

Var
    f               : Text ;
    i               : Integer ;
    StringArray     : Array[0 .. 20] of String ;
    Low, High       : Integer ;
    SearchValue     : String ;
    Key             : String ;

Begin
    {
        load file into memory
    }
    assign(f, 'filename.txt') ;
    reset(f) ;
        i := 0 ;
        while not eof(f) do
        begin
            if i > 20 then begin
                writeln ('File is too big to fit in memory.') ;
                close(f) ;
                halt
            end ;
            readln(f, StringArray[i]) ;
            i := i + 1
        end ;
    close(f) ;

    write('Enter Person ID to see contact details: ') ;
    readln(SearchValue) ;
    {
        binary search algorithm from
        Knuth's THE ART OF COMPUTER PROGRAMMING
        Vol 3, 2nd edition, page 410
    }
    Low := 0 ;
    High := i - 1 ;

    while High >= Low do begin  { High < Low means the search has failed }
        {
            at this point we know that if SearchValue is in the
            array it satisfies

            Key[Low] <= SearchValue <= Key[High]
        }
        i := (Low + High) div 2 ;   { get midpoint }
        {
            Compare
        }
        Key := Copy(StringArray[i], 1, 3) ;
        if SearchValue < Key then
            High := i - 1
        else if SearchValue > Key then
            Low := i + 1
        else begin { Success!  Search = Key - the only other possibility }
            writeln(StringArray[i]) ;
            Halt
        end
    end ;
    {
        Failure
    }
    writeln(SearchValue + ' not found!')

End.


I've tested this program using the data I previously posted and it seems to work.

Actor

Report
Re: Address Book Search Program Posted by gashhek on 16 Apr 2008 at 5:13 AM
Thanks! The code was easy to understand. I have another question - In the last line of the program (writeln(SearchValue + ' not found!')), you have used '+'. I've been taught to concatenate using a comma. Is there a right way of using +'s and commas or is it just for preference?
Report
Re: Address Book Search Program Posted by Actor on 16 Apr 2008 at 11:12 AM
: Thanks! The code was easy to understand. I have another question -
: In the last line of the program (writeln(SearchValue + ' not
: found!')
), you have used '+'. I've been taught to concatenate
: using a comma. Is there a right way of using +'s and commas or is it
: just for preference?
:

I would say it's just a preference. Either one works and, as far as I know, the output is always the same, although it's possible that is some cases there may be a slight difference in what gets output.
Report
Re: Address Book Search Program Posted by zibadian on 16 Apr 2008 at 1:15 PM
: : Thanks! The code was easy to understand. I have another question -
: : In the last line of the program (writeln(SearchValue + ' not
: : found!')
), you have used '+'. I've been taught to concatenate
: : using a comma. Is there a right way of using +'s and commas or is it
: : just for preference?
: :
:
: I would say it's just a preference. Either one works and, as far as
: I know, the output is always the same, although it's possible that
: is some cases there may be a slight difference in what gets output.
:
Comma's only work in readln() and writeln() due to some compiler-magic. In all other cases you need to use the +. For example:
procedure MyWrite(TextToWrite: string);
begin
  writeln(TextToWrite);
end;

begin
  MyWrite('Hello', ' World'); { Compiler error }
  MyWrite('Hello' + ' World'); { Works }
end.

This is because readln() and writeln() can have any number of parameters of nearly any type, while self created procedures have the parameters and their types specified at compile-time.
Report
Re: Address Book Search Program Posted by Actor on 16 Apr 2008 at 1:53 PM
: : : Thanks! The code was easy to understand. I have another question -
: : : In the last line of the program (writeln(SearchValue + ' not
: : : found!')
), you have used '+'. I've been taught to concatenate
: : : using a comma. Is there a right way of using +'s and commas or is it
: : : just for preference?
: : :
: :
: : I would say it's just a preference. Either one works and, as far as
: : I know, the output is always the same, although it's possible that
: : is some cases there may be a slight difference in what gets output.
: :
: Comma's only work in readln() and writeln()

I assumed that concatenation in writeln() was the context of the question.

: due to some
: compiler-magic. In all other cases you need to use the +. For
: example:
:
: 
: procedure MyWrite(TextToWrite: string);
: begin
:   writeln(TextToWrite);
: end;
: 
: begin
:   MyWrite('Hello', ' World'); { Compiler error }
:   MyWrite('Hello' + ' World'); { Works }
: end.
: 
:
: This is because readln() and writeln() can have any number of
: parameters of nearly any type,

Actually both take parameters of only a few types: integer, char, real and their various cousins (byte, word, short, etc). Neither will handle arrays (except for strings) nor user defined types (other than enumerations). Also, I don't think you can use + in readln. Readln(FirstName + LastName) would not work, and even it did, it would not be good programming style.




1 2  Next



 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.