Solved

# Indexing Arrays

Posted on 1998-01-08
235 Views
Hello
Is it possible to index a bidimensional array by a certain column?
How can I do it?
Thank you so much.
Alberto
0
Question by:asimoes
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 8
• 4

LVL 1

Expert Comment

ID: 1217080
Please elaborate. I think I may understand what you're after, but I need more information. Do you want to index a two-dimensional array using information stored in a "column"? Or do you want to index just the second index of a two-dimensional array while leaving the first index constant?  Both are possible, but the code is different depending on what you are after.
0

Author Comment

ID: 1217081
Hello again.
Yes, I want to index a two-dimensional array using information stored in a "column".

Thanks again
Alberto simões

0

LVL 1

Accepted Solution

zircon earned 200 total points
ID: 1217082
Alberto,

You can index either or both indexes of a two-dimensional array using a column (or two columns for both indexes) by assigning the index value(s) to the array index(es) within the loop used to read in the data from a file. For example, to assign values to both indexes of the array from values stored in columns in a file, and to read data of integer type into the array, the following code should work:

program IndexArray;
const MaxIndex1 = 50 {the maximum value for index 1};
MaxIndex2 = 100 {the maximum value for index 2};
type arraytype = array [1..MaxIndex1, 1..MaxIndex2] of integer;
var ArrVariable: arraytype;
DataFile: text;
index1, index2, tempvalue: integer;

begin
assign (DataFile, 'mydata.dat');
reset (DataFile);
while not seekeof (DataFile) do
begin
ArrVariable[index1, index2] := tempvalue
end; {while}
close (DataFile)

{the rest of the program}

end. {main}

Clearly, good programming style would dictate putting this code into a procedure and calling it from the main body, but for the sake of simplicity for this example I put it in the main body.

Bruce Brasaemle
0

Author Comment

ID: 1217083
Hello again

I still have the same problem becouse I cannot use files.
Just use temporary arrays to solve the problem.

Thanks again
alberto simoes
0

LVL 1

Expert Comment

ID: 1217084
How is the column of numbers input?  Are the values assigned within the program?  ...from another temporary array?

Bruce
0

Author Comment

ID: 1217085
The values of the array are assign within the program.
This is the code of the program.
This is a table of stores and products. The products are column 2, the cost of sale column 4, the cost of buy column 5 and I want  to index by the column 5(ascending) and 4(descending) to get the better profite for the store when I have the same product.

program loja(input,output);
uses crt;

type
tabela_1 =array[0..10,0..10] of integer;
var
tab_loja,tab_sel:tabela_1;

opcao,cod_prod,qtd_prod,i,j,q,a,b:integer;
prd_prod:char;
nome_forn,nome_prod:string;

procedure carrega_loja(var x_forn:tabela_1);

begin
tab_loja[i,j+0]:=1;
tab_loja[i,j+1]:=1;
tab_loja[i,j+2]:=20;
tab_loja[i,j+3]:=25;
tab_loja[i,j+4]:=19;  {20}
tab_loja[i,j+5]:=10;

tab_loja[i+1,j+0]:=1;
tab_loja[i+1,j+1]:=2;
tab_loja[i+1,j+2]:=30;
tab_loja[i+1,j+3]:=30;
tab_loja[i+1,j+4]:=25;
tab_loja[i+1,j+5]:=9;

tab_loja[i+2,j+0]:=2;
tab_loja[i+2,j+1]:=4;
tab_loja[i+2,j+2]:=50;
tab_loja[i+2,j+3]:=30;
tab_loja[i+2,j+4]:=25;
tab_loja[i+2,j+5]:=1;

tab_loja[i+3,j+0]:=2;
tab_loja[i+3,j+1]:=3;
tab_loja[i+3,j+2]:=40;
tab_loja[i+3,j+3]:=20;
tab_loja[i+3,j+4]:=20;
tab_loja[i+3,j+5]:=8;

tab_loja[i+4,j+0]:=3;
tab_loja[i+4,j+1]:=1;
tab_loja[i+4,j+2]:=5;
tab_loja[i+4,j+3]:=20;
tab_loja[i+4,j+4]:=15;
tab_loja[i+4,j+5]:=5;

tab_loja[i+5,j+0]:=3;
tab_loja[i+5,j+1]:=3;
tab_loja[i+5,j+2]:=60;
tab_loja[i+5,j+3]:=10;
tab_loja[i+5,j+4]:=10;
tab_loja[i+5,j+5]:=6;

tab_loja[i+6,j+0]:=4;
tab_loja[i+6,j+1]:=2;
tab_loja[i+6,j+2]:=5;
tab_loja[i+6,j+3]:=25;
tab_loja[i+6,j+4]:=20;
tab_loja[i+6,j+5]:=4;

tab_loja[i+7,j+0]:=5;
tab_loja[i+7,j+1]:=4;
tab_loja[i+7,j+2]:=5;
tab_loja[i+7,j+3]:=25;
tab_loja[i+7,j+4]:=22;
tab_loja[i+7,j+5]:=2;
end;

procedure mostra_loja;

var
w,z:integer;

begin

for w:=0 to 7 do

begin
for z:=0 to 5 do
write(tab_loja[i+w,j+z],'  ');
writeln;
end;
end;

procedure mostra_sel(n:integer);

var
w,z:integer;

begin

for w:=0 to n do

begin
for z:=0 to 5 do
write(tab_sel[i+w,j+z],'  ');
writeln;
end;
end;

procedure select_prod;

var
q,w,z,x:integer;

begin
q:=0;

for w:=0 to 7 do
begin
if (tab_loja[i+w,j+1])=1 then
begin
for z:=0 to 5 do

tab_sel[i+q,j+0]:=tab_loja[i+w,j+0];
tab_sel[i+q,j+1]:=tab_loja[i+w,j+1];
tab_sel[i+q,j+2]:=tab_loja[i+w,j+2];
tab_sel[i+q,j+3]:=tab_loja[i+w,j+3];
tab_sel[i+q,j+4]:=tab_loja[i+w,j+4];
tab_sel[i+q,j+5]:=tab_loja[i+w,j+5];

q:=q+1;
end;

end;
writeln;
mostra_sel(q-1);

end;

procedure indexa;

var
tmp:array [1..10] of integer;
a,b,c,d,h:integer;

begin
for a:=1 to 8 do
begin
for c:=1 to 6 do
tmp[c]:=tab_loja[a,c];
h:=tab_loja[a,5];
d:=a;
for b:=a to 8 do
if (tab_loja[b,5]<h) then
begin
d:=b;
h:=tab_loja[b,5];
end;
for c:=1 to 6 do
begin
tab_loja[a,c]:=tab_loja[d,c];
tab_loja[d,c]:=tmp[c];
end;
end;
end;

{***********************CORPO PRINCIPAL****************************}

BEGIN

i:=1;
j:=1;
clrscr;

writeln('                      PROGRAMA DE INDEXAO DE MATRIZ');
writeln('                      -------------------------------');
writeln;
carrega_loja(tab_loja);
mostra_loja;
writeln;

indexa;
mostra_loja;

select_prod;
END.

0

LVL 1

Expert Comment

ID: 1217086
Alberto,

I'm still thinking about the indexing or sorting issue, but I have a couple of things to consider regarding other portions of your code. Are i and j always equal to 1 and the dimensions of the array always fixed at 10 by 10?  If so,

1)  Could you use numbers instead of expressions (such as i+1, j+2) in procedure carrega_loga?  In other words, the statement:

tab_loja[i+1,j+2]:=30;

would become:

tab_loja[2,3]:=30;

Changing these expressions would make the program more readable and minimize the potential for errors in indexing the array.  My first preference would be to put all of the data in a text file and read it into the array using a procedure with while and for loops, but you've already said that can't be done, so I'll work with those rules.

2) You shouldn't need to use the global variables i & j to index arrays within procedures if their values are always equal to 1.  If i & j are always 1, please consider rewriting procedure mostra_loja as follows:

procedure mostra_loja(tab_loja: tabela_1);
{bring the array tab_loja into the procedure as a value
parameter rather than depending on the global variable
array - a matter of style and good programming practice}

var
w,z:integer;

begin

for w:=1 to 8 do

begin
for z:=1 to 6 do
write(tab_loja[w,z],' ');
writeln;
end;
end;

By indexing w from 1 to 8 and z from 1 to 6 you eliminate the need to use the global variables i and j to index the array, assuming the values of i and j are equal to 1.

Also, it is generally considered good programming style or practice to always pass the values of global variables to a procedure or function using value parameters rather than just using the global variables within a function or procedure. This practice prevents the value of the global variable from being changed accidentally within a subprogram.

Just some thoughts.  I hope they help.

Let me know if I'm missing something - like a reason i and j may need to be changed to a value other than 1.

Bruce
0

LVL 1

Expert Comment

ID: 1217087
Alberto,

In procedure select_prod, the "for z:=0 to 5 do" statement doesn't appear to do anything. Please try the following code for procedure select_prod:

procedure select_prod;

var
q,w,z:integer;
{I deleted x, because I couldn't find where you had used it.}

begin
q:=0;

for w:=1 to 8 do {instead of 0 to 7}
begin
if (tab_loja[w,2])=1 then
{note changes in array indexes}
begin
q:=q+1;
for z:=1 to 6 do {instead of 0 to 5}
tab_sel[q,z]:=tab_loja[w,z];
end; {if then}
end; {for w}

writeln;
mostra_sel(q);
{q should now pass the correct value to n in mostra_sel without subtracting 1}

end;

I'm not sure I've touched on anything that may help solve your problem yet, but I do hope you find my suggestions helpful.

Bruce
0

LVL 1

Expert Comment

ID: 1217088
Alberto,

I think I now understand some of my confusion in determining what you are after.  When you use the term "index" or "indexing", I think you mean what I call a "sort" or "sorting".  When I use the term "index" or "indexing", I'm using it to mean increment the subscript of an array.  Technically speaking, the subscript of an array is its index.

Is my perception correct?  If so, I know I can help you to get your data to sort the way you want it to, but it may not be possible to sort by both column 5 (ascending) and column 4 (descending) at the same time and have it displayed in a useful manner.

If my new perception of your problem is correct, I have two options for you:

1) You could do a sort for each column and display them separately. The disadvantage of this approach would be that you would need to compare the displays of two sorts to determine the most profitable option for your store.

2) You could calculate the profit (column 4 - column 5), store it in a new column within the array (column 7), and then sort the records in the array based on column 7 (descending, to show the highest profit margin at the top).

My preferred approach, if I were you, would be number 2.  The calculation would just take a simple for loop, and then the sort would take nested for loops similar to what you have in procedure indexa.  I can provide source code for all of this if you like, including a somewhat cleaner sorting procedure than indexa, but please be patient and give me a little time to do it.

Let me know how you would like to procede.

Bruce
0

LVL 1

Expert Comment

ID: 1217089
Alberto,

As I promised last week, here is the source code for two
based on my previously stated preference of calculating the
profit margin and storing it in a seventh column.  The first
is a procedure to calculate the profit margin and store the
profit margin in column 7 of the array (table).  The second
procedure sorts the records (or rows) in the table in descending
order by the profit margin.

I recommend that, in the main body of your program, you call
"procedure profit" immediately after "procedure carrega_loja",
and then call the new "procedure indexa" immediately after
"procedure profit".  You should also modify the "for loops" in
the remaining procedures (used to print to the screen, etc.) to
account for the seventh column in the table.

I hope you find these suggestions helpful.  Let me know if I can
be of more help to you.  Good luck.

Bruce

{1) Procedure to calculate profit (column 4 - column 5):}

procedure profit(tab_loja: tabela_1);

var x: integer;

begin
for x := 1 to 8 do
tab_loja[x,7] := tab_loja[x,4] - tab_loja[x,5];
end;

{2) Procedure to sort table by profit using a bubble sort that
allows early exit from the sort if it is completed prior to final
pass (replaces old procedure indexa):}

procedure indexa(tab_loja: tabela_1);

var tmp: array[1..10] of integer;
pass, a, b: integer;
sortFinished: boolean;  {early exit test variable}

begin

pass := 0;  {initialize pass counter}

repeat
pass := pass + 1;  {increment pass counter}

{initialize early exit test variable before each pass}
sortFinished := true;

for a:= 1 to (8 - pass) do
begin

{test profit margin of record "a" against profit in
record "a+1"}
if tab_loja[a,7] < tab_loja[a+1,7] then
begin
sortFinished := false;  {sort not yet completed}

{switch order of records to sort descending by
profit margin}
for b := 1 to 7 do
begin
tmp[b] := tab_loja[a,b];
tab_loja[a,b] := tab_loja[a+1,b];
tab_loja[a+1,b] := tmp[b];
end;  {for b}

end; {if then}

end; {for a}

until sortFinished; {until sortFinished = true at the end of a pass}

end; {procedure indexa}
0

LVL 1

Expert Comment

ID: 1217090
Hello again,

Whoops, in procedures profit and indexa, the parameters needs to be declared as a variable parameters.  Please replace the headers for each procedure with the following lines.  Sorry for the confusion.

Bruce

procedure profit(var tab_loja: tabela_1);

procedure indexa(var tab_loja: tabela_1);
0

Author Comment

ID: 1217091
Hello
Thanks for the code and the help.
I decided to use the solution to create a column(7) in the array with the profit and then index it by that column and it worked.
So thanks again.
Now I'm trying to do the screens for the user input and I would like to ask a new question.
I'll ask here and in the main page.
-> I want the user to answer a question where the answers are just the numbers (1), (2) or (3). How can I make this so that the user can´t answer with letters or any other caracters but just 1,2 or 3. And when the user gives just an "enter" the cursor passes to the next line, but I want it to stay in the same position.
How can I control this?

Thanks again
Alberto Simões

0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

### Suggested Solutions

Text To Speech and Speech To Text Enabled Delphi Application; 6 2,847
Unsigned int64 to unsigned int32 10 1,752
Neural Networks with Delphi 3 1,703
Delphi TSQL Connection runtime creating 1 1,143
Deploying our service is a grudge match between customer benefits and customer pain. In one corner, rolling out fixes (yay!) and delivering new features (double yay!). In the other corner, training on new features (boo – sounds like work), and chan…
In this series, we will discuss common questions received as a database Solutions Engineer at Percona. In this role, we speak with a wide array of MySQL and MongoDB users responsible for both extremely large and complex environments to smaller singl…
Six Sigma Control Plans
This video shows how to use Hyena, from SystemTools Software, to update 100 user accounts from an external text file. View in 1080p for best video quality.
###### Suggested Courses
Course of the Month4 days, 20 hours left to enroll