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.
Related
I have the following code written in c++ and the algorithm works when in this scenario. I am knew to c++ and don't understand what I did wrong in my 2nd test.
#include <iostream>
using namespace std;
void bubbleSort(int numbers[], int size) {
for (int i = 0; i<size;i++) {
for (int j=0; j<size;j++) {
if (numbers[j] > numbers[j+1]) {
swap(numbers[j], numbers[j+1]);
}
}
}
}
int main() {
int numbers[] = {7,5,6,4};
bubbleSort(numbers,4);
for (int print = 0; print < 4; print++) {
cout << numbers[print] << endl;
}
return 0;
}
But, fails when I try to put in numbers that are already sorted:
#include <iostream>
using namespace std;
void bubbleSort(int numbers[], int size) {
for (int i = 0; i<size;i++) {
for (int j=0; j<size;j++) {
if (numbers[j] > numbers[j+1]) {
swap(numbers[j], numbers[j+1]);
}
}
}
}
int main() {
int numbers[] = {1,2,3};
bubbleSort(numbers,3);
for (int print = 0; print < 3; print++) {
cout << numbers[print] << endl;
}
return 0;
}
for (int j=0; j<size;j++) {
If size is 3, if the array has three values, for example, this loop iterates with values of j of 0, 1, and 2.
if (numbers[j] > numbers[j+1]) {
When j is 2 this compares numbers[2] with numbers[3].
There is no numbers[3]. This is undefined behavior. The loop is off by 1 value.
Additionally, the overall bubble sort implementation is flawed. In the shown code the inner loop iterates over the entire array (ignoring the off-by-1 bug), every time. In a classical bubble sort the first pass (the first iteration of the outer loop) results in the inner loop iterating over the entire array and "bubbling" the smallest/largest value to the end of the array. On the next pass the inner loop does not need to iterate over the entire array, but only up until the 2nd smallest/largest position of the array. And so on, each pass (the outer loop) results in the inner loop iterating over a smaller, and smaller subset of the array, "bubbling" the corresponding value to the appropriate stop.
In addition to fixing the off-by-1 bug you'll also need to adjust the overall logic of this bubble sort, if you wish to get a perfect grade for your homework assignment.
Implementing bubble sort in its entirety is problematic. In the example code, the inner loop repeatedly iterates over the full array while disregarding the shift by 1. The inner loop iterates over the whole array in a traditional bubble sort's first iteration of the outer loop, "bubbling" the smallest/largest value to the array's end. On the subsequent iteration, the inner loop only has to iterate up to the array's second-smallest/largest point rather than the full array. The inner loop then iterates through a smaller and smaller subset of the array, making bubbles of the associated the associated value to the proper stop with each successive run in the outside loop.
Let's say I have a vector of integers:
vector<int> v(n);
Which I fill up in a for loop with valid values. What I want to do is to find a index of a given value in this vector. For example if I have a vector of 1, 2, 3, 4 and a value of 2, i'd get a index = 1. The algorithm would assume that the vector is sorted in ascending order, it would check a middle number and then depending of it's value (if its bigger or smaller than the one we're asking for) it would check one of halves of the vector. I was asked to do this recursive and using pointer. So I wrote a void function like:
void findGiven(vector<int> &v){
int i = 0;
int *wsk = &v[i];
}
and I can easily access 0th element of the vector. However I seem to have some basic knowledge lacks, because I can't really put this in a for loop to print all the values. I wanted to do something like this:
for (int j = 0; j<v.size(); j++){
cout << *wsk[j];
}
Is there a way of doing such a thing? Also I know it's recurisve, I'm just trying to figure out how to use pointers properly and how to prepare the algorithm so that later I can build it recursively. Thanks in advance!
The correct way is:
for (int wsk : v) {
cout << wsk;
}
If you insist on pointers:
int* first = v.data();
for (size_t j = 0; j < v.size(); ++j) {
cout << first[j];
}
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.
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.
So, I tried to make an array using input first, then sorting it out from smallest to biggest, then display the array to monitor.
So I come up with this code :
#include <iostream>
using namespace std;
void pancakeSort(int sortArray[], int sortSize);
int main()
{
// Input The Array Element Value
int pancake[10];
for(int i=0; i<10; i++)
{
cout << "Person " << i+1 << " eat pancakes = ";
cin >> pancake[i];
}
// call pancake sorting function
pancakeSort(pancake, 10);
}
void pancakeSort(int sortArray[], int sortSize)
{
int length = 10;
int temp;
int stop = 10;
// this is where the array get sorting out from smallest to biggest number
for(int counter = length-1; counter>=0; counter--)
{
for(int j=0; j<stop; j++)
{
if(sortArray[j]>sortArray[j+1])
{
temp = sortArray[j+1];
sortArray[j+1] = sortArray[j];
sortArray[j]=temp;
}
}
stop--;
}
// after that, the array get display here
for(int x=0; x<sortSize; x++)
{
cout << sortArray[x] << " ";
}
}
but the output is weird :
enter image description here
the function is successfully sorting the array from smallest to biggest,
but there is 2 weird things :
1. The biggest value element (which is 96 from what I input and it's the 10th element after got sorted out), disappear from the display.
2. For some reason, there is value 10 , which I didn't input on the array.
So, what happened?
In the loop
for(int j=0; j<stop; j++)
{
if(sortArray[j]>sortArray[j+1])
{
temp = sortArray[j+1];
sortArray[j+1] = sortArray[j];
sortArray[j]=temp;
}
}
stop is the length of the array, and you are iterating through values of j = 0 to stop - 1. When j reaches stop - 1, the next element that is j+1 becomes stop (10 in this case). But since your array has a length of 10, sortArray[10] is not part of the array, but is referring to some other object in memory which is usually a garbage value. The garbage value is 10 in this case. When you swap sortArray[10] and sortArray[9], the garbage value becomes part of the array and the value at index 9 leaves the array. This keeps on happening till the outer loop ends.
The end result is that unless the garbage value < largest element in the array, the garbage value is pushed in the array and the greatest value of the array is put at sortArray[10] which is not part of the array. If the garbage value is greater than all the values of the array, it'll be found at sortArray[10] which is again not part of the array and your code will return the desired result.
Essentially, what you are doing is giving the function an array of 10 (or stop) elements, but the function is actually working with an array of 11 (or stop + 1) elements, with the last element being a garbage value. The simple fix is to change the conditional of the loop to j < stop - 1.
Note that if you had written this code in a managed (or a comparatively higher level) language like Java or C#, it would have raised an IndexOutOfBoundsException.
At index 9, j+1 is out of bounds. So to fix this, you only need to check till index 8
for(int counter = length-1; counter>=0; counter--)
{
for(int j=0; j<stop-1; j++)
{
if(sortArray[j]>sortArray[j+1])
{
temp = sortArray[j+1];
sortArray[j+1] = sortArray[j];
sortArray[j]=temp;
}
}
stop--;
}
Look carefully at the inner loop condition j<stop-1