C++ Selection Sort (vectors) - c++

int temp;
for (int j = 0; j < vecsize - 1; ++j) {
int min = sort.at(j);
for (int i = j+1; i < vecsize; ++i) {
if (min > sort.at(i)) {
min = sort.at(i);
temp = i;
}
}
swap(sort.at(j), sort.at(temp));
}
I am trying to sort (in ascending order) the vector of: 23 42 4 16 8 15
However, my attempt at using selection sort outputs: 4 8 15 23 16 42
What am I doing wrong?

When you define min, you seem to be assigning it the value of the array sort at jth index. Yet, you are using an extra variable tmp to swap the elements, and you seem to fail to initialize it before the inner for loop, similar to how you initialize min. And if all the other elements in the array are smaller than the element at sort[j], tmp will be uninitialized for that iteration of the outer loop, possibly causing it to have an incorrect value in it.
int temp;
for (int j = 0; j < vecsize - 1; ++j) {
int min = sort.at(j);
temp = j; # HERE'S WHAT'S NEW
for (int i = j+1; i < vecsize; ++i) {
if (min > sort.at(i)) {
min = sort.at(i);
temp = i;
}
}
swap(sort.at(j), sort.at(temp));
}
You may see this code at work here. It seems to produce the desired output.

Try this : corrected-code
#include <iostream>
#include <vector>
using namespace std;
void print (vector<int> & vec) {
for (int i =0 ; i < vec.size(); ++i) {
cout << vec[i] << " ";
}
cout << endl;
}
int main() {
int temp;
vector<int> sort;
sort.push_back(23);
sort.push_back(42);
sort.push_back( 4);
sort.push_back( 16);
sort.push_back( 8);
sort.push_back(15);
print(sort);
int vecsize = sort.size();
for (int j = 0; j < vecsize - 1; ++j) {
int min = j;
for (int i = j+1; i < vecsize; ++i) {
if (sort.at(min) > sort.at(i)) {
min = i;
}
}
if (min != j)
swap(sort.at(j), sort.at(min));
}
print(sort);
return 0;
}

If you can use C++11, you can also solve sorting (as in your example) with lambdas. It's a more powerful and optimized way. You should try it maybe in the future.
[EDITED]:
A short example:
// Example program
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> myVector;
myVector.emplace_back(23);
myVector.emplace_back(42);
myVector.emplace_back(4);
myVector.emplace_back(16);
myVector.emplace_back(8);
myVector.emplace_back(15);
std::sort(myVector.begin(), myVector.end(),
[](int a, int b) -> bool
{
return a < b;
});
}

Related

Showing the original index of an element in a vector after bubblesort

I'm new to c++ and i'm having a problem with my code. I need to show the original indexes of a vector before it was sorted, after sorted. I tried it like this:
#include <vector>
using namespace std;
void bubblesort(vector<int> &a, int n) {
for (int j = 0; j < n - 1; j++) {
for (int i = n - 1; i > j; i--) {
if (a.at(i) < a.at(i-1)) {
int aux = a.at(i);
a.at(i) = a.at(i-1);
a.at(i-1) = aux;
}
}
}
}
int main()
{
int n;
cout << "Digite o tamanho do vetor: ";
cin >> n;
vector<int> v;
vector<int> vold;
vector<int> pos;
for (int i = 0; i < n; i++) {
int a;
cin >> a;
v.push_back(a);
vold.push_back(a);
}
bubblesort(v, n);
for (int i = 0; i < n; i++) {
if (vold.at(i) == v.at(i)) {
pos.push_back(i);
}
else {
for (int j = i+1; j < n - 1; j++) {
if (vold.at(i) == v.at(j)) {
pos.at(j) = i;
break;
}
}
}
}
for (const int& i : pos) {
cout << i << " ";
}
system("pause>0");
}
But it didn't worked, if someone could help me to see what I'm doing wrong I would be glad, thanks in advance.
If your goal is to show the indices of the sorted vector, then another approach is to not sort the original vector, but instead to sort a vector of index values based on the original vector.
The index vector would be initialized to 0, 1, 2, etc. up until the vector's size, minus 1.
Here is an example:
#include <vector>
#include <numeric>
#include <iostream>
void bubblesort(std::vector<int> &a, std::vector<int>& index)
{
// Make sure the index vector is the same size as
// the original
index.resize(a.size());
if ( a.size() <= 1 )
return;
// This is just a shortcut way of setting the values to 0,1,2,etc.
std::iota(index.begin(), index.end(), 0);
size_t n = a.size();
// Here is your sort, but with one difference...
for (size_t j = 0; j < n - 1; j++)
{
for (size_t i = n - 1; i > j; i--)
{
// Look at the comparison being done here using the index array
if (a.at(index[i]) < a.at(index[i-1]))
{
// We swap the index values, not the values
// in the vector
int aux = index.at(i);
index.at(i) = index.at(i-1);
index.at(i-1) = aux;
}
}
}
}
int main()
{
std::vector<int> v = {3, 1, 65, 23, 4};
std::vector<int> index;
bubblesort(v, index);
// Display the index values of the sorted items
for (const int& i : index)
std::cout << i << " ";
}
Output:
1 0 4 3 2
Note that the bubblesort function takes a vector of indices, and not n. There is no need to pass n, since a vector already knows its own size by utilizing the size() function.
The output shows the original index of each of the sorted items.

find frequency in array using vector

How can I change my code to get a count for every element?
With my code everything is okay. And it works, but how can I change only that part?
#include <iostream>
#include <vector>
void countFreq(int arr[], int n)
{
// Mark all array elements as not visited
std::vector<bool> visited(n, false);
// Traverse through array elements and
// count frequencies
for (int i = 0; i < n; i++) {
// Skip this element if already processed
if (visited[i] == true)
continue;
// Count frequency
int count = 1;
for (int j = i + 1; j < n; j++) {
if (arr[i] == arr[j]) {
visited[j] = true;
count++;
}
}
std::cout<<count<<" ";
}
}
int main()
{
int n;
std::cin>>n;
int arr[n];
for(int i = 0; i < n; i++){
std::cin>>arr[i];
}
countFreq(arr, n);
return 0;
}
And about the result`
input 10
1 1 2 2 3 3 4 4 5 5
output 2 2 2 2 2
but I want to get
output 2 2 2 2 2 2 2 2 2 2
(for every element)
Your function contains extra code that ends up confusing you. The visited variable is essentially unnecessary. Start the count at 0 and make no special case for the "current" cell and you'll find that some very simple code will do what you need:
void countFreq(int arr[], int n)
{
// Traverse through array elements and
// count frequencies
for (int i = 0; i < n; i++) {
// Count frequency
int count = 0;
for (int j = 0; j < n; j++) {
if (arr[i] == arr[j]) {
count++;
}
}
std::cout << count << " ";
}
}
You need to save the result to an array for each number. Then when you find any processed number then print counter from the saved array.
#include <iostream>
#include <vector>
#include <unordered_map>
void countFreq(int arr[], int n)
{
// Mark all array elements as not visited
std::vector<bool> visited(n, false);
std::unordered_map<int, int> counter;
// Traverse through array elements and
// count frequencies
for (int i = 0; i < n; i++)
{
// Skip this element if already processed
if (visited[i] == true)
{
std::cout << counter[arr[i]] << " ";
continue;
}
// Count frequency
int count = 1;
for (int j = i + 1; j < n; j++)
{
if (arr[i] == arr[j])
{
visited[j] = true;
count++;
}
}
counter[arr[i]] = count;
std::cout<<count<<" ";
}
}
int main()
{
int n;
std::cin>>n;
int arr[n];
for(int i = 0; i < n; i++)
{
std::cin>>arr[i];
}
countFreq(arr, n);
return 0;
}
The issue is that you discard the values already visited.
One possibility is instead to memorize the count when the value is visited the first time,
and to memorize the index value of the first value appearance, when a value is visited the 2nd, 3rd ... time.
#include <iostream>
#include <vector>
void countFreq(const std::vector<int>& arr) {
int n = arr.size();
// Mark all array elements as not visited
std::vector<int> mem_count(n, n);
// Traverse through array elements and
// count frequencies
for (int i = 0; i < n; i++) {
// Skip this element if already processed
if (mem_count[i] != n) {
std::cout << mem_count[mem_count[i]] << " ";
continue;
}
// Count frequency
int count = 1;
for (int j = i + 1; j < n; j++) {
if (arr[i] == arr[j]) {
mem_count[j] = i;
count++;
}
}
mem_count[i] = count;
std::cout << count << " ";
}
}
int main() {
int n;
std::cin>>n;
std::vector<int> arr(n);
for(int i = 0; i < n; i++){
std::cin >> arr[i];
}
countFreq(arr);
return 0;
}
You can find the frequencies of numbers this way if you know the what is your maximum element in the input array. lets say m is maximum number in your array.
so you have to create a new array of size m. you can simply co-relate them as m buckets. from 0 to m. And each bucket will hold the count of each element in the input array. The index of each bucket will refer to element in the input array. This has time complexity O(1) if we know what is the max element the array.
You can do this way:
std::vector<int> frequencey(std::vector<int>& nums){
auto max = *(std::max_element(nums.begin(), nums.end()));
std::vector<int> frequencies(max + 1, 0);
for(int i = 0; i < nums.size(); ++i){
frequencies[nums[i]] +=1;
}
return frequencies;
}
This is very simple
#include <vector>
#include <map>
#include <iostream>
void main()
{
std::vector<int> v { 1,1,2,2,3,3,4,4,5,5 }; // Your input vector
// Count "frequencies"
std::map<int, int> m;
for (auto i : v)
m[i]++;
// Print output
for (auto i : v)
std::cout << m[i] << " ";
}

What is wrong with my selection sort function c++?

void selectionSort (vector<string>& dictionary)
{
string min;
for (int i = 0; i < dictionary.size(); ++i)
{
for (int j = i + 1; j < dictionary.size(); ++j)
{
if (dictionary.at(j) < dictionary.at(i))
{
min = dictionary.at(j);
}
}
swap(dictionary.at(i), min);
}
return;
}
I entered 5 inputs: hey, ok, so, no, okay
Outputs: no, okay, so, no
Could someone explain where I went wrong with my sorting function? Thanks!
Try this instead:
void selectionSort(vector<string>& dictionary)
{
for (int i = 0; i < dictionary.size(); ++i)
{
int m = i;
for (int j = i + 1; j < dictionary.size(); ++j)
{
if (dictionary[j] < dictionary[m])
m = j;
}
if (m != i)
swap(dictionary[i], dictionary[m]);
}
}
Basically when your i-loop starts you assume that m-th element is smallest and then inside j-loop you check remaining elements if there is a smaller element. If you find smaller element you update m (instead of copying actual strings). At the end of the loop you check if m is changed from i, and if so you swap elements at i and m.
Here's full example with your input, when asking question it's recommended to provide similar minimal example that can easily reproduce your problem:
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <assert.h>
using namespace std;
void selectionSort(vector<string>& dictionary)
{
for (int i = 0; i < dictionary.size(); ++i)
{
int m = i;
for (int j = i + 1; j < dictionary.size(); ++j)
{
if (dictionary[j] < dictionary[m])
m = j;
}
if (m != i)
swap(dictionary[i], dictionary[m]);
}
}
int main()
{
vector<string> data{ "hey", "ok", "so", "no", "okay" };
vector<string> data2 = data;
selectionSort(data);
std::sort(data2.begin(), data2.end());
assert(equal(data.begin(), data.end(), data2.begin())); // verify that your sort matches what std::sort does
for (const auto s : data)
cout << s << ' ';
cout << endl;
}
and the output is:
hey no ok okay so

vector array - sorting failure

I have problem with sorting an array. I don't know why my codes does not sort an array properly. I am new in programming so be gentle on me. Here's a code. Also other functions like merge or quick sort does not work too. Thanks in advance for answer.
#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <iterator>
std::vector<int> bubbleSort(std::vector<int>& Array)
{
for (unsigned int j = 1; j < Array.size() - 1; ++j)
{
for (unsigned int i = 0; i < Array.size() - 1; i++)
{
if (Array[i] > Array[++i])
{
std::swap(Array[i], Array[++i]);
}
}
}
return Array;
}
int main()
{
for (int i = 0; i < 10;i++)
{
int N; //array size
srand(std::time(NULL));
std::cout << " array size: ";
std::cin >> N;
std::vector <int> Array;
//fill array
for (int i = 1; i <= N; i++)
Array.push_back(i);
for (int i = N - 1; i > 0; i--)
{
int j = rand() % i;
std::swap(Array[i], Array[j]);
}
bubbleSort(Array);
for (unsigned int i = 0; i < Array.size(); i++)
{
std::cout << Array.at(i) << std::endl;
}
}
system("pause");
}
It looks like you're unintentionally incrementing i within the loop. Don't use ++i, use i+1 instead. Also change your loop termination condition to just i < Array.size() instead of i < Array.size() - 1

How to sort elements into C++ matrix?

I'm new to C++ programming. I need to sort this matrix:
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
int main(int argc, char** argv) {
Mat10 a;
fillRand(a, 5, 5);
prnMat(a, 5, 5);
cout << endl;
return 0;
}
void fillRand(Mat10 m, int n, int k) {
for (int i = 0; i < n; i++)
for (int j = 0; j < k; j++)
m[i][j] = rand() % 1000;
}
void prnMat(Mat10 a, int m, int n) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++)
cout << setw(8) << a[i][j];
cout << endl;
}
}
I need to sort the matrix from the beginning from the beginning. The smallest value must be at the beginning of the of the first column. The next must be below it and so on. The result must be sorted matrix - the smallest number must be at the beginning of the left column - the biggest value must be at the end of the matrix. Would you please help to solve the problem?
EDIT
Maybe I found possible solution:
void sort(int pin[10][2], int n)
{
int y,d;
for(int i=0;i<n-1;i++)
{
for(int j=0; j<n-1-i; j++)
{
if(pin[j+1][1] < pin[j][1]) // swap the elements depending on the second row if the next value is smaller
{
y = pin[j][1];
pin[j][1] = pin[j+1][1];
pin[j+1][1] = y;
d = pin[j][0];
pin[j][0] = pin[j+1][0];
pin[j+1][0] = d;
}
else if(pin[j+1][1] == pin[j][1]) // else if the two elements are equal, sort them depending on the first row
{
if(pin[j+1][0] < pin[j][0])
{
y = pin[j][1];
pin[j][1] = pin[j+1][1];
pin[j+1][1] = y;
d = pin[j][0];
pin[j][0] = pin[j+1][0];
pin[j+1][0] = d;
}
}
}
}
}
But since I'm new to programming I don't understand is this the solution?
Here is a simple example for you:
#include <vector>
#include <algorithm>
using namespace std;
//This is the comparation function needed for sort()
bool compareFunction (int i,int j)
{
return (i<j);
}
int main()
{
//let's say you have this matrix
int matrix[10][10];
//filling it with random numbers.
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
matrix[i][j] = rand() % 1000;
//Now we get all the data from the matrix into a vector.
std::vector<int> vect;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
vect.push_back(matrix[i][j]);
//and sort the vector using standart sort() function
std::sort( vect.begin(), vect.end(), compareFunction );
//Finally, we put the data back into the matrix
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
matrix[i][j] = vect.at(i*10 + j);
}
After this, the matrix will be sorted by rows:
1 2
3 4
If you want it to be sorted by cols:
1 3
2 4
You need to replace matrix[i][j] in the last cycle only with matrix[j][i]
If you need to read about the the sort() function, you can do it here
Hope this helps.
You can simply call std::sort on the array:
#include <algorithm> // for std::sort
int main() {
int mat[10][10];
// fill in the matrix
...
// sort it
std::sort(&mat[0][0], &mat[0][0]+10*10);
}