Counting number of swaps by comparing adjacent elements in an array - c++

I am trying to count number of swaps to sort the given array in ascending order. Inside the for loop I have a if condition to check the condition weather to swap or not , But inside if condition I have added a cout statement to check which elements are being compared, When I have that cout statement number of swaps printed are different, and when I remove that statement number of swaps printed are different, for sample:
if I have cout statement
Sample Input
1
4
4 1 2 3
and output came as
3
if I remove or comment that cout statement
Sample Input
1
4
4 1 2 3
and output came as
4
I can't figure out the reason for this.
#include <iostream>
using namespace std;
int main() {
int swap=0,t,n,arr[20],temp;
cin>>t;
while(t!=0) {
cin>>n;
for(int i = 0 ; i < n ; i++) {
cin>>arr[i];
}
for(int i = 0 ; i < n ; i++) {
if(arr[i]>arr[i+1]) {
swap++;
cout<<arr[i]<<">"<<arr[i+1]<<endl; //this cout statement
temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
cout<<swap<<endl;
--t;
}
return 0;
}

Your result is non-deterministic since you are accessing a position of the array that should not be accessed, i.e. when i = n - 1, a[i+1] is trying to access a[n] that is "dirty" memory.
Furthermore I think that your algorithm does not do what you want it to do. I suggest you to read here before going further. From the right code, it's enough to add the counter (as you did) to obtain the correct result.

Related

Value of a variable is not updating, it is either 1 or 0

Hey there! In the following code, I am trying to count frequency of each non zero number
My intention of the code is to update freq after testing each case using nested loop but value of freq is not updating. freq value remains to be either 0 or 1. I tried to debug but still ending up with the same bug.
Code:
#include <bits/stdc++.h>
using namespace std;
int main() {
int size;
cin>>size;
int freq=0;
int d[size];
for(int i=0;i<size;i++){ //To create array and store values in it
cin>>d[i];
}
for(int i=0;i<size;i++){
if(d[i]==0 )continue;
for(int j=0;j<size;j++){
if(d[i]==d[j]){
freq=freq+1;
d[j]=0;
}
}
cout<<"Frequency of number "<<d[i]<<" is "<<freq<<endl;
d[i]=0;
freq=0;
}
}
Input:
5
1 1 2 2 5
Expected output:
Frequency of number 1 is 2
Frequency of number 2 is 2
Frequency of number 5 is 1
Actual output:
Frequency of number 0 is 1
Frequency of number 0 is 1
Frequency of number 0 is 1
Frequency of number 0 is 1
Frequency of number 0 is 1
Some one please debug the code and fix it. Open for suggestions.
#include <bits/stdc++.h>
This is not standard C++. Don't use this. Include individual standard headers as you need them.
using namespace std;
This is a bad habit. Don't use this. Either use individual using declarations for identifiers you need, such as using std::cout;, or just prefix everything standard in your code with std:: (this is what most people prefer).
int d[size];
This is not standard C++. Don't use this. Use std::vector instead.
for(int j=0;j<size;j++){
if(d[i]==d[j]){
Assume i == 0. The condition if(d[i]==d[j]) is true when i == j, that is, when j == 0. So the next thing that happens is you zero out d[0].
Now assume i == 1. The condition if(d[i]==d[j]) is true when i == j, that is, when j == 1. So the next thing that happens is you zero out d[1].
Now assume i == 2. The condition if(d[i]==d[j]) is true when i == j, that is, when j == 2. So the next thing that happens is you zero out d[2].
Now assume i == 3 ...
So you zero out every element of the array the first time you see it, and if(d[i]==d[j]) never becomes true when i != j.
This can be fixed by changing the inner loop to
for (int j = i + 1; j < size; j++) {
This will output freq which is off by one, because this loop doesn't count the first element. Change freq = 0 to freq = 1 to fix that. I recommend having one place where you have freq = 1. A good place to place this assignment is just before the inner loop.
Note, I'm using spaces around operators and you should too. Cramped code is hard to read.
Here is a live demo of your program with all the aforementioned problems fixed. No other changes are made.
To build an histogram, you actually need to collect history.
Example:
int main() {
int size;
cin >> size;
int d[size];
int hist[size + 1]{}; // all zeroes - this is for the histogram
for (int i = 0; i < size; i++) { // To create array and store values in it
cin >> d[i];
}
for (int i = 0; i < size; i++) {
++hist[d[i]];
}
for(int i = 0; i < size; ++i) {
cout << "Frequency of number " << i << " is " << hist[i] << endl;
}
}
Note: VLAs (Variable Length Arrays) are not a standard C++ feature. Use std::vector instead.
A slightly different approach would be to not be limited by the size parameter when taking the input values. std::map the value to a count instead:
#include <iostream>
#include <vector>
#include <map>
int main() {
int size;
if(not (std::cin >> size) or size < 1) return 1;
std::map<int, unsigned long long> hist; // number to count map
for(int value; size-- > 0 && std::cin >> value;) {
++hist[value];
}
for(auto[value, count] : hist) {
std::cout << "Frequency of number " << value << " is " << count << '\n';
}
}

What are all of these numbers following the expected output?

I was trying to write a program to take an input and output the reverse of that input; here was my code:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int num[n];
for (int i=1; i<=n; i++)
{
cin >> num[i];
}
for (int i=n; i>=0; i--)
{
cout << num[i] << " ";
}
return 0;
}
I realized that in the second for loop, i can equal 0 and then i equals -1. However, the outputs don't really make sense. For example, an input of
6
8 1 2 6 3 9
results in
9 3 6 2 1 8 8 8
and a lot of the time it's just the array reversed but with an 8 added onto the end, but sometimes there are these types of numbers:
9
1 0 2 8 1 4 2 9 8
8 9 2 4 1 8 2 0 1 1703936
Where do these ending numbers come from? Because I don't understand what's going on, I can't generalize what the problem is, but if you have an easily-accessible IDE nearby and will copy and paste my code (assuming it's not a well-known problem and I'm making everyone laugh at my stupidity), could anyone tell me why there are these numbers added onto the end?
for (int i=1; i<=n; i++)
In C++, array indexes are 0-indexed. This means if your array is size n, the valid indexes are 0, 1, 2, ..., n-1.
Your loop will loop over 1, 2, 3, ..., n. Do you see the issue? You never write to the 0'th index, and you write one past the last index (which is not allowed).
Then when you go to print:
for (int i=n; i>=0; i--)
You print n, n-1, n-2, ..., 0. You're printing the n'th element, which is again, not allowed.
Instead, your loops should look like:
for (int i=0; i<n; i++)
{
cin >> num[i];
}
for (int i = 0; i < n; i++)
{
cout << num[n - i - 1] << " ";
}
Your second loop begins with i equal to n ... but that's not a valid array index, because an array containing n elements has indexes [0..n-1]! Therefore, you are seeing "memory garbage."
So, your second loop should be:
for (int i=n-1; i>=0; i--)
You seem to think that arrays are indexed from 1 which is your main issue.
for (int i=1; i<=n; i++)
The last element of an array if length-1, so if you had 3 elements the last index is 2, not 3; however, the loop above starts at 1 (the second element) and then accesses an index out of bounds, which is undefined behaviour.
But really you don't need to use indices at all, just for (auto& i : n) will iterate properly over your container. If you want to loop using indices, you need
for (int i = 0; i < n; i++) // forwards
for (int i = n-1; i >= 0; i--) //backwards
It's worth noting that variable length arrays (that is, arrays whose lengths are not known at compile time) are not standard C++, but are an extension of GCC. It would be worth ditching that behaviour now, and using vector instead:
int length = 0;
std::cin >> length;
std::vector<int> n(length);

Insert numbers divisible by a number into a vector

I was given the integers 15, 16, 17 ,18 ,19 and 20.
I am supposed to put only the numbers divisible by 4 into a vector and then display the values in the vector.
I know how to do the problem using arrays but I'm guessing I don't know how to properly use pushback or vectors.
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> arrmain; int i,j;
for (int i = 15; i <=20 ; i++)
{
//checking which numbers are divisible by 4
if (i%4 == 0)
{ //if number is divisible by 4 inserting them into arrmain
arrmain.push_back(i);
//output the elements in the vector
for(j=0; j<=arrmain.size(); j++)
{
cout <<arrmain[i]<< " "<<endl;
}
}
}
return 0;
}
wanted output: Numbers divisible by 4: 16, 20
As already mentioned in the comments, you have a couple of problems in your code.
All which will bite you in the end when writing more code.
A lot of them can be told to you by compiler-tools. For example by using -Weverything in clang.
To pick out the most important ones:
source.cpp:8:10: warning: declaration shadows a local variable [-Wshadow]
for (int i = 15; i <=20 ; i++)
and
source.cpp:6:26: warning: unused variable 'i' [-Wunused-variable]
vector arrmain; int i,j;
Beside those, you have a logical issue in your code:
for values to check
if value is ok
print all known correct values
This will result in: 16, 16, 20 when ran.
Instead, you want to change the scope of the printing so it doesn't print on every match.
Finally, the bug you are seeing:
for(j=0; j<=arrmain.size(); j++)
{
cout <<arrmain[i]<< " "<<endl;
}
This bug is the result of poor naming, let me rename so you see the problem:
for(innercounter=0; innercounter<=arrmain.size(); innercounter++)
{
cout <<arrmain[outercounter]<< " "<<endl;
}
Now, it should be clear that you are using the wrong variable to index the vector. This will be indexes 16 and 20, in a vector with max size of 2. As these indexes are out-of-bounds for the vector, you have undefined behavior. When using the right index, the <= also causes you to go 1 index out of the bounds of the vector use < instead.
Besides using better names for your variables, I would recommend using the range based for. This is available since C++11.
for (int value : arrmain)
{
cout << value << " "<<endl;
}
The main issues in your code are that you are (1) using the wrong variable to index your vector when printing its values, i.e. you use cout <<arrmain[i] instead of cout <<arrmain[j]; and (2) that you exceed array bounds when iterating up to j <= arrmain.size() (instead of j < arrmain.size(). Note that arrmain[arrmain.size()] exceeds the vector's bounds by one because vector indices are 0-based; an vector of size 5, for example, has valid indices ranging from 0..4, and 5 is out of bounds.
A minor issue is that you print the array's contents again and again while filling it up. You probably want to print it once after the first loop, not again and again within it.
int main()
{
vector<int> arrmain;
for (int i = 15; i <=20 ; i++)
{
//checking which numbers are divisible by 4
if (i%4 == 0)
{ //if number is divisible by 4 inserting them into arrmain
arrmain.push_back(i);
}
}
//output the elements in the vector
for(int j=0; j<arrmain.size(); j++)
{
cout <<arrmain[j]<< " "<<endl;
}
return 0;
}
Concerning the range-based for loop mentioned in the comment, note that you can iterate over the elements of a vector using the following abbreviate syntax:
// could also be written as range-based for loop:
for(auto val : arrmain) {
cout << val << " "<<endl;
}
This syntax is called a range-based for loop and is described, for example, here at cppreference.com.
After running your code, I found two bugs which are fixed in code below.
vector<int> arrmain; int i, j;
for (int i = 15; i <= 20; i++)
{
//checking which numbers are divisible by 4
if (i % 4 == 0)
{ //if number is divisible by 4 inserting them into arrmain
arrmain.push_back(i);
//output the elements in the vector
for (j = 0; j < arrmain.size(); j++) // should be < instead of <=
{
cout << arrmain[j] << " " << endl; // j instead of i
}
}
}
This code will output: 16 16 20, as you are printing elements of vector after each insert operation. You can take second loop outside to avoid doing repeated operations.
Basically, vectors are used in case of handling dynamic size change. So you can use push_back() if you want to increase the size of the vector dynamically or you can use []operator if size is already predefined.

Backtracking of 'AABC' string in C++

I'm struggling with solving this problem in C++.
I have a string: {A,A,B,C} and I want to print all possible permutations for this.
This would be 12:
AABC, AACB, ABAC, ABCA, etc...
I've written the following piece of code in which I have:
- a string which contains the letters A,A,B,C.
- a result string in which I will print each permutation when base condition of recursivity is fullfilled
- an array of integers which represent counters values for each digit: counters[3] = {2,1,1} which means there can be 2 A's, 1 B and 1C in a permutation.
- a function which should solve the problem in a recursive manner like this:
Start from initial string. From left to right of string check if counter for each character is greater than 0. If it is put the character in result[lvl] where lvl is the depth of the recursion. Then decrement the counter for that character's position. Do that for all the elements to the right of the current element and then backtrack all the way up and start with next element(second A).
The base case would be when all counters are equal to 0 print the solution then return.
Here is the code:
#include <iostream>
using namespace std;
char theString[4] = {'A','A','B','C'};
char resultString[4]={};
int counters[3] = {2,1,1};
void printPermutation()
{
for(int i=0; i<4; i++)
{
cout << resultString[i];
}
cout << endl;
}
void solvePermutations(int *counters, int lvl)
{
if(lvl == 4)
{
printPermutation();
return;
}
for(int i=0; i<4; i++)
{
if(counters[i] == 0)
{continue;}
else
{
resultString[lvl] = theString[i];
counters[i]--;
solvePermutations(counters, lvl+1);
counters[i]++;
}
}
}
int main()
{
int *ptr;
ptr = counters;
solvePermutations(ptr, 0);
return 0;
}
When I run the code I get this output instead of what I'm expecting(12 distinct permutations):
ACAB
ACBA
BAAA
BAAC
BACA
etc
More than 12 and with no logic(to me :D)
Please help me correct this and tell me what is wrong in my algorithm and help me understand it. Thank you.
You have one small logical error in your algorithm. You are using a counter[3] and a theString[4]. The idea here is that each index of counter should correspond to one letter, and hold the amount of that letter used.
With your loop you are using i<4. When i is 3 in that loop, you are trying to access counter[3] which is out of bounds. This in undefined behavior and you could be reading any int value.
To correct this, you simply need to decrease the loop to go to max 2 (i < 3) and change theString to an array of 3 elements, {'A', 'B', 'C'}.
char theString[3] = {'A','B','C'};
//...
for(int i=0; i<3; i++)

This sorting array code cause the last element dissapear

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