How to search and sort a 2D array - c++

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. Could someone please help demonstrate how to begin sorting this 2D array? Please be as verbose as possible as this is only my 2nd semester. I apologies if I have not explained it properly.
// 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
// the bubble sort we have to use
void sort(float sales[], int size)
{
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;
}
}
}
}
// completely stuck here
int search_ID(float sales[][4])
{
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 or doesn't match perform a t/F
}
}
}
return sub;
}
// the avg sales for each employee
float avgSale(float sales[][4], int rowNum)
{
int r, c, totalSales;
float avg;
// would just use a for loop in main to call each row num.
for(r = rowNum; r <= rowNum; r++) {
for (c = 3; c < 4; c++) {
avg=sales[r][c]/totalSales;
}
}
return avg;
}
// we have to print a report with ID, Num sales, total sales, and avg for
// each so the 4 columns
void printReport(float sales[][4])
{
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;
}
}
int main()
{
infile.open("C://data//input//Sales.txt");
outfile.open("C:\\data\\SalesmenReport.txt");
//check if file opens
if(!infile) {
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];
// he showed us this as an example to call the search, idk where
// to put it or what to put in it.
sub = search_ID(sales);
}
}
printReport(sales);
avg = avgSale(sales, 0);
Edit & Run
I expect when the program is completed to be able to print the 12 employee ID numbers, their number of sales, total amount each salesman made, and each person's average clear across left to right in a table.

You need to pass empId (to be searched) as a parameter to the function. For example, following function will return 1 if it finds the record with given employee id, otherwise 0.
int search_ID(float sales[][4], int empIdToBeSearched)
{
int r, found;
found = 0;
for(r = 0; r < 13; r++) {
if(sales[r][0] == empIdToBeSearched) {
found = 1;
break;
}
}
return found;
}
And while sorting the records you should apply the sorting algorithm on any column that you want but while swapping the data you should swap the entire row and not just the particular cell. So in this case your temp (used in sort function) should be 2-D array something like float temp[1][4].

Related

Sliding Window Function to Count Unique Words in Vector in C++

I have a vector with a block of text read from a txt file. I need to use a window function to find the number of unique words in a sliding window of size K. I've found this count online which uses a similar technique but with an int array. However, when I try to adjust to code to fit my situation I'm getting an error:
"no match for ‘operator+’ (operand types are ‘std::vectorstd::__cxx11::basic_string<char >’ and ‘int’)gcc"
My question is, should I not be using a vector here? Should I be trying to figure out how to convert to an array? I didn't think there was too much of a difference between the two that I wouldn't be able to adapt the code, but perhaps I am wrong. I literally just started to learn C++ last night. Please help :(
// Counts distinct elements in window of size K
int countWindowDistinct(vector<string> text, int K)
{
int dist_count = 0;
// Traverse the window
for (int i = 0; i < K; i++) {
// Check if element arr[i] exists in arr[0..i-1]
int j;
for (j = 0; j < i; j++)
if (text[i] == text[j])
break;
if (j == i)
dist_count++;
}
return dist_count;
}
// Counts distinct elements in all windows of size k
void countDistinct(vector<string> text, int N, int K)
{
// Traverse through every window
for (int i = 0; i <= N - K; i++)
cout << countWindowDistinct(text + i, K) << endl;
}
int main()
{
//Declares two vectors
std::vector<std::string> book;
std::vector<std::string> unqWords;
//reads a text file and stores the contents in the vector book
book = readFile("test.txt");
//Ensures that all words in the text are lowercase
makeLower(book);
//Loops through the text (one word at a time) and removes all alphanumeric characters
for(int i = 0; i < book.size(); i++)
{
//Function used to remove alphanumeric characters from words
book[i] = removeAlpha(book[i]);
}
int K = 4;
int N = calculate_size(book);
// Function call
countDistinct(book, N, K);
}

Is there a way to count the number of ocurrences of each element of a string array?

I have the following code that does exactly what I want. The problem is that I need the sample array to compare the strings and keep the count. Is there a way to count the number of occurrences of each string on any array without a sample?
For a little bit more context, the initial problem was to read data from a .txt file including vehicles information, like:
Volkswagen Jetta
Ford Focus
Volkswagen Jetta
And count the number of vehicles of each brand. Keep in mind that this is from an introductory course for programming, and we don't know how to use vectors or maps.
#include <iostream>
#include <string>
using namespace std;
using std::string;
#define MAX 20
int main(){
int counter[MAX];
string arr[MAX]={"ABC","AOE","ADC","ABC","ADC","ADC"};
string sample[MAX]={"ABC", "AOE", "ADC"};
for(int i=0; i<=MAX; i++){
counter[i]=0;
}
for(int i=0; i<MAX;i++){
for(int j=0; j<MAX; j++){
if (sample[i]==arr[j]){
counter[i]++;
}
}
}
for(int i=0; i<3;i++){
cout<< sample[i] << "=" << counter[i]<<endl;
}
return 0;
}
All you are expected to do is keep a list (an array will do) of brand names, and an array of counts for each name:
std::string brand_names[100];
int counts[100]; // number of times each element of brand_names[] was read from file
int num_items = 0;
Each time you read a brand name from file, try to find it in the array of strings. If found, just add one to the count at the same index. If not found, add it to the end of the brand_names[] array, add 1 to the end of the counts[] array, and increment num_items.
You do not need anything more than a simple loop for this:
an outer loop to read the next brand name from file
an inner loop to try to find the brand name in the list
If you want to solve this problem without knowing the initial values of the sample array:
Create an empty sample array. When you see new elements add them to this array.
Use a variable sample_size to keep track how many samples have been seen. Below is a simple example which doesn't use std::vector or dynamic allocation.
int main()
{
std::string arr[MAX] = { "ABC","AOE","ADC","ABC","ADC","ADC" };
std::string sample[MAX];
int sample_size = 0;
int counter[MAX] = { 0 };
for (int i = 0; i < MAX; i++)
{
if (arr[i].empty()) break;
bool sample_found = false;
for (int j = 0; j < sample_size; j++)
if (arr[i] == sample[j])
{
sample_found = true;
counter[j]++;
break;
}
if (!sample_found)
{
sample[sample_size] = arr[i];
counter[sample_size]++;
sample_size++;
}
}
for (int i = 0; i < sample_size; i++)
cout << sample[i] << "=" << counter[i] << std::endl;
return 0;
}

Bug in selection sort loop

I need to make a program that will accept a input file of numbers(integer.txt) which will be sorted one number per line, into a vector, then use a selection sort algorithm to sort the numbers in descending order and write them to the output file (sorted.txt). I'm quite sure something is wrong in my selectionSort() function that is causing the loop not to get the right values, because after tested with cout I get vastly improper output. I'm sure it's a beginning programmer's goof.
vector<string> getNumbers()
{
vector<string> numberList;
ifstream inputFile ("integer.txt");
string pushToVector;
while (inputFile >> pushToVector)
{
numberList.push_back(pushToVector);
}
return numberList;
}
vector<string> selectionSort()
{
vector<string> showNumbers = getNumbers();
int vectorMax = showNumbers.size();
int vectorRange = (showNumbers.size() - 1);
int i, j, iMin;
for (j = 0; j < vectorMax; j++)
{
iMin = j;
for( i = j; i < vectorMax; i++)
{
if(showNumbers[i] < showNumbers[iMin])
{
iMin = i;
}
}
if (iMin != j)
{
showNumbers[j] = showNumbers [iMin];
}
}
return showNumbers;
}
void vectorToFile()
{
vector<string> sortedVector = selectionSort();
int vectorSize = sortedVector.size();
ofstream writeTo;
writeTo.open("sorted.txt");
int i = 0;
while (writeTo.is_open())
{
while (i < vectorSize)
{
writeTo << sortedVector[i] << endl;
i += 1;
}
writeTo.close();
}
return;
}
int main()
{
vectorToFile();
}
vectorRange defined but not used.
In your selectionSort(), the only command that changes the vector is:
showNumbers[j] = showNumbers [iMin];
Every time control reaches that line, you overwrite an element of the vector.
You must learn to swap two values, before you even think about sorting a vector.
Also, your functions are over-coupled. If all you want to fix is selectionSort, then you should be able to post that plus a main that calls it with some test data and displays the result, but no, your functions all call each other. Learn to decouple.
Also your variable names are awful.

Filling a Two Dimensional array with random numbers in C++

I am making a program that inserts a two dimensional array with random integers and locates the highest value to display it and it's coordinates in the array. I am using three files. utils.h, utils.cpp, and main.cpp. My program displays an array but it is not correct and I cannot figure out why despite all my research. Any help would be appreciated. This is a college assignment and I know that my professor wants main and utils.h left as is so the only thing I can change is utils.cpp. Thank you for your time.
#include "utils.h"
void fillTable(int table[ROW_COL_SIZE][ROW_COL_SIZE]) {
for(int i = 0; i < ROW_COL_SIZE; i++) {
for(int c = 0; c < ROW_COL_SIZE; c++) {
cout << rand() % table[i][c];
}
}
}
void findLargest(int table[ROW_COL_SIZE][ROW_COL_SIZE], int& largestRow,
int& largestCol) {
largestRow = 0;
largestCol = 0;
for ( int i = 0; i < ROW_COL_SIZE; i++) {
for ( int j = 0; j < ROW_COL_SIZE; j++) {
if(table[i][j] > table[largestRow][largestCol]) {
largestRow = i;
largestCol = j;
}
}
}
}
void displayTable(int table[ROW_COL_SIZE][ROW_COL_SIZE]) {
for (int i = 0; i < 10; i++) {
for ( int j = 0; j < 10; j++) {
cout << table[i][j];
}
}
}
This is my output I am getting.
55302337713078127332504421405961229072248303443307961481223132483391855019110600
92808812679236602328231529150663269913935376911094217591887215022974011255316512
71103276228950168692675422850260269511370054042617128509148242205517590190271332
93168530667935211606208729747118402681321223203422069312038223266476231187148148
05966618422064721159313592422312213211891498452701498229001417726265175102184575
4298481247015001631326472115171254718059341323252489617888241851323216308-858993
460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993
460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993
460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993
460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993
460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993
460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993
460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993
460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993
460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993
460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993
460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993
460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993
460-858993460-858993460-858993460The largest value located at [0] [0] is: -85899
3460
Press any key to continue . . .
Should fillTable fill table? Currently it does not - it only prints to cout. Therefore, table appears to remain uninitialized.
So, in fillTable, instead of:
cout << rand() % table[i][c];
You probably want something like:
table[i][c] = rand();
In fillTable you should use something like:
table[i][c] = rand() % MAX_VALUE; // MAX_VALUE is the largest value +1 you want to generate
cout << table[i][c] << " ";
(Note the whitespace to separate numbers, you might also want to insert a cout << endl; after each row. But I'm not sure if fillTable should also print out the values?)
Also the displayTable function only prints the first ten lines/columns (but this might be intentional?)
You are just making the random number output and not inserting in it.
do it like this
table [i][c] = rand () % table [i][c] ;
PLus you are getting a garbage value when you find the largest value because there is no actual value stored in the array.

Positive rows in a matrix

I have to do an exercise for University that asks me to check ( for k times ) if a matrix has positive rows ( i mean a row with all positive elements ) , i think there's something wrong with the indices of for loops but i cannot find the mistakes.
i tried to debug with a cout statement apply to the counter an it gives me "101" , so it seems like compiler assign "1" to the positive rows and "0" to the negative
This is the code i wrote:
#include <iostream>
using namespace std;
const int N = 3;
bool positive(int a[N][N], int row[N], int x) {
bool condition = false;
for(int i = 0; i < N; i++) {
row[i] = a[x][i];
}
int j = 0;
while(j < N) {
if(row[j] >= 0) {
condition = true;
} else {
condition = false;
}
j++;
}
return condition;
}
bool function (int a[N][N], int z, int j, int k) {
int b[N];
int c[N];
int count = 0;
if(positive(a, b, z) && positive(a, c, j)) {
count++;
}
if(count == k) {
return true;
} else {
return false;
}
}
int main() {
int a[N][N] = {
{
2, 8, 6
}, {
-1, - 3, - 5
}, {
6, 10, 9
}
};
int k = 2;
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
if(function (a, i, j, k)) {
cout << "OK";
} else {
cout << "NO";
}
}
}
return 0;
}
You should probably take another look at this problem and restart with a different solution. The objective is pretty easy but your code is surprisingly complex and some of it doesn't really make sense.
For example, if you had a matrix like this:
1 2 4 --> matrix A
-1 8 -6
3 9 2
You have N=3 rows and columns. The only thing you have to to based on what you said is take the matrix, cycle through the N rows, and for each row, check it's N columns to see if anything is < 0.
Doing this K times, as you put it, makes no sense. The matrix will be the same every time you compare it since you're not changing it, why would you do it more than once? I think you should reread the assignment brief there.
As for the logic of finding which rows are positive or negative, just do something simple like this.
//Create array so we have one marker for each row to hold results.
bool rowPositiveFlags[N] = { true, true, true };
//Cycle through each row.
for (int row = 0; row < N; ++row)
//Cycle through every column in the current row.
for (int col = 0; col < N; ++col)
//If the column is negative, set the result for this row to false and break
//the column for loop as we don't need to check any more columns for this row.
if (A[row][col] < 0) {
rowPositiveFlags[row] = false;
break;
}
You should always name things so that you can read your code like a book. Your i's, j's, and k's just make something simple confusing. As for the problem, just plan out your solution.
Solve the problem by hand on paper, write the steps in comments in your code, and then write code below the comments so what you do definitely makes sense and isn't overkill.
And this is a great site, but next time, post a smaller piece of code that shows your problem. People shouldn't ever give you a full solution here for homework so don't look for one. Just find the spot where your indices are broken and paste that set of 5 lines or whatever else is wrong. People appreciate that and you'll get faster, better answers for showing the effort :)