Sorting and searching data for sales

We are doing a program in class to read in about 100 lines of code, store it, and sort it. The code is first an employee's ID number followed by their sales. There are only 12 employees. We have to store it in a 12x4 2D array. We have to have the employee number, the total number of sales they made (counter), their total sales amount, and the average of all their sales/count. My issue is figuring out how to write a search function that is not already in the library. He mentioned returning the subscript from the search function to associate that ID number with a subscript. We can only use user-created functions and 2d arrays. Have not learned pointers or vectors yet.

So far I have done the bare bones b/c I'm not sure how to continue reading 100 values, but condensing them down to 12 people.


//example of data in file. ID number on left and a sale made on right. 
322 10.80
848 920.00
828 1267.00
848 8320.00
229 66330.00


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
 
 void sort(float sales[], int size) //the bubble sort we have to use 
 {
     int i, j;
    for(i=0;i<size-1;i++)
    {
        for(j=0;j<size-i-1;j++)
        {
            //checking if previous value is
            //grater than next one or not
            if(sales[j]>sales[j+1])
            {
                float temp=sales[j];
                sales[j]=sales[j+1];
                sales[j+1]=temp;
            }
        }
    }
 }
 
 int search_ID(float sales[][4])  //completely stuck here 
 {
     int r;
     for(c=0;c<=0;c++)
     {
     for(r=0;r<13;r++)
     {
         if(sales[r][c]!=sales[r][c])  //was thinking of if the ID number matches the number already stored, then skip or only store col 1 for the sales
     }
     }
     return sub;
 }
 
 float avgSale(float sales[][4], int rowNum) //the avg sales for each employee
 {
     int r, c, totalSales;
     float avg;
     for(r=rowNum;r<=rowNum;r++)  //would just use a for loop in main to call each row num. 
     {
       for (c=3;c<4;c++)
         {
           avg=sales[r][c]/totalSales;
         }
     }
            return avg;
 }
 
 void printReport(float sales[][4])  //we have to print a report with ID, Num sales, total sales, and avg for each so the 4 columns 
 {
     int r, c;
     cout<<fixed<<setprecision(2);
     for(r=0;r<13;r++)
     {
         for(c=0;c<=1;c++)
         {
       cout<<sales[r][c]<<" ";
         }
         cout<<endl;
     }
 }
 
/**************************************************************************************/
//beginning of main 
int main()
{
  
  infile.open("C://data//input//Sales.txt");  //opening the infile 
  outfile.open("C:\\data\\SalesmenReport.txt"); //opening the outfile 
  
  if(!infile)  //check if file opens 
  {
      cout<<"File did not open. Please try again."<<endl;
      return 0;
  }
  
    int size=12; 
    int sub;
    float avg;
    float sales[size][4];
    
     int r, c, sub;
     
     for(r=0;r<13;r++)
     {
         for(c=0;c<=1;c++)
         {
             infile>>sales[r][c];
             sub=search_ID(sales); //he showed us this as an example to call the search, idk where to put it or what to put in it. 
         }
     }
                        
    printReport(sales);
 
    avg=avgSale(sales, 0);
Last edited on
> int search_ID(float sales[][4])
¿what are you searching?

some pseudocode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def employee:
	id
	quantity
	sales_amount
	average

def search_id(table, id):
	//table is a collection
	//each entry has the fields
	//id, quantity, sales_amount, average
	for K in range(len(table)):
		if table[K].id == id:
			return K
	return NOT_FOUND

def load_from_file(file):
	table = collection(employee)

	//each line of the file has an id and a sale
	while [id, sale]=read_line(file):
		position = search_id(table, id)
		if position not_eq NOT_FOUND:
			add_sale(table[position], sale)
		else:
			new_entry(table, id, sale)

def add_sale(employee, sale):
    employee.quantity += 1
    employee.sales_amount += sale
    employee.average = employee.sales_amount / employee.quantity


for the code
you have float sales[12][4] to represent the collection, where each row holds the data of one employee
so sales[K] is one employee and each column represent a different field
sales[K][0] is the id
sales[K][1] is the number of sales
sales[K][2] is the sales amount
sales[K][3] is their average

¿can you translate the functions? I'll give you `new_entry()'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void new_entry(float sales_report[][4], int size, float id, float sale){
    for(int K=0; K<size; ++K)
        if(sales_report[K][0] == 0){ //an empty entry (an id=0 would be invalid)
			//filling the data
			sales_report[K][0] = id;
			sales_report[K][1] = 1; //number of sales
			sales_report[K][2] = sale; //sales amount
			sales_report[K][3] = sale; //average

			return; //so we don't fill another empty entry
        }
	//if we reach here then the table was full
	//perhaps you should signal an error
}

Thank you, that helps a lot. What we are "searching" as he calls it is for the subscript of that employee number so example:

322 $10.89
848 $1,200.50
322 $682

322 is in here twice so we find where he was first written to (what position) and add the $682 to his $10.89 and count it as two sales so far. I have 12 employees I have to do this for. Tomorrow morning I will try out what you wrote here, but I still need to figure out how to add multiple entries to only 12 id numbers.
Using a std::map might be useful.

http://www.cplusplus.com/reference/map/map/

Employee ID is the key value. Read each line in your file, separating the two values into temp Employee ID and a Sales Amount variables. Maybe an int for key and a std::vector for the sales amount?

Search your container for an already stored employee. If found add the new sales amount to the vector.

If this is a new employee, create a temp vector with the sales amount and insert a new element to your map (ID + sales vector).

Keep repeating until all the data in your file has been read.

The number of sales any employee makes being stored in a vector almost a no-brainer, you can expand the size as needed. Easy to find an employee, and know how many sales they made (the vector's size).
We actually haven't learned vectors yet so I have to be able to do it as a 2D array. He gave us an example of what the function call might look like, but it was very vague.
His example was for a 1D array and 4 of them titled: ID, Sales, Sum, and Avg
1
2
sub=searchInsert(ID, Sales);  //his example was for a 1D array with 4 arrays. 
sales[sub]=sales[sub]+count //not sure if his handwriting says count, salary or what.  


He explained that the search function has to return the subscript of the array if the value to be read in is the same as one previously read. Once we return that subscript, we increment the sales column (col 1) so for every loop iteration, it continually adds the sum of all the sales everytime it gets a repeat of one of the 12 employee numbers.

ex.
322 $10.80
848 $520.40
932 $1200.48
322 $600.00

once the second 322 is written, the value for row 0 col 1 needs to be changed from $10.80 to $610.80
> We have to store it in a 12x4 2D array.
>> His example was for a 1D array and 4 of them titled: ID, Sales, Sum, and Avg
>> He explained that the search function has to return the subscript of the array
perhaps you should read the assignment.

I have already showed you the search() function, ¿what part you don't understand?
What I have so far returns the subscript that number was written to. I need to figure out what to do if the subscript is equal to one already written in the array then don't make a new value, instead, sum the values. If it doesn't, make a new entry on that row.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  for(r=0;r<13;r++)  //reading the files in 
     {
         for(c=0;c<=1;c++)
         {
             infile>>sales[r][c];
             ID_Num=sales[r][0];
             sub=testSearch(sales, ID_Num, r);
           
         }
         
          cout<<"Sub: "<<sub<<endl;
    
     }
     
//function
 float testSearch(float sales[][4], int ID_Num, int rowNum)  //for row that you are on, for column 0, if sales of that 
                                                               //row==ID number you sent, return the sub
 {
       int r, c;
       for(r=0;r<=rowNum;r++)
     {
         for(c=0;c<1;c++)
         {
            if (sales[r][c]==ID_Num)
            {
                return r;
            }
           
         }
     }
 }



Sub: 0      322
Sub: 1      848
Sub: 2      828
Sub: 1      848
Sub: 4      229
Sub: 5      254

These are the subscripts it returns when I search the numbers, I need 848 to not be written again since it was already written. 

1
2
3
4
5
  for(r=0;r<13;r++)  //reading the files in 
     {
         for(c=0;c<=1;c++)
         {
             infile>>sales[r][c];
that's wrong
- you are not supposed to read into `sales', you should process each entry in order to fill the "table"
- you shouldn't have a table, but 4 arrays instead
- as you have now, you'll only read thirteen rows of the file, also will try to write to sales[12] which is invalid

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const int n = 12; //the number of employees
//four arrays, all initialised to 0
//note that they are not all the same type
int ID[n] = {};
int Sales_qty[n] = {};
double Sum[n] = {};
double Avg[n] = {};

//reading the file
int employee_id;
double sales_amount;
while(input >> employee_id >> sales_amount){ //read the whole file
   int position = search(ID, n, employee_id);  //¿what if the id is not found?
   ID[position] = employee_id;
   ++Sales_qty[position];
   Sum[position] += sales_amount;
   //you may compute the Avg later
}


now, on your testSearch() function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
float testSearch(float sales[][4], int ID_Num, int rowNum)  //for row that you are on, for column 0, if sales of that 
                                                               //row==ID number you sent, return the sub
 {
       int r, c;
       for(r=0;r<=rowNum;r++) //out of bounds
     {
         for(c=0;c<1;c++) //¿why a loop for only one iteration?
         {
            if (sales[r][c]==ID_Num)
            {
                return r;
            }
           
         }
     }
   //¿what do you return if the id is not found?
 }
I think the big problem you're having is that you aren't clear on how the data is stored. What is sales[3][2]? What is sales[11][0]? If this isn't crystal clear, then there is NO HOPE of writing code to manipulate it.

Here is how I'd store it, given what you said in the original post:
1
2
3
4
5
6
7
8
9
10
11
12
13
// Here is the data: 12 rows and 4 columns.
// Column 0 is the employee ID
// Column 1 is the number of sales made
// Column 2 is the total dollar value of all sales
// Column 3 is the average of sale value

const_expr unsigned NUM_ROWS=12;
float data[NUM_ROWS][4];

// Use an enum to create symbols for the column indexes. If you haven't
// learned about enums, you just need to know that this creates
// the 4 names with values 0,1,2,3
enum { ID, COUNT, SALES, AVG};


Note that I called the array "data" instead of "sales". Why call it "sales" when only two columns have sales data?

Now we're crystal clear on the data. data[x] contains the data for a single sales person. The columns contain the ID, count, total sales and average sale, respectively. We'll use the enum values to access the columns to be clear what we're doing.

Here's a search function. Notice how I've used "row" as the row index and ID as the column index. This makes it very clear what I'm doing. I've also added a comment that explains what the function does. If there's a problem calling the function, I can refer to the comment help determine if I'm calling the function wrong, or if the function is returning the wrong thing.
1
2
3
4
5
6
7
8
9
10
11
12
// Given the data with "size" rows, search for "id" and return
// the row number that matches or -1 if the ID isn't found
int search_ID(float data[][4], unsigned size, float id)
{
    int row;
    for (row=0; row < size; ++row) {
        if (data[row][ID] == id) {
            return row;
        }
    }
    return -1;
}


Ok thanks guys, I will try to implement what you have said here. We can't do 4 arrays, the homework says we have to do it as 1 2D array. He showed us with 4 arrays and that would make it so much easier, but the 2D part made it so much harder.
Topic archived. No new replies allowed.