Insertion Sort Printing Wrong Output - c++

I am trying to sort an array using the code below:-
The expected output should be an array which is sorted in ascending order.
But when i tried to run this code the output comes out to be 59 (6 times)
I have tried debugging it added a watch at first array declaration and added a breakpoint on the first for loop it gives out the error to be :-
->->error-begin
A syntax error in expression, near `A[6]={31,41,59,26,41,58}'.
#include<iostream>
using namespace std;
int main()
{
int A[6]={31,41,59,26,41,58};;
int j;
int length = 6;
for(j=2;j<length;j++)
{
int key;
key = A[j];
int i;
i=j-1;
while(i>0 && A[i]>key)
{
A[i+1]=A[i];
i=i-1;
}
A[i+1]=key;
cout<<A[j];
}
return 0;
}
Update:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int A[6] = { 31, 41, 59, 26, 41, 58 };
int temp;
int j;
int length = 6;
for (j = 2; j < length; j++) {
int key;
key = A[j];
int i;
i = j - 1;
while (i > 0 && A[i] > key) {
temp = A[i + 1];
A[i + 1] = A[i];
A[i] = temp;
i = i - 1;
}
A[i + 1] = key;
}
cout << A[j];
return 0;
}
It's working is supposed to be like a bubble sort I do know about
std::sort(std::begin(A), std::end(A));
But I am curious why this code isn't working, I have already tried looking up wiki and other sites for similar code but i can't seem to find anything relevant.

Replace:
while(i>0 && A[i]>key)
by:
while (i >= 0 && A[i] > key)//notice the equality sign!
It was just checking till the 1st index while the zeroth index was not touched
And you might want to print the contents of the array like this:
for(int i=0;i<6;i++)
cout << A[i]<<" ";

For starters this loop
for (j = 2; j < length; j++) {
^^^^^
has an incorrect initial setting. It will not sort an array that has only two elements or the second element will be never swapped with the first element if the second element is less than the first element.
It would be correctly to write the statement like
for (j = 1; j < length; j++) {
^^^^^
The inner loop
while (i > 0 && A[i] > key) {
does not touch the element A[0] due to the condition i > 0, Thus the subcondition A[0] > key will be never checked.
It is better instead of swapping each pair of elements that satisfy the condition just to copy elements and then to write the "added" element in the required position.
The program can look the following way.
#include <iostream>
int main()
{
int a[] = { 31, 41, 59, 26, 41, 58 };
const size_t N = sizeof(a) / sizeof(*a);
for (int x : a) std::cout << x << ' ';
std::cout << std::endl;
for (size_t i = 1; i < N; i++)
{
int value = a[i];
size_t j = i;
for (; j != 0 && value < a[j - 1]; --j)
{
a[j] = a[j - 1];
}
if (j != i) a[j] = value;
}
for (int x : a) std::cout << x << ' ';
std::cout << std::endl;
return 0;
}
The program output is
31 41 59 26 41 58
26 31 41 41 58 59

Related

Is what I'm doing an Insertion sort, I think the logic is correct but unconventional?

This code is supposed to be an Insertion sort but is it implemented as such? I'm lost. The first loop goes through the array and checks if the next element is smaller than the current element. The nested loop inserts the next element(j) correctly in its place in the sorted portion of the array.
#include <iostream>
using namespace std;
// Print array
void printArray(int array[], int arraySize)
{
for (int i = 0; i < arraySize; i++)
{
cout << array[i] << " ";
}
cout << endl;
}
int main()
{
int array1[] ={5, 3, 1, 9, 8, 2, 4, 7};
int array1Size = sizeof(array1)/sizeof(int);
printArray(array1, array1Size);
for (int i = 0; i < array1Size - 1; i++)
{
int oldNum = array1[i];
if (array1[i] > array1[i + 1])
{
array1[i] = array1[i + 1];
array1[i + 1] = oldNum;
}
int newI = array1[i];
// Check if arranged correctly
if ( i > 0)
{
// Swap bigger number and newI
for (int j = i - 1; newI < array1[j]; j--)
{
if (j < 0)
{
break;
}
array1[j + 1] = array1[j];
array1[j] = newI;
}
}
printArray(array1, array1Size);
}
return 0;
}
The key to insertion sort is to maintain a "sorted zone" and expand it in loop. In the beginning the zone is only one element, and finally it's all the list. We take an element outside the sorted zone and decide which position in sorted zone that it should be placed in.
BTW, loop invariant is easy to understand but powerful and awesome. Recommended.
int main() {
int array1[] ={5, 3, 1, 9, 8, 2, 4, 7};
int array1Size = sizeof(array1)/sizeof(int);
// loop invariant: array1[0..i-1] is sorted
// array1[i] is the element to be inserted
for (size_t i = 1; i < array1Size; i++) {
int temp = array1[i];
// find the right place to insert array1[i]. Can be replaced by binary search(but moving elements is more expensive than comparing)
size_t j = i; // j is used to save the right place
for (; j > 0 && array1[j-1] > temp; j--) {
array1[j] = array1[j-1];
}
array1[j] = temp;
}
return 0;
}
This for loop
for (int j = i - 1; newI < array1[j]; j--)
{
if (j < 0)
{
break;
}
array1[j + 1] = array1[j];
array1[j] = newI;
}
can invoke undefined behavior when j is equal to -1 due to this expression in the condition of the for loop
newI < array1[j]
And the code is too complicated. For example this code snippet
if (array1[i] > array1[i + 1])
{
array1[i] = array1[i + 1];
array1[i + 1] = oldNum;
}
where two elements are swapped is redundant. And this if statement
if ( i > 0)
{
also is redundant. It is enough to start the outer loop from 1 instead of from 0.
It is better to define a separate function. It can look for example the following way
void InsertionSort( int a[], size_t n )
{
for (size_t i = 1; i < n; i++)
{
if (a[i] < a[i - 1])
{
int tmp = a[i];
size_t j = i;
for ( ; j != 0 && tmp < a[j - 1]; --j )
{
a[j] = a[j - 1];
}
a[j] = tmp;
}
}
}
Pay attention to that the operator sizeof yields a value of the type size_t. You should use this type size_t for the variable that will be store the number of elements in the array. In general the type int is not large enough to store sizes of arrays.
If your compiler supports C++ 17 then instead of using the expression with the sizeof operator
int array1Size = sizeof(array1)/sizeof(int);
you could write at least
#include <iterator>
//...
int array1Size = std::size( array1 );
Also as the function printArray does not change the passed array then it first parameter should be declared with the qualifier const.
void printArray(const int array[], int arraySize);
Here is a demonstration program that shows usage of a separate function that sorts arrays using the insertion sort method..
#include <iostream>
#include <iterator>
void InsertionSort( int a[], size_t n )
{
for (size_t i = 1; i < n; i++)
{
if (a[i] < a[i - 1])
{
int tmp = a[i];
size_t j = i;
for ( ; j != 0 && tmp < a[j - 1]; --j )
{
a[j] = a[j - 1];
}
a[j] = tmp;
}
}
}
int main()
{
int array1[] ={5, 3, 1, 9, 8, 2, 4, 7};
for ( const auto &item : array1 )
{
std::cout << item << ' ';
}
std::cout << '\n';
InsertionSort( array1, std::size( array1 ) );
for ( const auto &item : array1 )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
The program output is
5 3 1 9 8 2 4 7
1 2 3 4 5 7 8 9

Print all the substrings with equal number of zeros and ones, But am not able to

I want to print all the substrings to be printed and everysubstring should have equal number of zeros and ones.I have strated the loop where i points to the index and initially number of zeros and one is equal to 0 and loop runs till both of them becomes equal and i push that in the vector. But My code is not running good . I am given enough time to figure out what could be the error but am not able to find.
Output
0 1 0 0 1 1 0 1 0 1
Expected Output
01 0011 01 01
I am not able figure out the error , Please help me with this.
#include <iostream>
#include <vector>
using namespace std;
vector<string> maxSubStr(string s, int n)
{
vector<string> v;
for (int i = 0; i < n; i++)
{
int ones = 0;
int zeros = 0;
int j = 0;
for (j = i; zeros != ones && j<n; j++)
{
if (s[j] == '0')
{
zeros++;
}
else
{
ones++;
}
}
if (zeros == ones)
{
int size = j - i;
v.push_back(s.substr(i, size));
}
if(j==n){
break;
}
i = j ;
}
return v;
}
int main()
{
string str = "0100110101";
int n = str.length();
vector<string> v;
v = maxSubStr(str, n);
vector<string>::iterator it;
for (it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
return 0;
}
There are a number of little mistakes in your code. You should learn to use a debugger to step through it, the errors would become evident.
In the loop over i it is useless to set the value of j just before setting in again in the loop over j.Then, the loop should be limited by j<n to prevent an access past end of string. Next, you do not want to test s[i] but s[j]. Finally, the test zeros == ones should be in the j loop and should set i to the next position, that is j + 1. Code could become:
vector<string> maxSubStr(string s)
{
vector<string> v;
int n = s.size();
for (int i = 0; i < n; i++)
{
int ones = 0;
int zeros = 0;
int j = 0;
for (j = i; j < n; j++)
{
if (s[j] == '0')
{
zeros++;
}
else
{
ones++;
}
if (zeros == ones)
{
v.push_back(s.substr(i, j + 1 - i));
i = j;
break;
}
}
}
return v;
}

Generating all R-digit numbers among N digits in C++ (combinations, iterative)?

I have a program, where I have to generate all R-digit numbers among N digits in C++, for example for N=3 (all digits from 1 to N inclusive) and R=2 the program should generate 12 13 21 23 31 32. I tried to do this with arrays as follows, but it does not seem to work correctly.
#define nmax 20
#include <iostream>
using namespace std;
int n, r;
void print(int[]);
int main()
{
cin >> n;
cin >> r;
int a[nmax];
int b[nmax];
int used[nmax];
for (int p = 1; p <= n; p++) {
//Filling the a[] array with numbers from 1 to n
a[p] = n;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < r; j++) {
b[j] = a[i];
used[j] = 1;
if (used[j]) {
b[j] = a[i + 1];
}
used[j] = 0;
}
print(b);
}
return 0;
}
void print(int k[]) {
for (int i = 0; i < r; i++) {
cout << k[i];
}
}
If I understand your question correctly, you can explore this website where it explains the problem and suggests the solution thoroughly.
Here is a slightly altered code:
Pay attention that time is an issue for bigger N values.
#define N 5 // number of elements to permute. Let N > 2
#include <iostream>
using namespace std;
// NOTICE: Original Copyright 1991-2010, Phillip Paul Fuchs
void PrintPerm(unsigned int *a, unsigned int j, unsigned int i){
for(unsigned int x = 0; x < N; x++)
cout << " " << a[x];
cout << " swapped( " << j << " , " << i << " )\n";
}
void QuickPerm(void){
unsigned int a[N], p[N+1];
register unsigned int i, j, PermCounter = 1; // Upper Index i; Lower Index j
for(i = 0; i < N; i++){ // initialize arrays; a[N] can be any type
a[i] = i + 1; // a[i] value is not revealed and can be arbitrary
p[i] = i;
}
p[N] = N; // p[N] > 0 controls iteration and the index boundary for i
PrintPerm(a, 0, 0); // remove comment to PrintPerm array a[]
i = 1; // setup first swap points to be 1 and 0 respectively (i & j)
while(i < N){
p[i]--; // decrease index "weight" for i by one
j = i % 2 * p[i]; // IF i is odd then j = p[i] otherwise j = 0
swap(a[i], a[j]); // swap(a[j], a[i])
PrintPerm(a, j, i); // remove comment to PrintPerm target array a[]
PermCounter++;
i = 1; // reset index i to 1 (assumed)
while (!p[i]) { // while (p[i] == 0)
p[i] = i; // reset p[i] zero value
i++; // set new index value for i (increase by one)
} // while(!p[i])
} // while(i < N)
cout << "\n\n ---> " << PermCounter << " permutations. \n\n\n";
} // QuickPerm()
int main(){
QuickPerm();
} //main
Here is a list of the modified items from the original code.
N defined to be 5 instead of 12.
A Counter has been added for more informative result.
The original swap instructions reduced by using c++ standard libraries' swap() function.
The getch() has been removed.
The 'Display()' function has been renamed to be 'PrintPerm()'.
The printf() function has been replaced by cout.
Printing number of permutation has been added.

Why is my insertion sort not getting the first element?

My insertion sort sorts every number but the first number. It sorts from the second element to the last element, but it never includes the first element. What is wrong with my insertion sort. I based this code off the pseudocode of the book CLRS and I cannot debug what is wrong with it.
#include <iostream>
void InsertSort(int data[], int length)
{
//std::cout<<length<<std::endl;
for(int j = 1; j < length; j++)
{
int key = data[j];
int i = j - 1;
while(i > 0 && data[i] > key)
{
data[i + 1] = data[i];
i--;
}
data[i+1] = key;
}
for(int x = 0; x < length; x++)
{
std::cout<<data[x]<<" ";
}
std::cout<<std::endl;
}
int main(int argc, const char * argv[])
{
// insert code here...
//std::cout << "Hello, World!\n";
int foo [] = { 18, 2, 77, 0, 12071 , 21, 45, 98, 54, 80};
InsertSort(foo, 10);
return 0;
}
Here is my output: 18 0 2 21 45 54 77 80 98 12071
here is the pseudocode i received from the book
for j = 2 to A.length
key - A[j]
//Insert A[j] into the sorted sequence A[1.. j - 1]
i = j -1
while i > 0 and A[i] > key
A[i+1] = A[i]
i = i -1
A[i+1] = key
If there are copy right issues, I will take down the pseudocode.
As you can see my first element is not sorted and for some reason is never sorted. What is wrong with my code?
Change the while loop to
while(i >= 0 && data[i] > key)
Here is the updated code:
#include <iostream>
void InsertSort(int data[], int length)
{
//std::cout<<length<<std::endl;
for(int j = 1; j < length; j++)
{
int key = data[j];
int i = j - 1;
while(i >= 0 && data[i] > key)
{
data[i + 1] = data[i];
i--;
}
data[i+1] = key;
}
for(int x = 0; x < length; x++)
{
std::cout<<data[x]<<" ";
}
std::cout<<std::endl;
}
int main(int argc, const char * argv[])
{
// insert code here...
//std::cout << "Hello, World!\n";
int foo [] = { 18, 2, 77, 0, 12071 , 21, 45, 98, 54, 80};
InsertSort(foo, 10);
return 0;
}

arranging array in ascending order

I'm trying to arrange a random array. In the code it's just the first step of swapping places by size.
When running the code a get Debug Error and the output after the swap shows that the first number in the array was deleted and the last is a long random number that was in the memory.
It looks like it starts the swapping from i=1, why?
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
void buildArray(int arr[], int size) {
srand ( (unsigned int)time(NULL) );
for(int i = 0; i < size; ++i)
arr[i] = rand() % 50 + 0;
}
void dispArray(int arr[], int size) {
for(int i = 0; i < size; ++i)
cout << i << ": " << arr[i] << endl;
}
int main()
{
const int size = 5;
int arr[size];
buildArray(arr, size);
dispArray(arr, size);
int swapHolder = -1;
for(int i = 0; i < size; ++i) {
if(arr[i] > arr[i+1]) {
swapHolder = arr[i+1];
arr[i+1] = arr[i];
arr[i] = swapHolder;
cout << endl;
}
}
dispArray(arr, size);
return 0;
}
Output example:
0: 46
1: 15
2: 47
3: 5
4: 19
0: 15
1: 46
2: 5
3: 19
4: -858993460
Here is the problem: if(arr[i] > arr[i+1]), your for loop goes from [0, size - 1], so on the last iteration, lets say size = 5, you would be testing if(arr[5] > arr[6]), accessing the uninitialized arr[6], the right way is to make your for loop go from [0, size - 2]:
for(int i = 0; i < size - 1; ++i) ...
for(int i = 0; i < size; ++i) {
if(arr[i] > arr[i+1]) {
swapHolder = arr[i+1];
arr[i+1] = arr[i];
The last iteration is for i = size -1. Then
if(arr[i] > arr[i+1])
means accessing array out of range. This is undefined behavior.