Can we write marks[j]=marks[i]; inside while loop instead of marks[i+1]=marks[i]; - insertion-sort

Insertion sort program in C++
#include"iostream"
using namespace std;
int main(){
int i,temp;
int marks[5]={12,11,13,5,6};
//this loop go through all element
//(staring from 2 to 5,
//assuming that first element is already sorted)
for(int j=1;j<5;j++){
i=j-1;
temp=marks[j];
while(i>=0 && marks[i]>temp){
marks[i+1]=marks[i];
i--;
}
marks[i+1]=temp;
}
//prints all the elements..
for(int z=0;z<5;z++){
cout<<marks[z]<<" ";
}
return 0;
}
can we write marks[j]=marks[i]; inside while loop instead of marks[i+1]=marks[i];
If not, why?

So the answer is no - it is not the same
Using j=2 as an example, the while loop starts with i=1
The 1st iteration, marks[i+1]=marks[i], i+1 is the same as j, but then i--, so i ends up as 0 by the end of the while loop.
for the 2nd iteration in the while loop, marks[i+1]=marks[i], i+1 is NOT the same as j.

Related

How can i erase element of VECTOR LIST in c++?

I need to erase the element of position 'k' in my code , Suppose i got the '3' in K so i wants to erase member of position 3 in vector list . What is the solution?
thanks in advance !
using namespace std ;
int main()
{
vector<double> v1;
vector <double>v2;
double a ;
for (int i=0;i<6;i++)
{
cout<<"Enter values :";
cin>>a;
v1.push_back(a);
}
cout<<endl;
for (int i=0;i<6;i++)
{
for (int k=0;k<6;k++)
{
if (v1[i]==v1[k] && i!=k && k>i)
{
cout<<"FOUND A REPEATING MEMBER IN VECTOR :"<<endl;
cout<<"repeating position: "<<k<<endl;
cout<<v1[k]<<endl;
cout<<"ERASING MEMBER AT POSITION "<<k<<endl;
v1.erase(v1[k],v1.end()); //ERROR HERE!
cout<<"DONE"<<endl;
}
}
}
}
https://en.cppreference.com/w/cpp/container/vector/erase
iterator erase( iterator pos );
Erases the specified elements from the container. 1) Removes the
element at pos.
so, assuming you are sure that k is a valid input, then do:
v1.erase(v1.begin() + k);

Hackerearth bubbleSort

In Hackerearth i tried solving bubble sort swap counting. and my output always different from correct output.for example;
my output is 2475 and correct output is 2788
#include <iostream>
using namespace std;
int main()
{
int *A,tm,times=0;
cin >> tm;
A = new int[tm];
for(int i = 0; i<tm;i++) {cin >> A[i];}
int temp;
for(int i = 0; i<tm;i++){
for(int j = 0; j < tm-i-1;j++){
if(A[j] > A[j+1]){
times++;;
temp = A[j];
A[j] = A[j+1];
A[j] = temp;
}
}
}
cout << times;
return 0;
}
Am i doing something wrong or correct outputs are wrong?
In the swap logic, in place of
A[j]=temp;
write
A[j+1]=temp;
In the outer for loop, i<tm-1 instead of i<tm
May be this is irrelevant, but it is possible to find the number of inversion with a better complexity. This solution will require O(n^2). It can be done in O(nlogn) time complexity. The idea is to use merge sort and at merging state you already know how many values are greater/smaller from a value without actually counting them. While merging, if a value of right subarray is greater, then all other values right of it are also greater. You just need to count how many values are at right. A detailed and pleasant explanation is provided here.
Number of swaps performed by Bubble-Sort on a given array
http://www.geeksforgeeks.org/counting-inversions/

find permutation of an array with duplicates. Why pass by value in recursion (C++ implementation)

There are different ways to find all permutation of an integer array with duplicates. Here I only talk about the recursive method without using an additional "visited[]" array.
There correct way to do it is:
void helper(vector<vector<int>>& ans, vector<int> nums, int pos) {
if(pos == nums.size()-1) {
ans.push_back(nums);
return;
}
for(int i = pos; i < nums.size(); i++) {
if(i == pos || nums[i] != nums[pos]) {
swap(nums[i], nums[pos]);
helper(ans, nums, pos+1);
}
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> ans;
sort(nums.begin(), nums.end());
helper(ans, nums, 0);
return ans;
}
It is not so clear to me why it passes nums[] as a copy into the recursive function. So I looked around and on geeks for geeks , it says that "The idea is to fix the first character at first index and recursively call for other subsequent indexes". I was thinking that I can fix the first character then recursively call for the other subsequent indexes by passing nums[] as reference and "swap back" when recursion is done (as below). But unfortunately it did not work.
void helper(vector<vector<int>>& ans, vector<int>& nums, int pos) {
if(pos == nums.size()-1) {
ans.push_back(nums);
return;
}
for(int i = pos; i < nums.size(); i++) {
if(i == pos || nums[i] != nums[i-1]) {
swap(nums[i], nums[pos]);
helper(ans, nums, pos+1);
swap(nums[i], nums[pos]);
}
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> ans;
sort(nums.begin(), nums.end());
helper(ans, nums, 0);
return ans;
}
I am wondering what is wrong when passing nums[] as reference into recursion? Why passing nums[] by copy into recursion is correct?
I think I found the reason. Passing by value and passing by reference give two totally different algorithms. To understand that. Let's first note two important observations:
The first thing we did is to sort the array, why? because we want that all the permutations are visited in the "next permutation" order, i.e. 123, 132, 213, 231, 312, 321. So that there will be no duplicates.
The subproblem in the next recursion also maintained the sorted property. Let's use an example to illustrate this.
Input nums = [1,2,2,3] passing by value to recursion, with pos = 0,
i = 0: subproblem is [2,2,3],
i = 1: subproblem is [1,2,3],
i = 2: skipped,
i = 3 subproblem is [1,2,2].
All the subproblems in this level of recursion are all SORTED.
But if [1,2,2,3] is passed by reference, the subproblems are NOT sorted, so you can not reply on "next permutation" method to give you non-duplicated permutations.
If you are still confused, please take some time to read through this discussion:
https://discuss.leetcode.com/topic/8831/a-simple-c-solution-in-only-20-lines/28?page=2

n nested for loops in a method with n as input

I have a function, and one of the inputs is the number of for loops that I need to do. In other words, the function is:
double MethodName(otherinputs, int numberofForLoops)
The number of for loops, however, is the number of nested forloops. In other words, if numberofForLoops = 3, then I would run
for(int i blah blah blah)
{
for(int j blah blah blah)
{
for(int k blah blah blah)
{ actual function }
}
}
How would I structure the method?
There is no way to do that directly. What you can do is use recursion, and make a single recursive call for each loop that you need (and have one loop in the method)
So if your actual function does not depend on i, j, k, you can substitute your n loops with just one.
for(int j blah^n){
actual function
}
The number of times it will be executed is the same as the number of times n nested loops will be executed.
The algorithm is very much like incrementing a Very Long Number (in a varied base BTW).
Since you have an undetermined amount of loops, you need to pass their count along with their limits:
ret_type do_loops(int numberOfForLoops, int limits[])
The do_loops function shall keep the current state in the similar array:
ret_type do_loops(int numberOfForLoops, int limits[]) {
int indices[numberOfForLoops] = { 0 };
and always try to increment the lowest possible dimension:
ret_type do_loops(int numberOfForLoops, int limits[]) {
int indices[numberOfForLoops] = { 0 };
int index = 0;
while (1) {
// Call with current index configuration
call_target_function(numberOfForLoops, indices);
// Increment current loop. If it overflows, propagate the carry
indices[index] += 1;
while (index < numberOfForLoops && indices[index] == limits[index]) {
indices[index] = 0;
index += 1;
}
// If the highest dimension overflown, you are done
if (index == numberOfForLoops) {
return ...;
}
// If some dimension successfully incremented, all dimensions below it were reset to 0
index = 0;
}

My code for merge sort in C++ using dynamic arrays returning garbage values

Please tell me why this code is giving garbage values
Compiles well, implemented this based on the Cormen algorithm for mergesorting
Basically taking given numbers in a dynamic array. two void functions are taken.One is to merge the two sub arrays via merge sort and the other to recursively split the array to sub arrays
#include<iostream>
using namespace std;
void merge(int *A,int p, int q, int r)// a function to merge two //sub arrays
{
int n1= q-p+1;
int n2=r-q;
int L[n1];
int R[n2];
for (int i=0;i<n1;i++)
{
L[i]=A[p+i];
}
int m=1;
for(int j=0; j<n2 ;j++)
{
R[j]=A[q+m];
m=m+1;
}
int i=0;
int j=0;
for(int k=0;k<r;k++)
{
if (L[i]<=R[j])
{
A[k]=L[i];
i=i+1;
}
else
{
A[k]=R[j];
j=j+1;
}
}
}
void mergesort(int *A,int p,int r)// dividng the sequence to sub arrays
{
if (p<r)
{
int q;
q=(p+r)/2;
mergesort(A,p,q);
mergesort(A,(q+1),r);
merge(A,p,q,r);
}
}
int main()
{
int n;
cout<<"Enter the number of numbers to be sorted by merge sort"<<endl;
cin>>n;
int* a=NULL;
a=new int[n];
int temp;
cout<<"Enter the numbers"<<endl;
for(int i=0;i<n;i++)
{
cin>>temp;
*(a+i)=temp;// inputting the given numbers into a dynamic array
}
cout<<"The given numbers are:"<<endl;
for(int j=0;j<n;j++)
cout<<*(a+j)<<" ";
mergesort(a,0,n-1);
cout<<"The merged sorted numbers are:"<<endl;
for(int s=0;s<n;s++)
cout<<*(a+s)<<" ";
delete [] a;
system("pause");
return 0;
}
You are getting your intervals wrong pretty much everywhere in your code. For example:
Based on your usage in main, mergesort is supposed to sort the sublist of indices [0,n-1].
With this meaning, your recursion in mergesort says in order to sort the indices [p,r-1], you should first sort [p,q-1] then sort [q+1,r-1]: you completely ignore index q.
Similarly, merge is confused: once you fix the typo when coping into L (A[i] should be A[p+i]), it takes [p,q] as one list, and [q,r] as the other list: note you copy entry q twice, and you also copy r when you probably shouldn't be.
To fix your code, you need to straighten out exactly what intervals everything is supposed to be working on. This isn't a hard problem, you just have to bring yourself to write down explicitly exactly what all of your functions and loops and stuff are supposed to be doing.
The typical convention these days is half-open intervals: you should generally think of taking indices [p,q) from a list. ([p,q) is the same as [p,q-1]) Here are several examples of why this is preferred:
The number of entries of [p,r) is simply r-p
A for loop iterating through [p,r) is the usual for(i=p; i<r; ++i) (not <=)
Splitting the interval [p,r) into parts gives you intervals [p,q) and [q,r) -- there is no worry about remembering to add 1 in places.
e.g. merge would normally be designed to take the first list comes from indices [p,q) and the second list from indices [q,r).

Resources