Bubble sort output is not sorted - c++

My code works when put in the int main() function but when I implement it as another function (void bubbleSort) the output displays it as if there was no sorting done.
void bubbleSort(int numeros[])
{
int store = 0;
int length = ARRAY_SIZE(numeros);
for(int i=0; i<(length-1); i++)
{
for(int j=0; j<(length-i-1); j++)
{
if(numeros[j] < numeros[j+1])
{
store = numeros[j];
numeros[j] = numeros[j+1];
numeros[j+1] = store;
}
}
}
for(int m=0; m<1000; m++)
{
cout << numeros[m] <<' ';
}
}
What could I have possibly done wrong? Any help would be greatly appreciated.

You can't pass a full array as an argument to a c++ function, only a pointer to the first element in the array. As a result you need some way to tell the function how long the array is. One way it to pass that in as another argument (as shown below). There is some discussion and suggestions of other/better ways to do it here.
For example if you accidentally pass in the wrong length argument to these functions they will start operating on whatever memory exists after the block of memory where your array is.
#include <iostream>
using namespace std;
void printArray(int array[], int length) {
for(int i=0; i<length; i++) {
cout << array[i] << " ";
}
cout << endl;
}
void bubbleSort(int numeros[], int length) {
int store = 0;
for(int i=0; i<(length-1); i++) {
for(int j=0; j<(length-i-1); j++) {
if(numeros[j] < numeros[j+1]) {
store = numeros[j];
numeros[j] = numeros[j+1];
numeros[j+1] = store;
}
}
}
cout << "array at end of bubble sort: ";
printArray(numeros, length);
}
int main() {
int anArray[] = {1, 3, 2, 4, 6, 5, 10, 9, 7, 8};
int arraySize = sizeof(anArray)/sizeof(anArray[0]);
cout << "arraySize: " << arraySize << endl;
cout << "array before sort: ";
printArray(anArray, arraySize);
bubbleSort(anArray, arraySize);
cout << "array after sort: ";
printArray(anArray, arraySize);
return 0;
}

Related

How to debug my C++ program?

I try to enter 2d array and to sum all numbers in one row. Then I convert that number to binary (8 bit) and to set it again in new 2d array. Here's my code. I get output in negative numbers and I expect binary number.
I input
1 2 3
4 5 6
7 8 9
And i want this output
00000110
00001111
00011000
i get
00000000
00000000
00000000
#include<iostream>
using namespace std;
int main()
{
int n,m,j,i;
int a[50][50],b[50][8],c[50];
cin>>n>>m;
for(i=0;i<n;i++)
{
c[i]=0;
for(j=0;j<m;j++)
{
cin>>a[i][m];
cin.ignore();
c[i]+=a[i][j];
}
}
for(i=0;i<n;i++)
for(j=0;j<8;j++)
{
b[i][j]=c[i]%2;
c[i]/=2;
}
for(i=0;i<n;i++)
{
for(j=0;j<8;j++)
{
cout<<b[i][j];
}
cout<<endl;
}
}
I attempted to revise your code but I soon realised that you were doing some weird unnecessary things so I just started fresh and here's what I've got for you:
#include <iostream>
#include <vector>
using namespace std;
void add_array(int arr1[], int arr2[], int arrLength, int ret[]) {
for(int i = 0; i < arrLength; i++) {
ret[i] = arr1[i]+arr2[i];
}
return;
}
void to_binary(int n, vector<int> *ret) {
while(n!=0) {
ret->push_back(n%2==0 ?0:1);
n/=2;
}
}
int main() {
int a[5] = {1,2,3,4,5};
int b[5] = {6,7,8,9,10};
int c[5];
add_array(a, b, 5, c);
cout << "A:" << endl;
for(int i = 0; i < 5; i++) {
cout << i << " : " << a[i] << endl;
}
cout << "B:" << endl;
for(int i = 0; i < 5; i++) {
cout << i << " : " << b[i] << endl;
}
cout << "C:" << endl;
for(int i = 0; i < 5; i++) {
cout << i << " : " << c[i] << endl;
}
vector<int> vec;
for(int i = 0; i < 5; i++) {
to_binary(c[i], &vec);
for(int j = 0; j < vec.size(); j++) {
cout << vec[j];
}
cout << endl;
vec.clear();
}
return 0;
}
I don't know how you were handling the adding of the two functions so I just wrote a really simple function there, I'll start with the parameters
int arr1[], int arr2[]
These are the two functions you'll be adding, simple.
int arrLength
This tells the function what the length of the two arrays is for the 'for loop'
int ret[]
Ret is the return array and is passed in so that it can be modified with the added arrays, now you could do that with either of the other two arrays but this is better practice especially if you want to reuse the other arrays later.
Now here's the function itself
for(int i=0;i<arrLength;i++){ ret[i]=arr1[i]+arr2[i];}
Here we loop through each position in the arrays and place them in the variable 'ret', this is the whole thing.
The function
void to_binary(int n, vector<int> *ret)
handles the decimal to binary using a vector for variable sizes, it's basically what you were doing just in a function.
In the function main we create the three arrays and call add_array with the necessary arguments, then we create the vector vec and then proceed to loop through the array c getting the binary number of each position and then since we stored the binary number in an int vector instead of a string we loop through the vector
for(int j = 0; j < vector.size(); j++)
We are using vector.size() to get the dynamic size of the vector, then we print out each binary digit and then print an endl and clear the vector for reuse.

Error implementing selection sort in C++

I've written this code to sort an array using selection sort, but it doesn't sort the array correctly.
#include <cstdlib>
#include <iostream>
using namespace std;
void selectionsort(int *b, int size)
{
int i, k, menor, posmenor;
for (i = 0; i < size - 1; i++)
{
posmenor = i;
menor = b[i];
for (k = i + 1; k < size; k++)
{
if (b[k] < menor)
{
menor = b[k];
posmenor = k;
}
}
b[posmenor] = b[i];
b[i] = menor;
}
}
int main()
{
typedef int myarray[size];
myarray b;
for (int i = 1; i <= size; i++)
{
cout << "Ingrese numero " << i << ": ";
cin >> b[i];
}
selectionsort(b, size);
for (int l = 1; l <= size; l++)
{
cout << b[l] << endl;
}
system("Pause");
return 0;
}
I can't find the error. I'm new to C++.
Thanks for help.
The selectionSort() function is fine. Array init and output is not. See below.
int main()
{
int size = 10; // for example
typedef int myarray[size];
myarray b;
for (int i=0;i<size;i++)
//------------^^--^
{
cout<<"Ingrese numero "<<i<<": ";
cin>>b[i];
}
selectionsort(b,size);
for (int i=0;i<size;i++)
//------------^^--^
{
cout<<b[l]<<endl;
}
system("Pause");
return 0;
}
In C and C++, an array with n elements starts with the 0 index, and ends with the n-1 index. For your example, the starting index is 0 and ending index is 9. When you iterate like you do in your posted code, you check if the index variable is less than (or not equal to) the size of the array, i.e. size. Thus, on the last step of your iteration, you access b[size], accessing the location in memory next to the last element in the array, which is not guaranteed to contain anything meaningful (being uninitialized), hence the random numbers in your output.
You provided some sample input in the comments to your question.
I compiled and executed the following, which I believe accurately reproduces your shown code, and your sample input:
#include <iostream>
void selectionsort(int* b, int size)
{
int i, k, menor, posmenor;
for(i=0;i<size-1;i++)
{
posmenor=i;
menor=b[i];
for(k=i+1;k<size;k++)
{
if(b[k]<menor)
{
menor=b[k];
posmenor=k;
}
}
b[posmenor]=b[i];
b[i]=menor;
}
}
int main(int argc, char **argv)
{
int a[10] = {-3, 100, 200, 2, 3, 4, -4, -5, 6, 0};
selectionsort(a, 10);
for (auto v:a)
{
std::cout << v << ' ';
}
std::cout << std::endl;
}
The resulting output was as follows:
-5 -4 -3 0 2 3 4 6 100 200
These results look correct. I see nothing wrong with your code, and by using the sample input you posted, this confirms that.

Passing values of array to a function that modifies the value then returns it into a new array

I'm having trouble getting my code to return the correct arrays. void map takes in a function such as tiple and modifies the value that was passed into it from the array src and then returns the new value into dst which is then printed out. I can get the code to compile but it doesn't return the correct array. For example, when it takes in [1,2,3,4] it returns [0,3,6,9] instead of [3,6,9,12]
typedef int (*intModifier)(int);
int triple(int x){
return 3*x;
}
void map(intModifier func, int src[], int dst[], int length){
for(int *i = src; i < src + length; ++i){
dst[*i] = func(*i);
}
return;
}
void printIntArray(int arr[], int length){
cout << "{";
if (length > 0){
cout << arr[0];
}
for(int i = 1; i < length; ++i){
cout << ", " << arr[i];
}
cout << "}";
}
int main(){
int arr1[4] = {1, 2, 3, 4};
int arr2[4] = {0, 0, 0, 0};
int arr3[4] = {0, 0, 0, 0};
int arr4[4] = {0, 0, 0, 0};
cout << "Testing map." << endl;
cout << " setting arr1 = {1,2,3,4}" << endl << endl;
cout << " mapping from arr1 to arr2 using triple" << endl;
map(triple, arr1, arr2, 4);
cout << " arr2 = ";
printIntArray(arr2, 4); cout << endl << endl;
return 0;
}
Any help is appreciated. Thanks.
I am not sure why it is only the second element being modified. But the fact that is only one is almost definitely this:
void map(intModifier func, int src[], int dst[], int length){
for(int *i = src; i < src + length; i++){
dst[*i] = func(src[*i]);
return; // You return here!!!
}
}
You will always return from map during the first iteration of your for loop. See how beneficial it is to indent your code!
Your map function is what is causing most of the issues. Especially in the way you are trying to conduct the operations in the for loop.
void map(intModifier func, int src[], int dst[], int length){
for(int *i = src; i < src + length; ++i){ // There are some major issues in how you are
dst[*i] = func(*i); // iterating through the source array.
}
return;
}
You are using the value of the source array to increment and store data between your destination array and source array. Your arrays are only 4 int "blocks" yet you increment through source at the source base length plus 4 i < src + length which is going well past your array length.
It would be better if you iterate through using the length you pass in, that's essentially why you pass the length in correct? So you could use this:
void map(intModifier func, int src[], int dst[], int length){
for (int i = 0; i < length; i++) // Iterate until we have met the length of the source
{ // array. Pass the source array off to our triple func
dst[i] = func(src[i]);
}
return;
}
The function iterates through source and passes its contents to the triple func then stores it at the same location in our destination array.
EDIT: Credit given to 1201ProgramAlarm and Ben.

C++ Passing Dynamic Pointer to a 2D Array

This is an extension to a previous question I previously asked. I can use a template to submit a dynamic 2D array and access the elements. Now, let's say I have a pointer to such an array. I am currently using the method shown here to assign my pointer to the original 2d array. I initially thought I could just change the expected input of the template function to (*A)[M][N] but that's a no-go. Am I missing some concept regarding pointers that someone could kindly explain?
header.h
#pragma once
#include <cstddef>
#include <iostream>
using namespace std;
template<size_t N, size_t M>
void printPtr( int(*A)[M][N]) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << A[i][j] << " ";
}
cout << endl;
}
}
main.cpp
#include "header.h"
#include <iostream>
using namespace std;
int main() {
int A[][3] = {
{1,2,3},
{4,5,6},
{7,8,9},
{10,11,12}
};
int (*ptrA)[3] = A;
printPtr(ptrA);
}
If you're not interested in knowing why your code isn't working in the first place just skip to the end of this post
The problem with your code is that you're "simulating" an array decaying by passing your pointer along:
int A[][2] = {
{1,2,3},
{4,5,6},
{7,8,9},
{10,11,12}
};
int (*ptrA)[3] = A;
This is confirmed by the following code which uses C++11 features:
#include <iostream>
#include <type_traits>
using namespace std;
template <typename T, typename U>
struct decay_equiv :
std::is_same<typename std::decay<T>::type, U>::type
{};
int main() {
int A[][4] = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 }
};
std::cout << std::boolalpha
<< decay_equiv<decltype(A), int(*)[3]>::value << '\n'; // Prints "true"
}
Example
You should either pass a non-decayed type (i.e. a type that has all the information regarding the array dimension) to the function via a pointer or a reference:
#include <cstddef>
#include <iostream>
using namespace std;
template<size_t N, size_t M>
void printPtr(int (*A)[M][N] /* Also a reference could work */) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << (*A)[i][j] << " ";
}
cout << endl;
}
}
int main() {
int A[][6] = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 }
};
int(*ptrA)[4][7] = &A; // Not a decayed type
printPtr(ptrA);
}
Example
Another solution would be to not use a pointer to the array in the first place or dereference it when passing a reference to the array:
template<size_t N, size_t M>
void printPtr( int(&A)[M][N]) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << A[i][j] << " ";
}
cout << endl;
}
}
...
printPtr(A);
printPtr(*ptrA);
Example
You defined the function parameter as a pointer to a two-dimensional array
int(*A)[M][N])
while are trying to call the function passing as the argument a pointer to a one-dimensional array
int (*ptrA)[3] = A;
printPtr(ptrA);
Moreover the function itself is invalid. It shall look like
template<size_t N, size_t M>
void printPtr( int(*A)[M][N]) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << ( *A )[i][j] << " ";
}
cout << endl;
}
}
that is you have to use expression ( *A )[i][j] instead of A[i][j]
So you need to change the function the way shown above and to use appropriate pointer as the argument
int (*ptrA)[4][3] = &A;
printPtr(ptrA);
Of course it would be better to define the function parameter as reference to a two-dimensional array. For example
template<size_t N, size_t M>
void printPtr( int(&A)[M][N]) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << A[i][j] << " ";
}
cout << endl;
}
}
In this case you could call the function like
printPtr( A );
It should be
template<size_t N, size_t M>
void printPtr(const int(&A)[M][N]) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << A[i][j] << " ";
}
cout << endl;
}
}
calling with:
printPtr(A);
or
template<size_t N, size_t M>
void printPtr(const int(*A)[M][N]) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << (*A)[i][j] << " ";
}
cout << endl;
}
}
calling with:
printPtr(&A);
BTW your pointer should be:
int (*ptrA)[4][3] = &A;

Find unique numbers in array

Well, I have to find how many different numbers are in an array.
For example if array is: 1 9 4 5 8 3 1 3 5
The output should be 6, because 1,9,4,5,8,3 are unique and 1,3,5 are repeating (not unique).
So, here is my code so far..... not working properly thought.
#include <iostream>
using namespace std;
int main() {
int r = 0, a[50], n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int j = 0; j < n; j++) {
for (int k = 0; k < j; k++) {
if (a[k] != a[j]) r++;
}
}
cout << r << endl;
return 0;
}
Let me join the party ;)
You could also use a hash-table:
#include <unordered_set>
#include <iostream>
int main() {
int a[] = { 1, 9, 4, 5, 8, 3, 1, 3, 5 };
const size_t len = sizeof(a) / sizeof(a[0]);
std::unordered_set<int> s(a, a + len);
std::cout << s.size() << std::endl;
return EXIT_SUCCESS;
}
Not that it matters here, but this will likely have the best performance for large arrays.
If the difference between smallest and greatest element is reasonably small, then you could do something even faster:
Create a vector<bool> that spans the range between min and max element (if you knew the array elements at compile-time, I'd suggest the std::bitset instead, but then you could just compute everything in the compile-time using template meta-programming anyway).
For each element of the input array, set the corresponding flag in vector<bool>.
Once you are done, simply count the number of trues in the vector<bool>.
A std::set contains only unique elements already.
#include <set>
int main()
{
int a[] = { 1, 9, 4, 5, 8, 3, 1, 3, 5 };
std::set<int> sa(a, a + 9);
std::cout << sa.size() << std::endl;
}
How about this?
#include <list>
int main()
{
int a[] = {1, 9, 4, 5, 8, 3, 1, 3, 5};
std::list<int> la(a, a+9);
la.sort();
la.unique();
std::cout << la.size() << std::endl;
return 0;
}
Since you've stated that you cannot use the standard library and must use loops, let's try this solution instead.
#include <iostream>
using namespace std; // you're a bad, bad boy!
int main()
{
int r = 0, a[50], n;
cout << "How many numbers will you input? ";
cin >> n;
if(n <= 0)
{
cout << "What? Put me in Coach. I'm ready! I can do this!" << endl;
return -1;
}
if(n > 50)
{
cout << "So many numbers! I... can't do this Coach!" << endl;
return -1;
}
cout << "OK... Enter your numbers now." << endl;
for (int i = 0; i < n; i++)
cin >> a[i];
cout << "Let's see... ";
// We could sort the list but that's a bit too much. We will choose the
// naive approach which is O(n^2), but that's OK. We're still learning!
for (int i = 0; i != n; i++)
{ // Go through the list once.
for (int j = 0; j != i; j++)
{ // And check if this number has already appeared in the list:
if((i != j) && (a[j] == a[i]))
{ // A duplicate number!
r++;
break;
}
}
}
cout << "I count " << n - r << " unique numbers!" << endl;
return 0;
}
I urge you to not submit this code as your homework - at least not without understanding it. You will only do yourself a disservice, and chances are that your instructor will know that you didn't write it anyways: I've been a grader before, and it's fairly obvious when someone's code quality magically improves.
I think the location for increasing the value of r is incorrect
#include <iostream>
using namespace std;
int main()
{
int r=0,a[50],n;
cin >>n;
for(int i=0;i<n;i++)
{
cin >> a[i];
}
for (int j=0;j<n;j++)
{
bool flag = true;
for(int k=;k<j;k++)
{
if(a[k]!=a[j])
{
flag = false;
break;
}
}
if (true == flag)
{
r++;
}
}
cout << r << endl;
return 0;
}
However, my suggestion is using more sophisticated algorithms (this algorithm has O(N^2)).
this should work, however its probably not the optimum solution.
#include <iostream>
using namespace std;
int main()
{
int a[50],n;
int uniqueNumbers; // this will be the total numbers entered and we will -- it
cin >>n;
uniqueNumbers = n;
for(int i=0;i<n;i++)
{
cin >> a[i];
}
for (int j=0;j<n;j++)
{
for(int k=0;k<n;k++)
{
/*
the and clause below is what I think you were missing.
you were probably getting false positatives when j == k because a[1] will always == a[1] ;-)
*/
if((a[k] == a[j]) && (k!=j))
{ uniqueNumebers--; }
}
}
cout << uniqueNumbers << endl;
return 0;
}
We can use C++ STL vector in this program .
int main()
{
int a[] = {1, 9, 4, 5, 8, 3, 1, 3, 5};
vector<int>v(a, a+9);
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
cout<<v.size()<<endl;
return 0;
}
Please dry run your code
See in the outer for loop for each element it is counted more than one inside inner loop.let us say the loop contains 1,2,3,4.1.....elements dry run it in the second iteration and third iteration 1 is counted because 1 is 1!=2 as well as 1!=3
Now solution time!!
#include<iostream>
#include<vector>
#include<algorithm>
#define ll long long
using namespace std;
ll arr[1000007]={0};
int main()
{
ios_base::sync_with_stdio(false);//used for fast i/o
ll n;cin>>n;
for(ll i=1;i<=n;i++)
cin>>arr[i];
sort(arr,arr+n);
ll cnt=0;
for(ll i=1;i<=n-1;i++)
{
if(arr[i+1]-arr[i]==0)
cnt++;
}
cout<<n-cnt<<endl;
cin.tie(NULL);
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int find_unique(int arr[], int size){
int ans = 0;
for(int i = 0; i < size; i++){
ans = ans^arr[i]; // this is bitwise operator .its call XOR it's return only unique value..
}
return ans;
}
void print_array(int arr[], int size){
for(int i = 0; i < size; i++){
cout << arr[i] << " ";
}
cout << endl;
}
int main()
{
ios_base::sync_with_stdio(false); cin.tie(NULL); // use for fast input and output....
int arr[5] = {1, 3, 5, 3, 1};
cout <<"Orginal array: " << endl;
print_array(arr, 5);
int result = find_unique(arr, 5);
cout << result << endl;
return 0;
}