Disclaimer: I know that parallel arrays are awful and should be avoided and that selection sort is not the most efficient sort, but in this case that's the way the boss man wants it done. I have looked at a lot of different websites and none that really seem to nail down an answer. Also, it is probably good to point out that I am new to C++ and only know fairly basic coding and debugging.
I have two simple parallel arrays and am trying to design a simple selection sort that sorts one of the arrays, and then swaps the elements in the second array accordingly. I have the selection sort part working, but it does not seem to swap the elements in my second array correctly.
Here is what my output looks like:
1 (jibberish)
2 (jibberish)
3 (jibberish)
4 (jibberish)
5 (jibberish)
Where I have (jibberish) the console does not form any identifiable letter, just odd shapes (if it's helpful, the last element that is output is a heart).
Here's what it is supposed to look like:
1 a
2 b
3 c
4 d
5 e
Now I realize that I could easily run a selection sort on the second array in this scenario, but my point is to get the second array to swap elements respective to what the selection sort does to the first array.
Is there any way to keep these arrays lined up correctly? I've been trying to solve this issue for most of the day and I'm sure it's a fairly simple thing to figure out, but my brain is shot.
Below is my code, thanks in advance for looking at it.
#include "stdafx.h"
#include <iostream>
using namespace std;
//Function Prototypes
void sort(int num[], char alph[], int size);
//Selection sort function
void sort(int num[], char alph[], int size)
{
int startScan;
int minIndex;
int minValue;
for (startScan = 0; startScan < (size - 1); startScan++) //Moves through the elements
{
minIndex = startScan;
minValue = num[startScan];
int index = 0;
for (index = startScan + 1; index < size; index++) //Compares the elements
{
if (num[index] < minValue)
{
minValue = num[index];
minIndex = index;
}
}
num[minIndex] = num[startScan];
num[startScan] = minValue;
alph[minIndex] = alph[startScan];
alph[startScan] = alph[index];
}
}
//Main
int _tmain(int argc, _TCHAR* argv[])
{
int num[] = {5, 3, 1, 4, 2};
char alph[] = { 'e', 'c', 'a', 'd', 'b' };
int const SIZE = 5;
//Prints out unsorted array
cout << "This is the unsorted arrays." << endl;
cout << endl;
for (int count = 0; count < SIZE; count++)
{
cout << num[count] << " \t ";
cout << alph[count] << endl;
}
cout << endl;
cout << endl;
//Calls the sort function
sort(num, alph, SIZE);
//Prints out the sorted array
cout << "This is the sorted array." << endl;
cout << endl;
for (int count = 0; count < SIZE; count++)
{
cout << num[count] << " \t";
cout << alph[count] << endl;
}
//Pause
char temp[50];
cin >> temp;
return 0;
}
EDIT: I edited the
alph[minIndex] = num[startScan]
issue so it reads correctly now as:
alph[minIndex] = alph[startScan]
I am now getting this as an output:
1 (jibberish)
2 (jibberish)
3 (jibberish)
4 (jibberish)
5 e
EDIT 2: I edited the line of code under my previous edit and the arrays are now lining up properly and I am no longer getting a bunch of jibberish for outputs. Below is the edited sort function of my code:
//NOTICE temp VARIABLE CHANGES!
void sort(int num[], char alph[], int size)
{
int startScan;
int minIndex;
int minValue;
int temp;
for (startScan = 0; startScan < (size - 1); startScan++) //Moves through the elements
{
minIndex = startScan;
minValue = num[startScan];
temp = alph[startScan];
int index = 0;
for (index = startScan + 1; index < size; index++) //Compares the elements
{
if (num[index] < minValue)
{
minValue = num[index];
minIndex = index;
temp = alph[index];
}
}
num[minIndex] = num[startScan];
num[startScan] = minValue;
alph[minIndex] = alph[startScan];
alph[startScan] = temp;
}
}
The best solution might be to change your
num[minIndex] = num[startScan];
num[startScan] = minValue;
char temp=alph[minIndex];
alph[minIndex] = alph[startScan];
alph[startScan] = temp;
to this which does the job and really can't be made any simpler.
std::swap(num[minIndex], num[startScan]);
std::swap(alph[minIndex],alph[startScan]);
See this line:
alph[minIndex] = num[startScan];
Second faulty line:
alph[startScan] = alph[index];
It should be:
alph[startScan] = alph[minIndex];
By the time the code exits of the inner loop, size has a value of one beyond the array size.
My advice: Use an IDE and the debugger to follow up code execution and examine variables. Also, my first hint should have gotten you looking at incorrect indexes. C++ does not care to check array bounds by default. You usually get garbage when getting out of bounds or following a incorrect pointer. You can remedy the first problem by selecting a compiler option to check for array bounds. That will slow down your application during development time but can be removed once everything works correctly.
Related
c++
When printing to console, if function execution is sequential it would seem logical the ordered array would be printed after calling insertionSort, however order list does not print until next loop. Any help would be appreciated.
#include <stdio.h>
#include <iostream>
#include <array>
using namespace std;
void insertionSort(int* array, int size) {
for (int i = 1; i < size; i++) {
int key = i - 1;
while (i > 0 && array[key] > array[i] ) {
int tmp = array[i];
array[i] = array[key];
array[key] = tmp;
i -= 1;
key -= 1;
}
}
}
const int ARRAY_MAXSIZE = 5;
int main(void) {
int *array = (int*)calloc(ARRAY_MAXSIZE, sizeof(int));
int input;
cout << "Enter 5 digits\n";
for (int size=0; size < ARRAY_MAXSIZE; size++) {
cout << size << " index ";
cin >> input;
array[size] = input;
insertionSort(array, size);
for (int j=0; j <= size; j++) {
cout << array[j];
}
cout << '\n';
}
}
Console Entry
This is a classic off-by-one error. Your insertionSort expects you to pass the number of elements to sort via the parameter size. But your main loop is always holding a value that is one less than the size immediately after adding an element.
I want to say that bugs like this are easily discovered by stepping through your program's execution with a debugger. If you don't know how to use a debugger, start learning now. It is one of the most important tools used by developers.
Anyway, the quick fix is to change your function call to:
insertionSort(array, size + 1);
However, as Paul McKenzie pointed out in comments, it's a bit crazy to do this every time you add a new element because your function sorts an entire unsorted array. Your array is always nearly sorted except for the last element. You only need to call that function once after your input loop is done:
// Read unsorted data
for (int size = 0; size < ARRAY_MAXSIZE; size++) {
cout << size << " index ";
cin >> input;
array[size] = input;
}
// Sort everything
insertionSort(array, ARRAY_MAXSIZE);
// Output
for (int j = 0; j < ARRAY_MAXSIZE; j++) {
cout << array[j];
}
cout << '\n';
But if you want every insertion to result in a sorted array, you can "slide" each new value into place after inserting it. It's similar to a single iteration of your insertion-sort:
// Sort the last element into the correct position
for (int i = size; i >= 1 && array[i] > array[i - 1]; i--)
{
std::swap(array[i], array[i - 1]);
}
Even better, you don't need to swap all those values. You simply read the value, then shuffle the array contents over to make room, then stick it in the right spot:
// Read next value
cin >> input;
// Shuffle elements to make room for new value
int newPos = size;
while (newPos > 0 && array[newPos - 1] > input) {
array[newPos] - array[newPos - 1];
newPos--;
}
// Add the new value
array[newPos] = input;
as the title says I'm attempting to compare elements in an array. My intent is to have the user enter 3 integers into the program, thereafter it should increment through this array comparing the the 1st number to the 2nd, and so forth and swapping the element's from order of lowest to highest.
My issue currently is that it will swap the first and second elements but the third causes an integer overflow due to me comparing and assigning an integer in an index higher than the initialized array can hold.
I'm currently drawing a blank as to how I could still compare these numbers in this manner without causing it to overflow.
A hint or perhaps a whole different perspective would be appreciated.
#include "E:/My Documents/Visual Studio 2017/std_lib_facilities.h"
int main()
{
cout << "Enter three integers: \n";
int numbersArray[3];
int temp = 0; //This lets us hold our integers temporarily so we can swap them around in the array
//This enters integers as elements in the array
for (int i = 0; i < 3; i++)
{
cin >> numbersArray[i];
}
//This should swap the elements from smallest to greatest
for (int i = 0; i = 3; i++)
{
if (numbersArray[i] > numbersArray[i+1])
temp = numbersArray[i];
numbersArray[i] = numbersArray[i+1];
numbersArray[i+1] = temp;
//swap(numbersArray[i], numbersArray[++i]);
}
//This prints the index's containing the elements in the array
for (int i = 0; i < 3; i++)
{
cout << numbersArray[i] << ' ';
}
cout << endl;
keep_window_open();
return 0;
}
You will need to modify this to suit your needs, but this should get you on the right track. One important thing to investigate is how you decided to sort the elements. Your sorting needs to be looped, otherwise, you won't necessarily sort the entire array (depending on your inputs).
#include <iostream>
using namespace std;
int main()
{
cout << "Enter three integers: \n";
int numbersArray[3];
int temp = 0; //This lets us hold our integers temporarily so we can swap them around in the array
//This enters integers as elements in the array
for (int i = 0; i < 3; i++)
{
cin >> numbersArray[i];
}
for(int loop = 0; loop <3; loop++){
//This should swap the elements from smallest to greatest
for (int i = 0; i < 2; i++)
{
if (numbersArray[i] > numbersArray[i+1]){
temp = numbersArray[i];
numbersArray[i] = numbersArray[i+1];
numbersArray[i+1] = temp;
}
//swap(numbersArray[i], numbersArray[++i]);
}
}
//This prints the index's containing the elements in the array
for (int i = 0; i < 3; i++)
{
cout << numbersArray[i] << ' ';
}
cout << endl;
return 0;
}
This question already has answers here:
srand() — why call it only once?
(7 answers)
Closed 4 years ago.
I am having trouble with shuffling a deck of cards in C++.
I have a deck of cards class. Within the class I have a vector of objects, which are the cards within the deck, and I am trying to shuffle the elements within the vector to shuffle the cards. However, the function I wrote to do it appears to be just shifting everything over every iteration instead of swapping it with another random element within the vector. I'm sure its something really simple and stupid that I am missing, but I just haven't been able to figure it out yet. Any help would be greatly appreciated.
Thanks.
void shuffle(int seed = 0)
{
for (int i = 0; i < 100; i += 1)
{
for (unsigned int i = 0; i < deck.size(); i++)
{
card *swap = deck[i];
srand(time(NULL) + seed);
int temp = rand() % 52;
deck[i] = deck[temp];
deck[temp] = swap;
}
cout << "shuffled deck: ";
for (unsigned int i = 0; i < deck.size(); i++)
cout << deck[i]->compare() << " ";
cout << endl;
}
}
This is being called within a probability function I made, inside a loop. The seed for the shuffle function is the iteration of the loop.
This is a sample of part of the output in one iteration
Initialize your RNG just once, for example in your main() function
srand(time(NULL));
Then one of simplest methods of shuffling is just swap each item from the end to the beginning with a random element from those preceding it. Note the item to swap can be the same to be swapped – this way the item can also stay where it already is.
void shuffle()
{
for (int i = 0; i < 100; i ++)
{
for (unsigned int n = deck.size(); n > 1; --n)
{
unsigned swapPosition = rand() % n;
card *swap = deck[n-1];
deck[n-1] = deck[swapPosition];
deck[swapPosition] = swap;
}
cout << "shuffled deck: ";
for (unsigned int n = 0; n < deck.size(); n++)
cout << deck[n]->compare() << " ";
cout << endl;
}
}
I am trying to understand this recursion using the debugger and trying to understand it step by step the main.The debugger shows the smallAns returns the size of the array I can't understand how this smallAns is returning the size of the array input[].can anyone explain this
#include<iostream>
using namespace std;
int subsequences(char input[], int startIndex,char output[][50]){
if(input[startIndex] == '\0'){
output[0][0] = '\0';
return 1;
}
int smallAns = subsequences(input, startIndex+1, output);
for(int i = smallAns; i < 2*smallAns; i++){
int row = i - smallAns;
output[i][0] = input[startIndex];
int j = 0;
for(; output[row][j] != '\0'; j++){
output[i][j + 1] = output[row][j];
}
output[i][j + 1] = '\0';
}
return 2*smallAns;
}
int main(){
char input[] = "abc";
char output[100][50];
int ans = subsequences(input, 0, output);
for(int i = 0; i < ans; i++){
for(int j = 0; output[i][j] != '\0'; j++){
cout << output[i][j];
}
cout << endl;
}
}
Here's what the algorithm is doing:
Start at the end, with the empty subsequence (or "\0"). You have 1 subsequence.
Look at the last character not yet considered. For all the subsequences you have found, you can either add this last character, or don't. Therefore you have doubled the number of subsequences.
Repeat.
Therefore, 2 * smallAns means "Take the number of subsequences found in the lower recursive call, and double it." And this makes sense after you know how it was implemented. Thus the importance of comments and documentation in code. :)
I've got an array of structs, and I'm trying to sort it by price using selection sort. I'm consistently getting a ECX_BAD_ACCESS signal.
This is what I've got:
#include <iostream>
#include <string>
using namespace std;
So thing is just a struct with a name and a price. The price is what I want to sort the structs by
struct Thing
{
std::string name;
double price;
};
Right now, the main method just checks to make sure that the sortThing function is working.
Thing *sortThing(Thing input[], int size);
int main ()
{
Thing *stuff = new Thing[3];
stuff[0].name = "middle";
stuff[0].price = 2.00;
stuff[1].name = "last";
stuff[1].price = 3.00;
stuff[2].name = "first";
stuff[2].price = 1.00;
stuff = sortThing(stuff, 3);
cout << stuff[0].name + " " + stuff[1].name + " " + stuff[2].name;
return 0;
}
This is where the problem is. It complains about the line where I assign input[maxIndex].name to output[i].name, saying: "Program Received 'EXC_BAD_ACCESS'"
Thing *sortThing(Thing input[], int size)
{
Thing *output = new Thing[size];
Thing nullThing;
nullThing.name = "&nullThing";
int min = 0;
int minIndex;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (input[j].name.compare("&nullThing") != 0 && input[j].price <= min) minIndex = j;
}
output[i].name = input[minIndex].name;
output[i].price = input[minIndex].price;
input[minIndex] = nullThing;
minIndex = 0;
min = 0;
}
return output;
}
Any help is appreciated
I think your loop for determining minIndex is incorrect... Since all prices are >= 0, you will never set minIndex, and since you never initialized it, it's value can be anything. Most likely in your case the value is outside the range of the array and effectively having an array out of bounds error.
Might want to look into some sorting algorithms.
Debugging 101: here's the first thing to do. Change:
int minIndex;
to:
int minIndex = -42;
(temporarily) then output the value of minIndex immediately after the inner loop.
This will show you that the value is not being changed.
The reason it's not being changed is the initial setting of min. Unless you're giving your product away for free, or paying people to take it away, prices will always be greater than zero and the second part of the if statement will always be false.
Quick fix, set min initially to INT_MAX (and also where you reset it at the end of the outer loop).