C++ issue with bubble sort - c++

I am attempting to use bubble sort in C++ which I am new to. This is my code so far:
My issue is that when ever I try and sort the arrays, the integer array is set to zero at every index.
Could this have something to do with memory allocation?
#include <iostream>
#include <cstring>
#include <array>
using namespace std;
int main() {
//requires users input to create an array that wouldn't use too much memory
cout << "Enter number of dealers you wish to enter" << endl;
int array_size;
cin >> array_size;
std::string sales_names[array_size]; //makes a 2D array that can have 15 rows and 2 colums {Name, sales total}
int sales_data[array_size];
for(int i = 0; i < array_size; i++){
std::string dealers_name;
int dealers_value;
cout << "Enter Dealers Name: ";
cin >> dealers_name;
cin.clear();
cout << "Enter Dealers Sales: ";
cin >> dealers_value;
sales_names[i] = dealers_name;
sales_data[i] = dealers_value;
cout << endl;
}
string temp_name;
int temp_value;
//Bubble Sort?
for(int i = 0; i < array_size; i++){
for(int k = 0; k < array_size; k++){
if(sales_data[k] = sales_data[k+1])
{
temp_value = sales_data[k];
temp_name = sales_names[k];
sales_data[k] = sales_data[k+1];
sales_names[k] = sales_names[k+1];
sales_data[k+1] = temp_value;
sales_names[k+1] = temp_name;
}
}
}
for(int i = 0; i < array_size; i++){
cout << sales_data[i] << endl;
cout << sales_names[i] << endl;
}
return 0;
}
Im not sure why, but after the first loop of the for loop, every item in the sales_data array is set to 0
Here is my output:
Enter number of dealers you wish to enter
3
Enter Dealers Name:test1
Enter Dealers Sales:12
Enter Dealers Name:test2
Enter Dealers Sales:6
Enter Dealers Name:test3
Enter Dealers Sales:9
0
test3
0
test2
0
test1
Thanks in advance

You have two obvious problems.
In
for(int i = 0; i < array_size; i++){
for(int k = 0; k < array_size; k++){
if(sales_data[k] = sales_data[k+1])
you are assigning (=) instead of comparing (==). Though there's no point in a bubble if they match. Perhaps you want less than?
Also, watch out for running up to k, and inspecting k+1

Your comparison is wrong:
if (sales_data[k] = sales_data[k + 1])
This should be a < (or a >, depending on if you want to sort ascending or descending). Even if you wanted to test for equality, == would have been right, not =. Also here
for (int k = 0; k < array_size-1; k++) {
You should put array_size-1, otherwise it's going out of bounds.
Also note that VLAs aren't actually part of standard C++. Use std::vector instead:
std::vector<std::string> sales_names(array_size);
std::vector<int> sales_data(array_size);
By the way, that comment about it making a 2D array is wrong.

There are multiple issues with your code:
sales_data[k] = sales_data[k+1] should be sales_data[k] == sales_data[k+1]
for(int k = 0; k < array_size; k++) loop should start from i+1 for a bubble sort or you can change the condition to k < array_size-i-1

2 changes/questions:
Why are you swapping when data is same ? You only need to swap if i < k and arr[i] > arr[k].
You are going out of bounds when accessing k+1 for inner loop, it should be k
.

Related

i am only getting the output right if i say i is int specially in for loop

#include <iostream>
using namespace std;
// finding the required sum of subarray
int main()
{
int n,s;
int i=0,j=0,st=-1,en=-1,sum=0;
cin>>s; //input required sum
cin>>n;
int a[n];
for(int i=0;i<n;i++){ // here if i only mention int again i //am getting the output or else the values of st and en are printing //out the same as i initialize
cin>>a[i];
}
while (j<n){
sum+=a[j];
while(sum>s){
sum-=a[i];
i++;
}
if(sum==s){
st=i+1;
en=j+1;
break;
}
j++;
}
cout<<st<<" "<<en<<" ";
return 0;
the output is -1 -1
and if i mention "int i" again in for loop of inputing array i a getting the answer.
i want to know the reason i already intialize i before why do i need to do it again
The problem statement is unclear, I'm assuming you simply want the indexes of the repeating numbers in array a. You are correct for the most part, using b[i] = i is the problem. If you understand what a vector is, then simply create a vector like this and push the indexes in the vector. For example,
vector<int> b;
and inside the a[i] == a[j] condition,
b.push_back(i);
then finally print out result like,
for(int i = 0 ; i < b.size() , i++)
cout << b[i] << " ";
If you're unfamiliar with vectors, simply use another variable cnt to update index of array b
int a[n], i, b[n], j, cnt = 0;
and inside the a[i] == a[j] condition,
b[cnt] = i;
cnt++;
and finally
for(int i = 0 ; i < cnt ; i++)
cout << b[i] << ' ';

New integer array shifted to the right?

I should input the array x[ ] and create the new array y[ ], that is shifted to the right from the original.
I'm havong trouble with the first element, y[0]
for ex. if i input {7, 8, 4, 2, 3}
the code below returns: {-693726240, 7, 8, 4, 2}
where is the error?
Thanks in advance.
#include <iostream>
using namespace std;
int main()
{
int i, j, n, m=0, x[100],y[100];
cin >>n;
for(int i=0; i<n; i++)
{
cout << "enter "<< i+1 <<". element: ";
cin >> x[i];
if (i>0)
y[m++] = x[i-1];
else //THIS IS FOR Y[0] BUT DOESN'T WORK
y[m++] = x[n-1];
}
// ARRAY SHIFTED TO THE RIGHT:
for(int j=0; j<m; j++)
{
cout << y[j]<<" ";
}
return 0;
}
Loop starts with i == 0. You read the i-th element at i-th iteration. i == n - 1 is yet some time in the future when you read x[n - 1] in the 0-th iteration. C++ is not obliged to initialise variables for you to any particular value, so when you read from a not-yet-initialised location, you are likely to get garbage (in this case, -693726240).
To solve this, you have to solve the time paradox. Don't assign anything at iteration 0; wait till the loop is done and all data is in, and only then sneak back and fill in the 0-th element.
Alternately, read the entirety of x first, then when you know all the values, use your current algorithm to shift x into y (i.e. separate the current do-everything loop into a read loop and shift loop). This way, all the x values will be known when you start on y, and you won't have any time-travel mishaps.
I am assuming that you are looking for a circular shift given that you wrote y[m++] = x[n-1]
Amadan's answer highlights a way of solving your problem, here is some code you can follow :
for(int i = 0;i < n-1;i++){
cin>>x[i];`
y[i+1] = x[i];
}
cin>>x[n-1];
y[0] = x[n-1];
got it, great, #Amadan thanks for explanation and quick answer
I also removed "j" and "m" as separate variables for the new array,
think it's not needed actually, I can use the same "i" and "n" that are used for the original array (right? Or should I keep the new variables?)
Here's corrected code that works:
#include <iostream>
using namespace std;
int main()
{
int i, j, n, m=0, x[100],y[100];
cin >>n;
for(int i=0; i<n; i++)
{
cout << "enter "<< i+1 <<". element: ";
cin >> x[i];
if (i>0)
y[i] = x[i-1];
}
y[0] = x[n-1];
// ARRAY SHIFTED TO THE RIGHT:
for(int i=0; i<n; i++)
{
cout << y[i]<<" ";
}
return 0;
}
also I tried the other alternative #Amadan suggested, and used it also for left shifting
- first input all the elements, then assigning another array elements when they're all known
I consider this as the best one, tested and working. Thanks again:
#include <iostream>
using namespace std;
int main()
{
int i, n, x[100],y[100], z[100];
cin >>n;
for(int i=0; i<n; i++)
cin >> x[i];
// ARRAY SHIFTED TO THE RIGHT:
for(int i=0; i<n; i++)
{
if (i > 0) y[i] = x[i-1];
else y[i] = x[n-1];
cout << y[i]<<" ";
}
cout << endl;
// ARRAY SHIFTED TO THE LEFT:
for(int i=0; i<n; i++)
{
if (i < n-1) z[i] = x[i+1];
else z[i] = x[0];
cout << z[i]<<" ";
}
return 0;
}

Sorting my 2d array in c++

My homework program has to write random numbers for arrival time and burst time into a file. Then after they are written, it reads the file and sorts the contents.
I figured setting up a 2d array would be the easiest way for me to go about this. But I am unsure on how to implement my sort so that if an arrival time swaps places then burst time of that arrival goes along for the ride.
I feel like I worded that poorly, but a basic example would be:
array[3][10] > array[2][23]
So since second array has an earlier arrival time I need both its arrival 2 and its burst 23 to move before array[3][10], but I need this do that and compare 100 inputs.
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <fstream>
const int max = 100;
using namespace std;
int main()
{
multimap<int [][]> myMap;
int randomBurst[max];
int arrivalTime[max];
int line[max][2];
int first = 0;
for (int i = 0; i < 100; i++)
{
if (i < 100)
{
ofstream write("Schedule.txt", ios::app);
randomBurst[i] = rand() % 1000;
arrivalTime[i] = rand() % 1000;
write << arrivalTime[i] << " " << randomBurst[i] << endl;
}
}
ifstream read("Schedule.txt");
for (int i = 0; i <= max; i++)
{
for (int j = 0; j < 2; j++)
{
read >> line[i][j];
cout << line[i][j] << " " ;
}
cout << endl;
}
cout << endl;
cout << endl;
for (int i = 0; i <= max; i++)
{
for (int j = 0; j < 2; j++)
{
myMap.insert(pair<int[][]>(line[i][j]);
}
cout << endl;
}
system("pause");
return 0;
}
My code sets up my array correctly after it reads the written file content, but I'm kind of lost what I should implement for a sort.
Well coming forward with this, mainly left that comment to be able to find this question faster on my laptop.
Like I said in the comment, if you want a presorted, by key value 2D "array", the quickest manner in which you could do this is with the map container., and if you really need the internal points to be ordered, and you will be using multiple entries within it, lets say entries 2,30 2,12 ... You could either build a map of vectors, or arrays, or use a Multimap. Not too sure of this data structure, as I have never really had a reason to use it as of yet. Referenced here http://www.cplusplus.com/reference/map/multimap/
The above will provide you with the sorting done for you, and the reason why I recommended a vector is the lack of order within it, and not sure if the 'bursts?' are to be ordered as well.
EDIT:
Forgot to mention, that a map will not hold more than one key of any given value, so if you are, again, inputting multiple points a above, then you will. if implementing things as you were before, overwrite things.
EDIT:
So this is more or less the fix I think I have, but you are working around this in a very indirect manner, that is hard to follow honestly.
#include <map>
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <fstream>
using namespace std;
const int MAX = 100;
int main()
{
multimap<int,int> myMap;
int randomBurst[100];
int arrivalTime[100];
int line[100][2];
int first = 0;
for (int i = 0; i < 100; i++)
{
if (i < 100)
{
ofstream write("Schedule.txt", ios::app);
randomBurst[i] = rand() % 1000;
arrivalTime[i] = rand() % 1000;
write << arrivalTime[i] << " " << randomBurst[i] << endl;
}
}
ifstream read("Schedule.txt");
for (int i = 0; i <= 100; i++)
{
for (int j = 0; j < 2; j++)
{
read >> line[i][j];
cout << line[i][j] << " " ;
}
cout << endl;
}
// cout << endl;
// cout << endl;
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 2; j++)
{
//Attain the value in the index, and the held value within it.
myMap.insert(pair<int, int> (line[i][j], line[i][j]));
}
cout << endl;
}
// system("pause");
return 0;
This fixes the insertion point, just because you give it an array it does not mean that the program will take that as a pair, as the first index is a point to another array in itself. And so on. I recommend starting off wiht a map object instead, as the multimap makes things a bit annoying, if you are familiar with the vector containers then use that instead within the map to log multiple values.

Having Trouble With A Simple C++ Program

I'm creating this very simple C++ program.
the program asks the user to enter a few integers and stores them in an array.but when a specific integer(for example 50)is entered,the input is ended and then,all of the integers are displayed on the screen except for 50.
for example:
input:
1
2
88
50
output:
1
2
88
the error i'm getting is when i use cout to print the array,all of numbers are shown,including 50 and numbers i did'nt even entered.
this is my code so far:
#include<iostream>
int main() {
int num[100];
for(int i=0;i<=100;i++) {
cin >> num[i];
if (num[i]!=50) break;
}
for(int j=0;j<=100;j++) {
cout << num[j] << endl;
}
return 0;
}
Change the program the following way
#include<iostream>
int main()
{
const size_t N = 100;
int num[N];
size_t n = 0;
int value;
while ( n < N && std::cin >> value && value != 50 ) num[n++] = value;
for ( size_t i = 0; i < n; i++ ) std::cout << num[i] << std::endl;
return 0;
}
Here in the first loop variable n is used to count the actual number of entered values. And then this variable is used as the upper bound for the second loop.
As for your program then the valid range of indices for the first loop is 0-99 and you have to output only whose elements of the array that were inputed.
A do while loop is more suitable for your problem. The stop condition will check if the number fit inside the array (if k is not bigger than 100) and if number entered is 50.
#include<iostream>
using namespace std;
int main() {
int num[100];
int k = 0;
// A do while loop will be more suitable
do{
cin >> num[k++];
}while(k<100&&num[k-1]!=50);
for (int j = 0; j < k-1; j++) {
cout << num[j] << endl;
}
return 0;
}
Also, a better solution to get rid of 100 limitation is to use std::vector data structure that automatically adjust it's size, like this:
vector<int> num;
int temp;
do {
cin >> temp;
num.push_back(temp);
} while (temp != 50);
Note, you can use temp.size() to get the number of items stored.
You read up to 101 numbers, but if you enter 50 you break the loop and go for printing it. In the printing loop you go through all 101 numbers, but you actually may have not set all of them.
In the first loop count in a count variable the numbers you read until you meet 50 and in the printing loop just iterate count-1 times.
You have allocated an array of 100 integers on the stack. The values are not initialized to zero by default, so you end up having whatever was on the stack previously appear in your array.
You have also off-by-one in both of your loops, you allocated array of 100 integers so that means index range of 0-99.
As the question is tagged as C++, I would suggest that you leave the C-style array and instead use a std::vector to store the values. This makes it more flexible as you don't have to specify a fixed size (or manage memory) and you don't end up with uninitialized values.
Little example code (requires C++11 compiler):
#include <iostream>
#include <vector>
int main()
{
std::vector<int> numbers; // Store the numbers here
for(int i = 0; i < 100; ++i) // Ask a number 100 times
{
int n;
std::cin >> n;
if( n == 50 ) // Stop if user enters 50
break;
numbers.push_back(n); // Add the number to the numbers vector
}
for (auto n : numbers) // Print all the values in the numbers vector
std::cout << n << std::endl;
return 0;
}
There are just 2 changes in your code check it out :
int main()
{
int num[100],i; //initialize i outside scope to count number of inputs
for(i=0;i<100;i++) {
cin >> num[i];
if (num[i]==50) break; //break if the entered number is 50
}
for(int j=0;j<=i-1;j++)
{
cout << num[j] << endl;
}
return 0;
}
Okay, others already pointed out the two mistakes. You should use i < 100 in the loop conditions instead of i <= 100 and you have to keep track of how many elements you entered.
Now let me add an answer how I think it would be better.
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers; // Create an empty vector.
for (int temp; // a temp variable in the for loop.
numbers.size() < 100 && // check that we have less than 100 elements.
std::cin >> temp && // read in the temp variable,
// and check if the read was a success.
temp != 50) // lastly check that the value we read isn't 50.
{
numbers.push_back(temp); // Now we just add it to the vector.
}
for (int i = 0; i < numbers.size(); ++i)
std::cout << numbers[i]; // Now we just print all the elements of
// the vector. We only added correct items.
}
The above code doesn't even read anymore numbers after it found 50. And if you want to be able to enter any number of elements you just have to remove the check that we have less than 100 elements.
Now I commented the above code a bit much, if you compress it it'll reduce to just:
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers; // Create an empty vector.
for (int temp; numbers.size() < 100 && std::cin >> temp && temp != 50)
numbers.push_back(temp);
for (int i = 0; i < numbers.size(); ++i)
std::cout << numbers[i];
}
If you can use the C++11 standard it reduces to:
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers; // Create an empty vector.
for (int temp; numbers.size() < 100 && std::cin >> temp && temp != 50)
numbers.push_back(temp);
for (int element : numbers)
std::cout << element;
}
for (auto element : numbers) is new, it basically means for every int 'element' in 'numbers'.

Arrays homework question

I have this homework question:
Write and test a program that read in n integers (max value for n is 20), each integer has
a value between 0 and 100 inclusive. You program should then print out the unique values
among the input numbers and the count of these values.
Sample input:
Enter a the number of integers = 8
Enter 8 integers: 5 6 7 6 6 17 17 35
Sample output:
Number 5: 1
Number 6: 3
Number 7: 1
Number 17: 2
Number 35: 1
This is what I did:
#include<iostream>
using namespace std;
int main(){
int a[20], n;
cout<< "Please enter the number of integers= ";
cin>> n;
cout<<"Please enter"<< n<<" integers: ";
for (int i=0; i<n; i++)
cin >> a[i];
for (int k=0; k< n; k++){
int sum=0;
for (int i=0; i< n; i++){
if (a[i]==a[k])
sum= sum+1;
}
cout<< "Number "<< a[k]<<" : "<< sum<< endl;
}
}
Consider that when you iterate through your list, you're checking all values with both i and k. So essentially, if you had a list of 1 1 2 2, then the first one will count itself, and the 1 at a[1]. The second 1 will count the first 1 and itself, giving you your repeated output.
A way to simplify this would be to make use of a hash_map, or some similar structure (I'm not as familiar with C++) that maps a key to a value and doesn't allow repeats. This would allow you to record the unique numbers as keys, and increment them with only one pass through the list. The advantage to using the hashMap is that you make your program linear (although I don't think that's really a concern at this stage).
The simplest way to solve your problem, however would be to use a Bin sort technique. The underlying idea here is that your number range is simply 0 to 100, meaning you could create bins for 0 to 100 and increment each one. Again, this is Java code, and doesn't have any actual input for a.
// Count is the key, it uses indexes from 0 to 100, with null values of
// 0 after initialized. Simply iterate the loop, and use the value of
// a[k] to increment the corresponding count in the count array.
// Finally, print the results
int[] a = new int[20];
int[] count = new int [101];
for (int k = 0; k < a.length; k++){
count[a[k]]++;
for (int i = 0; i < count.length; i++){
if (count[i] > 0)
System.out.println(i + ": " + count[i]);
}
Add another bool b[20] ,initialize it with true. Then every time you detect a[k] is a dupe, you set b[k] = false. Only print a[k] if b[k] == true
for (int k = 0; k < n; k++) {
if (!b[k]) {
continue;
}
int sum = 0;
for (int i = 0; i < n; i++) {
if (a[i] == a[k]) {
sum = sum + 1;
b[i] = false;
}
}
cout << "Number " << a[k] << " : " << sum << endl;
}
You have to keep a running count of the items you processed in a separate array, and before running your inner loop to count the items, check if he item you're trying to count isn't in your second array already.
Before you print the result, check if you already printed it for this number
Here's my new attempt.
A quick fix (while not the most professional) would be to create another loop checking for repeats right before printing out.
I took your current big loop and turned it into an even bigger monster.
I also tested it out and it works for me. =D
for (int k=0; k< n; k++){
int sum=0;
for (int i=0; i< n; i++)
{
if (a[i]==a[k])
sum= sum+1;
}
bool repeat = false;
for(int i = 0; i < k; i++)
{
if(a[k] == a[i])
{
repeat = true;
}
}
if(!repeat)
cout<< "Number "<< a[k]<<" : "<< sum<< endl;
}
An alternate implementation (and more memory-hungry with your current limit of 20 input values) would be to create an array of 100 "count" values. Increment the appropriate item for each input value, then iterate through the count array outputting non-zero values.
Apparently that description wasn't good enough... perhaps some code would help (NOTE:This code is untested, but should be enough for you to understand the concept):
#include<iostream>
using namespace std;
int main(){
int a[101], n, v;
cout<< "Please enter the number of integers= ";
cin>> n;
cout<<"Please enter"<< n<<" integers: ";
for (int i=0; i<n; i++)
{
cin >> v;
a[v] ++;
}
for (int k=0; k< 100; k++){
if (a[k] > 0)
{
cout<< "Number "<< k + 1 <<" : "<< a[k] << endl;
}
}
}
}
getting familiar with Standart Template Library is the key to writing good programs in my humble opinion, since this is a homework, you do the controlling for 0 and 100 ;-))
#include <iostream>
#include <map>
using std::cin;
using std::map;
using std::cout;
using std::endl;
int main()
{
int limit = 20;
int cnt=0;
int n;
map<int, int> counters;
while( cnt++ < limit )
{
cin >> n;
++counters[n];
}
for(map<int, int>::iterator it = counters.begin();
it!=counters.end(); ++ it)
cout << it->first << " " << it->second << endl;
return 0;
}