C++ insertion sort - c++

I have this function called WordSort(worddata W [], int count) that is fed two variables
1 - worddata is the array holding information on a given word in a file. count is just the counter variable to see which word in the array we are looking at.
the words.txt file that is read into this program would just be a string of words.
this is a list of words
there are letters and numbers
23 people recommend this program.
Heres the function:
void WordSort (worddata W [], int count)
{
for (int i=1; i < count; i++)
{
for (int j=i; j > 0 && W[j-1].word > W[j].word; j--)
{
Swap(W[j], W[j-1]);
}
}
}
The swap function is suppose to swap every element with the one before it as long as j > 0 or the list is over. Im confused on how to complete the swap function, here's the example i was given.
void Swap (worddata & a, worddata & b)
{
int += a;
a = b;
b =+;
}
Swap is suppose to swap every element with the one before it
I think the WordSort function works fine, the only thing missing is the Swap function. Could anyone point me in the right direction or explain insertion sorting better to me?

void insertion_sort()
{
/* Algorithm : Insertion Sort
* Coded by .
*/
int num;
/*
* Asking the User no of Integers he/she wants to enter
*/
cout << "Enter no of integers u want to enter: ";
cin >> num;
/* Creating an Array to store the integers*/
int s[num];
/*Taking Integers from the User */
for(int i = 0 ; i < num ; i++)
{
cout << "Integer " << i+1 << " is : ";
int x;
cin >> x;
s[i] = x;
}
/* The Magic of INSERTION SORT */
for(int j = 1 ; j <= (num-1) ; j++)
{
int key = s[j];
int k = j-1;
while(k >=0 && key <= s[k])
{
s[k+1] = s[k];
k = k - 1;
}
s[k+1]=key;
}
/*Printing Out the Sorted List */
cout << "The Sorted List is \n\n";
for(int i = 0 ; i < num ; i++)
{
cout << s[i] << " ";
}
}

Use standard library std::swap instead. In your loop:
for (...)
{
std:swap(W[j], W[j-1]);
}
std::swap requires worddata class to have a copy constructor and an assignment operator defined explicitly or implicitly.

Swap should look like this -- I have no idea how your example is even close.
void Swap (worddata & a, worddata & b)
{
worddata temp = a;
a = b;
b = temp;
}

Insertion sort using "for loop" (2 iterations)
#include<iostream>
using namespace std;
int insertion(int arr[], int size_arr)
{
int i,j,n, temp;
for(i=1;i<size_arr; i++){
j=i-1;
temp = arr[i];
for (j; j >= 0; j--)
{
if(arr[j] > temp){
arr[j+1] = arr[j];
arr[j] = temp;
}
}
arr[j] = temp;
}
for(i=0;i<size_arr;i++){
cout<<arr[i]<<endl;
}
return 0;
}
int main(){
int arr[] = {3,38,1,44,66,23,105,90,4,6};
int size_arr = sizeof(arr) / sizeof(arr[0]);
insertion(arr,size_arr);
return 0;
}

Related

Trying to make a simple Array sorter with input numbers

I'm very new to C++ or even coding. I was trying to make a simple array sorter, where the I first input the number of elements that will be in the array and then input the elements. My outcome should be the array sorted in ascending order. I have not thought about the case if elements inserted are same. So I would love to get some help from you folks.
The main error that I'm facing is that only the first unsorted element is sorted while the rest are either interchanged or left the same.
int main(){
int x;
cout<<"Enter no. of elements"<<endl;
cin>>x;
int A[x];
for (int i = 0;i<x;i++){
cin>>A[i];
}
for(int i=0;i<x;i++)
cout<<A[i]<<",";
int count=0;
if(count <= (x-1)){
for (int i=0;i<(x-1);i++){
if(A[i]>A[i+1]){
int a;
a = A[i];
A[i] = A[(i+1)];
A[i+1] = a;
}
else if(A[i]<A[i+1])
count++;
}
}
cout<<"Sorted array:";
for(int i=0;i<x;i++)
cout<<A[i]<<",";
return 0;
}
You declared a variable length array
int x;
cout<<"Enter no. of elements"<<endl;
cin>>x;
int A[x];
because its size is not a compile-time constant.
However variable length arrays are not a standard C++ feature though some compilers have their own language extensions that support variable length arrays,
It is better to use the class template std::vector.
Another problem is that it seems you are trying to use the bubble sort method to sort the array. But this method requires two loops.
Here is a demonstration program that shows how the bubble sort algorithm can be implemented.
#include <iostream>
int main()
{
int a[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
const size_t N = sizeof( a ) / sizeof( *a );
for (const auto &item : a)
{
std::cout << item << ' ';
}
std::cout << '\n';
for (size_t last = N, sorted = N; not ( last < 2 ); last = sorted)
{
for (size_t i = sorted = 1; i < last; i++)
{
if (a[i] < a[i - 1])
{
// std::swap( a[i-1], a[i] );
int tmp = a[i - 1];
a[i - 1] = a[i];
a[i] = tmp;
sorted = i;
}
}
}
for (const auto &item : a)
{
std::cout << item << ' ';
}
std::cout << '\n';
}
The program output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
Let us try the following method:
find the largest element in the array and move it to the end, by swapping with the last element;
repeat with the array but the last element, and so on.
To find the largest element in A[0..m-1], scan the array and keep an index to the largest so far, let l. This index can be initialized to 0.
// Move the largest to the end
int l= 0;
for (int i= 1; i < m; i++)
{
if (A[i] > A[l]) l= i;
}
// A[l] is the largest in A[0..m-1]
Swap(A[l], A[m-1]);
// A[m-1] is the largest in A[0..m-1]
To sort, repeat with decreasing m. You can stop when the subarray just holds one element:
// Sort
for (int m= n-1; m > 1; m--)
{
// Move the largest to the end
....
}
Writing the Swap operation and assembling the whole code is your task. Also check
correctness of the Move for the limit cases m= 0, 1, 2.
correctness of the Sort for the limit cases n= 1, 2, 3.
how you could instrument the code to verify that the Move does its job.
how you could instrument the code to verify that the Sort does its job.
what happens in case of equal keys.
Your code can be fixed a bit to make it working.
Just replace if (count <= (x - 1)) with while (count < (x - 1)) and also set count = 0; at start of loop, plus replace else if (A[i] < A[i + 1]) with just else. And your code becomes working!
Necessary fixes I did in code below. Also I did formatting (indents and spaces) to make code looks nicer. Rest remains same.
As I see you have a kind of Bubble Sort.
Try it online!
#include <iostream>
using namespace std;
int main() {
int x;
cout << "Enter no. of elements" << endl;
cin >> x;
int A[x];
for (int i = 0; i < x; i++) {
cin >> A[i];
}
for (int i = 0; i < x; i++)
cout << A[i] << ",";
int count = 0;
while (count < (x - 1)) {
count = 0;
for (int i = 0; i < (x - 1); i++) {
if (A[i] > A[i + 1]) {
int a;
a = A[i];
A[i] = A[(i + 1)];
A[i + 1] = a;
} else
count++;
}
}
cout << "Sorted array:";
for (int i = 0; i < x; i++)
cout << A[i] << ",";
return 0;
}
Input:
10
7 3 5 9 1 8 6 0 2 4
Output:
7,3,5,9,1,8,6,0,2,4,Sorted array:0,1,2,3,4,5,6,7,8,9,
If you are taking the size of array as input from user you have to create your array dynamically in c++ like
int *array=new int(x)
and after taking the inputs of the elements just run a nested loop from 0 to size and
the inner loop from 0 to size-1 and check if(A[i]>A[i+1]) if true then swap the values else continue

Insertion Sort on a String Array

I am having trouble applying the insertion sort algorithm to the string because it. I have been getting various errors which I think are from issues regarding strings vs char types.
Ex:
candidate template ignored: could not match 'stack' against 'basic_string'
operator> (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
The insertion sort algorithm was pulled from geeks for geeks but I just changed it to string array.
void insertionSort(string arr[], int n)
{
int i, key, j, unsortedness;
for (i = 1; i < n; i++)
{
key = arr[i];
j = i - 1;
/* Move elements of arr[0..i-1], that are
greater than key, to one position ahead
of their current position */
while (j >= 0 && arr[j] > key)
{
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}
int main()
{
//Read in from file stuff missing to save space
int d, lengthStrings, numberStrings; // D will hold the number of data sets
infile >> d;
cout << d << endl;
while (d != 0)
{
infile >> lengthStrings;
infile >> numberStrings;
int numCopy = numberStrings;
int i = 0;
string arrayDna[numberStrings]; //char arrayDna[numberStrings][lengthStrings] instead?;
while (numberStrings != 0)
{
infile >> arrayDna[i];
i++;
numberStrings--;
}
insertionSort(arrayDna[], numCopy);
for (int i = 0; i < numCopy; i++)
cout << arrayDna[i] << "\n";
d--;
So basically I need help fixing the error not allowing me to apply this insertion algorithm to my own string array.
I didn't work on the logic, but cleared all the basic errors, hopefully:)
changes:
(1) arrayDna[] => arrayDna (in the parameters) while invoking insertionSort function.
(2) In the insertionSort function at line : key = arr[i],
key is an int type but needed string type, so changed type of key to string from int
void insertionSort(string arr[], int n)
{
int i,j, unsortedness;
string key;
for (i = 1; i < n; i++)
{
key = arr[i];
j = i - 1;
/* Move elements of arr[0..i-1], that are
greater than key, to one position ahead
of their current position */
while (j >= 0 && arr[j] > key)
{
arr[j + 1] = arr[j];
j = j - 1;
// Since I just need to find unsortedness and not actually sort
//I should probably just replace the two lines with something such as
//unsortedness++ and compare that way
}
arr[j + 1] = key;
}
}
int main(){
//Read in from file stuff missing to save space
int d,lengthStrings, numberStrings; // D will hold the number of data sets
infile >> d;
cout << d << endl;
while(d !=0){
infile >> lengthStrings;
infile >> numberStrings;
int numCopy=numberStrings;
int i=0;
string arrayDna [numberStrings]; //char arrayDna[numberStrings][lengthStrings] instead?;
while(numberStrings != 0){
infile >> arrayDna[i];
i++;
numberStrings--;
}
insertionSort(arrayDna, numCopy);
for (int i = 0; i < numCopy; i++)
cout << arrayDna[i] << "\n";
d--;
}
}

Generate numbers from 2 to 10,000. The numbers printed can only be a multiple of 2 prime numbers

Homework: I'm just stumped as hell. I have algorithms set up, but I have no idea how to code this
Just to be clear you do not need arrays or to pass variables by reference.
The purpose of the project is to take a problem apart and using Top-Down_Design or scratch pad method develop the algorithm.
Problem:
Examine the numbers from 2 to 10000. Output the number if it is a Dual_Prime.
I will call a DualPrime a number that is the product of two primes. Ad where the two primes are not equal . So 9 is not a dual prime. 15 is ( 3 * 5 ) .
The output has 10 numbers on each line.
My Algorithm set-up
Step 1: find prime numbers.:
bool Prime_Number(int number)
{
for (int i = 2; i <= sqrt(number); i++)
{
if (number % 1 == 0)
return false;
}
return true;
}
Step 2: store prime numbers in a array
Step 3: Multiply each array to each other
void Multiply_Prime_Numbers(int Array[], int Size)
{
for (int j = 0; j < Size- 1; j++)
{
Dual_Prime[] = Arr[j] * Arr[j + 1]
}
}
Step 4: Bubble sort
void Bubble_Sort(int Array[], int Size) // Sends largest number to the right
{
for (int i = Size - 1; i > 0; i--)
for (int j = 0; j < i; j++)
if (Array[j] > Array[j + 1])
{
int Temp = Array[j + 1];
Array[j + 1] = Array[j];
Array[j] = Temp;
}
}
Step 5: Display New Array by rows of 10
void Print_Array(int Array[], int Size)
{
for (int i = 0; i < Size; i++)
{
cout << Dual_Prime[i] << (((j % 10) == 9) ? '\n' : '\t');
}
cout << endl;
}
I haven't learned dynamic arrays yet,
Although dynamic arrays and the sieve of Eratosthenes are more preferable, I tried to write minimally fixed version of your code.
First, we define following global variables which are used in your original implementation of Multiply_Prime_Numbers.
(Please check this post.)
constexpr int DP_Size_Max = 10000;
int DP_Size = 0;
int Dual_Prime[DP_Size_Max];
Next we fix Prime_Number as follows.
The condition number%1==0 in the original code is not appropriate:
bool Prime_Number(int number)
{
if(number<=1){
return false;
}
for (int i = 2; i*i <= number; i++)
{
if (number % i == 0)
return false;
}
return true;
}
In addition, Multiply_Prime_Numbers should be implemented by double for-loops as follows:
void Multiply_Prime_Numbers(int Array[], int Size)
{
for (int i = 0; i < Size; ++i)
{
for (int j = i+1; j < Size; ++j)
{
Dual_Prime[DP_Size] = Array[i]*Array[j];
if(Dual_Prime[DP_Size] >= DP_Size_Max){
return;
}
++DP_Size;
}
}
}
Then these functions work as follows.
Here's a DEMO of this minimally fixed version.
int main()
{
int prime_numbers[DP_Size_Max];
int size = 0;
for(int j=2; j<DP_Size_Max; ++j)
{
if(Prime_Number(j)){
prime_numbers[size]=j;
++size;
}
}
Multiply_Prime_Numbers(prime_numbers, size);
Bubble_Sort(Dual_Prime, DP_Size);
for(int i=0; i<DP_Size;++i){
std::cout << Dual_Prime[i] << (((i % 10) == 9) ? '\n' : '\t');;
}
std::cout << std::endl;
return 0;
}
The Sieve of Eratosthenes is a known algorithm which speeds up the search of all the primes up to a certain number.
The OP can use it to implement the first steps of their implementation, but they can also adapt it to avoid the sorting step.
Given the list of all primes (up to half the maximum number to examine):
Create an array of bool as big as the range of numbers to be examined.
Multiply each distinct couple of primes, using two nested loops.
If the product is less than 10000 (the maximum) set the corrisponding element of the array to true. Otherwise break out the inner loop.
Once finished, traverse the array and if the value is true, print the corresponding index.
Here there's a proof of concept (implemented without the OP's assignment restrictions).
// Ex10_TwoPrimes.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include "pch.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void Homework_Header(string Title);
void Do_Exercise();
void Sieve_Of_Eratosthenes(int n);
void Generate_Semi_Prime();
bool Semi_Prime(int candidate);
bool prime[5000 + 1];
int main()
{
Do_Exercise();
cin.get();
return 0;
}
void Do_Exercise()
{
int n = 5000;
Sieve_Of_Eratosthenes(n);
cout << endl;
Generate_Semi_Prime();
}
void Sieve_Of_Eratosthenes(int n)
{
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
memset(prime, true, sizeof(prime));
for (int p = 2; p*p <= n; p++)
{
// If prime[p] is not changed, then it is a prime
if (prime[p] == true)
{
// Update all multiples of p
for (int i = p * p; i <= n; i += p)
prime[i] = false;
}
}
}
bool Semi_Prime(int candidate)
{
for (int index = 2; index <= candidate / 2; index++)
{
if (prime[index])
{
if (candidate % index == 0)
{
int q = candidate / index;
if (prime[q] && q != index)
return true;
}
}
}
return false;
}
void Generate_Semi_Prime()
{
for (int i = 2; i <= 10000; i++)
if (Semi_Prime(i)) cout << i << "\t";
}

Classis task for splitting weights into 2 trucks (C++) (Dynamic Programming)

I have a task that by given line of weights of cages and I have to split them into 2 trucks. The split should be done like this that |a - b| to have least value where 'a' is the common weight of the cages in the first truck and 'b' is the common weight of the cages of second truck. My program seems to work but when I upload it to hackerrank abort function is called. So where is my fault? Here is the code:
#include <iostream>
#include <vector>
#include <sstream>
#include <cstring>
using namespace std;
int main()
{
string input;
int k;
while (getline(cin, input))
{
/* splitting the input into integers */
vector<int> v;
istringstream iss(input);
while (iss >> k) v.push_back(k);
/* --- II --- */
unsigned long sum = 0;
unsigned i, j;
for (i = 0; i < v.size(); i++)
sum += v[i];
vector<char> can;
can.push_back(1);
for (i = 1; i <= sum; i++)
can[i] = 0;
for (i = 0; i < v.size(); i++)
{
for (j = sum; j+1 > 0; j--)
{
if (can[j])
{
can[j + v[i]] = 1;
}
}
}
for (i = sum / 2; i > 1; i--)
{
if (can[i])
{
if (i <= sum - i)
{
cout << i << " " << sum - i << endl;
break;
}
else
{
cout << "a should be <= b";
break;
}
}
}
}
return 0;
}
How can this work?
You create an empty vector of char, push one single value into it and that try to assign value passed the first:
...
vector<char> can;
can.push_back(1); // can contains one single value
for (i = 1; i <= sum; i++)
can[i] = 0; // Error "vector subscript out of range" in debug mode
If you do not ask the control of vector subscript you will just invoke undefined behaviour.
But if you just want to expand the vector, you can repeatedly can push_back:
for (i = 1; i <= sum; i++)
can.push_back(0);

C++ Vector Subscript out of Range Error 1221

I am trying to make a program that recieves numbers from the user, and then rearranges the from least to greatest. I am using vectors (which I just learned about), and it gives me a subscript out of range error. I am not able to find what part of the code gives me this error, so hopefully someone more knowledgeable on vector and c++ can find it:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void order(int a, int b);
void orderRev(int a, int b);
int main() {
vector<int> num;
bool going = true;
do {
cout << "\nEnter a number or type 'x' to order:" << endl;
string reply;
getline(cin, reply);
if (reply != "x") {
int a = atoi(reply.c_str());
num.push_back(a);
cout << "\nYou currently have " << num.size() << " numbers added." << endl;
}
else {
going = false;
}
} while (going);
for (int i = 0; i < num.size(); i++) {
order(num[i], num[i + 1]);
}
for (int i = num.size() - 1; i >= 0; i--) {
orderRev(num[i + 1], num[i]);
}
cout << "\nThe number you entered in order from least to greatest are: " << endl;
for (int i = 0; i < num.size(); i++) {
cout << num[i] << " ";
}
void order(int a, int b) {
if (a > b) {
int c = b;
b = a;
a = c;
}
}
void orderRev(int a, int b) {
if (a < b) {
int c = b;
b = a;
a = c;
}
}
Fix these lines to this:
// added the -1 as this will now go up to the 2nd to last element
// for `n`, and the last element for `n+1`
for (int i = 0; i < num.size() - 1; i++) {
order(num[i], num[i + 1]);
}
// changed the starting number to size -2 (for the same reasoning)
for (int i = num.size() - 2; i >= 0; i--) {
orderRev(num[i + 1], num[i]);
}
Why does this need to be this way? Think about how indices in C++ work. They are zero-indexed! That means that if you want both the element and the one in front of it, you must go up to the size of the vector minus 1. Hence, for a vector of 10 items (size 10), at i == 9 your code will work like this:
for (int i = 0; i < num.size(); i++) {
// i = 9
order(num[9], num[9+1]);// index 10 does not exist! Hence, you really need to go up to num.size() - 1!
}
Vectors index start with 0. index will be 0 to n-1 , if you use num[i + 1] it will exceed the vector size, if you don't check in loop condition.
Your code has more than one flaw. The output will be same as the input , hint: know the difference between pass by reference and pass by value and after that check some sorting algorithms.