Sort Specific Column of 2D int array (C++) - c++

I've got a bit of a conundrum. I'm currently trying to create a user-defined function to sort a column (in ascending order) of a 2D int array I created and populated in the main function. I feel like I'm close, but for some reason the final output is incorrect, it provides a number for the final value that isn't even in the array. Judging from the value provided and the extra few seconds it takes to compile, I'm assuming I've messed up my bounds/ gone beyond them at some point within the code, but I've been fighting this thing for hours to no avail and I feel fresh (and likely more experienced) eyes would be-be of some use. I'm still in my "Intro to" class for programming, so ripping me a new one for obvious errors is encouraged as my final is this Thursday and any and all pointers/tips are appreciated. Cheers!
#include <iostream>
using namespace std;
void sort2D(int arr[3][5], int rows, int columns) //the problem child
{
int userCol;
cout<<"Please enter the number of the column you'd like to sort: "<<endl;
cin>>userCol; //ask for appropriate column
for (int row_index=0; row_index<rows; row_index++) //start with first row and continue for all values in code
{
int temp;
if ((arr[row_index][userCol-1]<arr[row_index+1][userCol-1]))//if first value of selected column is less than next value
{
temp = arr[row_index+1][userCol-1];//create copy of second value
arr[row_index+1][userCol-1]=arr[row_index][userCol-1]; //replace second value with first value
arr[row_index][userCol-1]=temp;//set first equal to second's original value
}
}
for(int i=0; i<rows; i++)//print that shiz
{
for(int j=0; j<columns; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
const int rows = 3;
const int columns = 5;
int arr[rows][columns];
for (int row_index=0; row_index<rows; row_index++)
{
for (int column_index=0; column_index<columns; column_index++)
{
arr[row_index][column_index] = (50+rand()%51);
cout << arr[row_index][column_index]<<" ";
}
cout << endl;
}
findMaxandIndex(arr, rows, columns);//i left my code for this out because it's working and isn't utilized in the problem code
cout << endl;
sort2D(arr, rows, columns);
return 0;

Your sort function is very close to bubble sort, one of the simplest sorting algorithms to understand and implement. With a little modification, your code will work :
void sort2D(int arr[3][5], int rows, int columns) //the problem child
{
//input userCol ...
//sorting start here ...
bool found = true; //we can quit the loop if the array is already sorted.
for (int bubble = 0; bubble < rows-1 && found ; bubble++)
{
found = false;
for (int row_index=0; row_index < rows - bubble - 1; row_index++)
{
int temp;
if ((arr[row_index][userCol-1] < arr[row_index+1][userCol-1]))//if first value of selected column is less than next value
{
//swap two elements.
temp = arr[row_index+1][userCol-1];//create copy of second value
arr[row_index+1][userCol-1]=arr[row_index][userCol-1]; //replace second value with first value
arr[row_index][userCol-1]=temp;//set first equal to second's original value
found = true; //we found something, continue to sort.
}
}
}
//print out the result ...
}
As you start in C++, an advice is to use C++ facilities if possible : std::vector for your array and std::qsort for sorting elements.

Issue 1: The int arr[3][5]; you declared in sort2D() is NOT the same as the int arr[rows][columns]; you declared in main().
lesson : check (or web search) on "pass by reference" & "pass by value" . For simplicity, I recommend pass by value.
Issue 2: The sort only compare 2 values and only run for 1 pass.. so {2,1,4,3} may get sorted to {1,2,3,4} but {1,4,3,2} will only get to {1,3,2,4} with 1 pass. #ZDF comment is helpful for this part.
Issue 3: at this line.. temp = arr[row_index+1][userCol-1]; when row_index is 2, this will refer to a location that is not in the arr[][] array. arr are only defined for row = 0,1,2 .. not 3 (when row_index is 2, row_index+1 is 3). This may answer :
it provides a number for the final value that isn't even in the array.
Solution.. hurm. I suggest you have a look and try.. and share where you stuck at. you may also test the sort2D in the main function before doing it as separate function. IMHO, you can start by 1st looking for the sorting algorithm that works (with sample data).. Then work on making it work in this project. ( :
p/s: I don't see my post as an answer.. more like a correction guide.

Related

How to write a C++ array printing loop that starts at a different point on each iteration?

I have a struct that has two member variables, each is an int.
struct trash
{
int sector;
int weight;
};
I have an array where each element contains one of these structs. All of the data is randomly generated within a set range. In this case, sectors are generated randomly from 1-7. Also, the array is size 15 in this instance. So each sector has a random number of weight variables associated with it. What I am trying to accomplish is printing out what piles belong to each sector. So the format should look like this
Sector 1
Pile 1: xxx
Pile 2: xxx
...
Sector 2
Pile 1: xxx
....
Sector 7
and so on if that makes sense
My attempt at this so far was to sort the array of structs by sector from least to greatest first and then print out the weight variable of each by iterating over the array using for loops. In a nutshell, I just want to print out the array in order after it is sorted by sector but break it up by sector. I can't for the life of me seem to figure out how to accomplish this in a compact, concise way. Below is the loop I have written now that doesnt quite work because the inner loop starts at the same point each time.
for(int i=0;i<NUM_SEC;i++)
{
cout<<"Sector "<<(i+1)<<endl;
for(int j=0;j<num_piles[i];j++)
{
cout<<"Pile "<<(j+1)<<": "<<data[j].weight<<endl;
cout<<endl;
}
}
Any tips would be appreciated, I've already spent hours on just this small aspect of the program and its very frustrating.
Looks like you want to access not data[j], but data[j + previous_piles]. You could then do something like:
int previous_piles = 0;
for(int i=0;i<NUM_SEC;i++)
{
cout<<"Sector "<<(i+1)<<endl;
for(int j=0;j<num_piles[i];j++)
{
cout<<"Pile "<<(j+1)<<": "<<data[j+previous_piles].weight<<endl;
cout<<endl;
}
previous_piles += num_piles[i];
}
You are not keeping record of your progress!!
Look at the following code:
int last_pile = 0; // will keep track of the last printed index
for(int i=0;i<NUM_SEC;i++)
{
cout<<"Sector "<<(i+1)<<endl;
for( int j = 0; j < num_piles[i]; j++)
{
cout << "Pile " << (j+1) << ": " << data[j+last_pile].weight << endl; // sum last_pile to j
}
// updated last printed index
last_pile += num_piles[i];
cout << endl; // empty line 'cause finihes with this sector
}
I created a new variable last_pile which will store the last visited index. Then, inside the loop, I add the value of this variable to the sub-index j so you always get the correct element from the array.
Please pay attention to the comment, I added useful information there.

Selection sort not sorting first value

I wrote this c++ function to sort an array, it works, but it doesn't seem to work with the fist value: it isalways the bigger instead of the smaller!
void s_iSort (double a[])
{
cout << "INCREASING SORTER:\n\n";
unsigned int mx,maxx;
double temp;
cout << "Insert maximum element to sort: "; cin>>mx;
for (int c=0; c<mx; c++)
{
maxx=0;
for (int i=c; i<mx; i++)
if (a[i]<a[maxx])
maxx=i;
temp=a[c];
a[c]=a[maxx];
a[maxx]=temp;
}
cout << "\nDONE!\n\n";
}
What's worng with this?
You should either use a debugger, or try to explain your algorithm to a rubber duck. However, I am in a rubber duck mood and will point you to a mistake:
for (int c=0; c<mx; c++) {
maxx=0;
for (int i=c; i<mx; i++) if (a[i]<a[maxx]) maxx=i;
temp=a[c];
a[c]=a[maxx];
a[maxx]=temp;
}
In each iteration of this loop you want to go trough a range of elements, find the minimum value in that range and put it as the first element of that range. It works for the first iteration, but already on the second it goes wrong. You initialize maxx (which is supposed to be the first element in that range) to 0, ie the first element of the array. However you should only consider elements that have not yet been sorted, ie change it to
maxx = c;
Also note, that (apart from exercises) you should not write your own sorting algorithm but use std::sort.

Solving sudoku puzzle with c++

I want to make a program for solving a 3*3 sudoku puzzle. I have made a program but it is only working for 50% problems and for the rest it gives 60% right solution. I do not know how to solve it in a finite number of steps for every possible problem. The technique I have used is that I am searching every individual element of array and check which no does not exist in the same row and column and then I put it in that unit and move to the next. But this is not the solution for every problem. The next thing that come to mind was that we should have to write each and every possible number for a unit and then proceed. But how will we decide that which number we should finally put in the unit. I just want that how to write a solution that will work for every problem. I hope you got the point.
The code I have written is
#include<iostream>
using namespace std;
int rowsearch(int l[9][9],int row,int num) // function to search a particular number from a row of array
{
int counter=0;
for (int c=0 ; c<9 ; c++)
{
if (l[row][c]==num)
counter=counter+1;
}
if (counter>0)
return 1;
else
return 0;
}
int colsearch(int l[9][9],int col,int num) // function to search a number from a column of an array
{
int counter=0;
for (int c=0 ; c<9 ; c++)
{
if (l[c][col]==num)
counter=counter+1;
}
if (counter>0)
return 1;
else
return 0;
}
int rowcolnotexist(int x[9][9],int row , int col) // to find a nuber which does not exists int a row and column
{
for (int c=1 ; c<=9 ; c++)
{
if ( rowsearch(x,row,c)!=1 && colsearch(x,col,c)!=1)
return c;
}
return 0;
}
int main()
{
int l[9][9]={};
// input of the list
for (int i=0 ; i<9 ; i++)
for (int j=0 ; j<9 ; j++)
{
cout<<"Enter "<<i+1<<"*"<<j+1<<"entry of the list(For not entering a number enter 0).";
cin>>l[i][j];
}
// operations
for (int i=0 ; i<9 ; i++)
{
for (int j=0 ; j<9 ; j++)
if (l[i][j]==0)
l[i][j]=rowcolnotexist(l,i,j);
}
// printing list
for (int i=0 ; i<9 ; i++)
{
for (int j=0 ; j<9 ; j++)
{
cout<<l[i][j];
if ((j+1)%3==0)
cout<<" ";
else
cout<<" ";
}
if ((i+1)%3==0)
cout<<"\n\n\n";
else
cout<<"\n\n";
}
return 0;
}
I'd recommend the same algorithm I use when solving them myself ;-)
Choose an arbitrary square and list all the valid values for it, based on what is present in all the other rows (there's probably a way to make a more efficient decision about which square to start with).
Then move on to a related empty square (there's probably a way to make a more efficient decision about which square to check next) and store all its possible values.
Rinse and repeat until you find a square that has only one valid value.
Then unzip.
This should sounds like a recursive problem, by now. (note: almost anything that can be done recursively can be done conventionally, but the idea is the same).
So, store up a list of partially solved squares, and when you get to a square that's been solved completely, go back through your list in reverse order re-evaluating your partial solutions with the new data (namely, the one you WERE able to solve).
Rinse and repeat for full body and volume.

How do I drop the lowest value?

I'm pretty new to C++, and I need help figuring out the code for dropping the lowest value of a randomly generated set of numbers. Here is my code so far:
//Create array and populate the array with scores between 55 and 10
// Drop lowest Score
#include <iostream>
#include <cstdlib>//for generating a random number
#include <ctime>
#include <iomanip>
#include <algorithm>
#include <vector>
using namespace std;
//function prototype
int *random (int);
int main()
{ int *numbers; //point to numbers
//get an array of 20 values
numbers = random(20);
//display numbers
for (int count = 0; count < 20; count++)
cout << numbers[count] << endl;
cout << endl;
system("pause");
return 0;
}
//random function, generates random numbers between 55 and 100 ??
int *random(int num)
{ int *arr; //array to hold numbers
//return null if zero or negative
if (num <= 0)
return NULL;
//allocate array
arr = new int[num];
//seed random number generator
srand(time (0));
//populate array
for (int count = 0; count < num; count++)
arr[count] = (rand()%(45) +55);
//return pointer
//
return arr;
}
For this piece of code, how would I sort or find the lowest score to drop it after the function returns the random numbers?
int main()
{ int *numbers; //point to numbers
//get an array of 20 values
numbers = random(20);
//display numbers
for (int count = 0; count < 20; count++)
cout << numbers[count] << endl;
cout << endl;
system("pause");
return 0;
}
Your suggestions are appreciated!
In general, to find the lowest value in an array, you can follow this psuedo-algorithm:
min = array[0] // first element in array
for (all_values_in_array)
{
if (current_element < min)
min = current_element
}
However, you can't "drop" a value out of a static array. You could look into using a dynamic container (eg. vector), or swapping the lowest value with the last value, and pretending the size of the array is 1 less. Another low level option would be to create your own dynamic array on the heap, however, this is probably more complicated than you are looking for.
Using an vector would be much easier. To drop the lowest element, you just have to sort in reverse order, then remove the last element. Personally, I would recommend using a vector.
The obvious approach to find the smallest element is to use std::min_element(). You probably want to use std::vector<T> to hold your elements but this isn't absolutely necessary. You can remove the smallest value from an array like this:
if (count) {
int* it = std::min_element(array, array + count);
std::copy(it + 1, array + count--, it);
}
Assuming you, reasonable used std::vector<int> instead, the code would look something like this:
if (!array.empty()) {
array.erase(std::min_element(array.begin(), array.end()));
}
First find the index of the lowest number:
int lowest_index=0, i;
for (i=0; i<20; i++)
if (arr[i]<arr[lowest_index])
lowest_index=i;
Now that we know the index, move the numbers coming after that index to overwrite the index we found. The number of numbers to move will be 19 minus the found index. Ie, if index 2 (the third number, since the first is at index 0) is lowest, then 17 numbers comes after that index, so that's how many we need to move.
memcpy(&arr[lowest_index],&arr[lowest_index+1],sizeof(int)*(19-lowest_index))
Good luck!
Sort the array ascending.
The lowest value will be at the beginning of the array.
Or sort the array descending and remove the last element.
Further to what others have said, you may also choose to use something like, perhaps a std::list. It's got sorting built-in, also offering the ability to define your own compare function for two elements. (Though for ints, this is not necessary)
First, I typically typedef the vector or list with the type of the elements it will contain. Next, for lists I typedef an iterator - though both of these are merely a convenience, neither is necessary.
Once you've got a list that will holds ints, just add them to it. Habit and no need to do otherwise means I'll use .push_back to add each new element. Once done, I'll sort the list, grab the element with the lowest value (also the lowest 'index' - the first item), then finally, I'll remove that item.
Some code to muse over:
#include <cstdio>
#include <cstdlib>
#include <list>
using namespace std;
typedef list<int> listInt;
typedef listInt::iterator listIntIter;
bool sortAsc(int first, int second)
{
return first < second;
}
bool sortDesc(int first, int second)
{
return first > second;
}
int main (void)
{
listInt mList;
listIntIter mIter;
int i, curVal, lowestScore;
for (i=1; i<=20; i++)
{
curVal = rand()%45 + 55;
mList.push_back(curVal);
printf("%2d. %d\n", i, curVal);
}
printf("\n");
mList.sort();
// mList.sort(sortAsc); // in this example, this has the same effect as the above line.
// mList.sort(sortDesc);
i = 0;
for (mIter=mList.begin(); mIter!=mList.end(); mIter++)
printf("%2d. %d\n", ++i, *mIter);
printf("\n");
lowestScore = mList.front();
mList.pop_front();
printf("Lowest score: %d\n", lowestScore);
return 0;
}
Oh, and the choice to use printf rather than cout was deliberate too. For a couple of reasons.
Personal preference - I find it easier to type printf("%d\n", someVar);
than cout << someVar << endl;
Size - built with gcc under windows, the release-mode exe of this example is 21kb.
Using cout, it leaps to 459kb - for the same functionality! A 20x size increase for no gain? No thanks!!
Here's an std::list reference: http://www.cplusplus.com/reference/stl/list/
In my opinion the most optimal solution to your problem would be to use a linked list to store the numbers, this way you can use an algorithm with complexity O(N) = N to find the smallest element in the list, it is a similar finding method given by user1599559 or Mikael Lindqvist, you only need stored together with the minimum value the pointer to the Item(ItemX) in the linked list that store it, then to eliminate Item X just tell Item X - 1 points to Item X + 1 and free memory allocated by Item X

recursive function error

I have a program that is supposed to read in values from user into a vector. My function is then supposed to keep a running sum and start from element 1 and compare element 2 to the sum(this point it is just element 1). Move to the next element, add element 2 to the sum and see if element 3 is greater than the sum of elements 1 and 2. I am supposed to print only the elements that are greater than the sum. I'm having trouble getting it to print out any values. Could someone please let me know what I might be doing wrong? Thanks
int main()
{
vector <int> theData;
int i;
cout<< "Enter in the list of integers ending with a -1" << endl;
do
{
cin >> i;
if (i==-1)
{
break;
}
theData.push_back(i);
}while(i!=-1);
int index = 1;
int runningSum = unsortedData[i];
largeValue(unsortedData, index, runningSum);
system("PAUSE");
return 0;
}
void largeValue(vector<int> myVector, int index, int runningSum)
{
int size = myVector.size();
if (index == size)
{
return;
}
if (myVector[index] > runningSum)
{
cout << myVector[index] << " ";
runningSum += myVector[index];
index = index +1;
largeValue(myVector, index, runningSum);
}
else if (myVector[index] < runningSum)
{
runningSum += myVector[index];
index = index + 1;
largeValue(myVector, index, runningSum);
}
}
There are several errors in your code:
int runningSum = unsortedData[i];
You probably meant index, not i. Both are wrong, though: the first index in the array is 0, not 1 (which is the value of index).
Also, your recursive function contains at least one error: you don’t consider that the current element equals the sum.
Another thing: you pass the vector to your function by value – not a good idea: for each call of the function, the whole vector is copied, which may take considerable time for medium-sized vectors. In “real” code, large data types should always be passed by (const) reference. Just change the function signature slightly:
void largeValue(vector<int> const& myVector, int index, int runningSum)
This way, you pass an unmodifiable reference of your vector to the function instead of copying it. Notice that this makes it impossible to modify the data of the vector inside the function.
Firstly, your function fails to meaningfully process the case when myVector[index] == runningSum.
Secondly, the initial value of runningSum is taken from unsortedData[i] which doesn't make any sense, since i is -1 at that time. You probably meant unsortedData[0].
Early in main you use theData and later you use unsortedData. I'm not sure why the compiler hasn't complained about unsortedData not being defined.