I'm trying to make this program which gets an element from user and inserts it into the made array by user (array must be sorted)
But it doesn't work properly
for example:
a[4]
a[0]=1
a[1]=3
a[2]=5
a[3]=7
then i insert>> 6
but then it goes like this
a[0]=1
a[1]=3
a[2]=5
a[3]=6
a[4]=3866936
the array is able to have upto 100 elements
:|
it's a practice from a book
#include<iostream>
#include<windows.h>
using namespace std;
void insert(int[], int&, int);
int main()
{
const int maxsize = 100;
int a[maxsize];
cout << "build ur array\n"; Sleep(650);
cout << "Enter the number of elements:";
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cout << "a[" << i << "]=";
cin >> a[i];
}
int k;
cout << "Enter a new element:";
cin >> k;
n++;
insert(a, n, k);
for (int i = 0; i < n; i++)
cout << "a[" << i << "]=" << a[i] << endl;
system("pause");
}
void insert(int a[], int& n, int x)
{
for (int i = n - 1; a[i]>x; i--)
a[i] = a[i + 1];
for (int i = n; i <= n; i--)
{
if (x >= a[i])
{
a[i + 1] = x;
break;
}
}
Assuming you know what you're doing ex. no one can enter more than 99, assuming you will check if the value is less than 100, you have only one error in insert:
a[i] = a[i+1];
should be
a[i+1] = a[i];
The full function should look like this to work with all possible cases:
void insert(int a[], int& n, int x)
{
for (int i = n - 2; a[i]>x && i >= 0; i--)
a[i+1] = a[i];
for (int i = n-2; i >= 0; i--)
{
if (x >= a[i])
{
a[i + 1] = x;
return;
}
}
a[0] = x;
}
You are experiencing undefined behavior due to the fact that you are reading from outside of the array bounds (0 - 3). You should use an std::vector for dynamically sized arrays:
std::vector<int> vec;
vec.push_back(1);
vec.push_back(3);
vec.push_back(5);
vec.push_back(7);
and then:
vec.push_back(6);
Later on, if you want to sort the array you can just do:
std::sort(vec.begin(), vec.end());
You just need to remember that index of array starts from 0. When you want to have 4 elements array int tab[4] you can can read/write elements value using indexes from 0 to 3 tab[0], tab[1], tab[2], tab[3]. Element tab[4] is not part of your array and when you want to read element from your such place, you will get value that is already there (you can think about it as unpredictable random value, but it is not true random value).
By the way, you question is about C language. If you using C++, read about containers like std::array, std::vector etc.
With some stuff from STL, you may use the following:
class SortedVector
{
public:
using const_iterator = std::vector<int>::const_iterator;
void insert(int value) {
auto it = std::lower_bound(v.begin(), v.end(), value);
v.insert(it, value);
}
const_iterator begin() const { return v.begin(); }
const_iterator end() const { return v.end(); }
private:
std::vector<int> v;
};
Live Example
std::vector is the container.
std::lower_bound finds the location where to insert (the way that insertion is still in order)
std::vector::insert does the insertion (which the shifting of the element).
if you don't want to use std::vector and us C-array: you may use:
void insert(int a[], int& n, int x)
{
auto it = std::lower_bound(a, a + n, x);
std::copy(it, a + n, it + 1);
*it = x;
++n;
}
Live example.
>
with help of prajmus
i solved the problem
:
#include<iostream>
#include<windows.h>
using namespace std;
void insert(int[], int&, int);
int main()
{
const int maxsize = 100;
int a[maxsize];
cout << "build ur array\n"; Sleep(650);
cout << "Enter the number of elements:";
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cout << "a[" << i << "]=";
cin >> a[i];
}
int k;
cout << "Enter a new element:";
cin >> k;
n++;
insert(a, n, k);
for (int i = 0; i < n; i++)
cout << "a[" << i << "]=" << a[i] << endl;
system("pause");
}
void insert(int a[], int& n, int x)
{
for (int i = n - 2; a[i]>x; i--)
a[i+1] = a[i];
for (int i = n-1; i <= n; i--)
{
if (x >= a[i])
{ a[i + 1] = x;
break;
}
}
}
Related
I wanted to write a program to take two arrays as input and convert the first array such that the difference of maximum value and minimum value from the first array gives the smallest possible number.
I tried to write a code to find a smaller number most closest to the maximum from the array in C++, but the function for finding the minimum works on Codelite, but not on other compilers;
Is there any fix to solve this, either to the code or the compiler?
Here is the code I tried:
#include <iostream>
using namespace std;
void swap(int A[], int B[], int n)
{
int x, y, temp;
for(x=0;x<n;++x)
{
for(y=0;y<n;++y)
{
if(A[x]>B[y])
{
temp = A[x];
A[x] = B[y];
B[y] = temp;
}
}
}
}
void sortas(int A[], int n)
{
int i, j, temp;
for (i = 0; i < n; i++)
{
for (j = i; j < n; j++)
{
if (A[i] > A[j+1])
{
temp = A[i];
A[i] = A[j+1];
A[j+1] = temp;
}
}
}
}
int maxfind(int A[], int n)
{
int z, a;
a = A[0];
for(z=0;z<n;++z)
{
if(a<A[z])
{
a = A[z];
}
}
cout << "Max value in A is" << a << endl;
return a;
}
int minfind(int A[], int n, int amax, int amin)
{
int z, maxi;
maxi = amax;
for(z=0;z<n;++z)
{
if(maxi >= A[z])
{
amin = A[z];
}
else
{
maxi = maxi-1;
}
}
cout << "Mix value in A is" << amin << endl;
return amin;
}
int main() {
int z, t;
cout << "Enter number of test cases: ";
cin >> t;
int n, i, j, amax, amin;
for(z=0;z<t;++z)
{
cout << "Enter size of array" << endl;
cin >> n;
int A[n], B[n];
cout << "Enter Array A values:" << endl;
for(i=0;i<n;++i)
{
cin >> A[i];
}
cout << "Enter Array B values:" << endl;
for(j=0;j<n;++j)
{
cin >> B[j];
}
swap(A, B, n);
sortas(A, n);
cout << "Swapped and sorted array is: " << endl;
for(i=0;i<n;++i)
{
cout << A[i] << "\t" << B[i] << endl;
}
amax = 0;
amin = 0;
amax = maxfind(A, n);
amin = minfind(A, n, amax, amin);
}
return 0;
}
Here is the output to that code:
1 1 1 3 4 2
Max value in A is 1 Min value in A is 1
1 2 2
-1882830412 4 3 6 3
Max value in A is 2 Min value in A is -1882830412
The problem is with your bubble sort:
void sortas(int A[], int n)
{
int i, j, temp;
for (i = 0; i < n; i++)
{
for (j = i; j < n; j++) // why not start at i + 1 ??
{
if (A[i] > A[j+1]) // j + 1 is out of bounds when j == n - 1
{
temp = A[i];
A[i] = A[j+1]; // <-- Some random value is written to A.
A[j+1] = temp; // <-- Overwriting some variable on the stack
// of main() (possibly B ?)
}
}
}
}
A correct bubble sort (this is not the pedantic bubble sort), this is probably the most used.
void sortas(int A[], int n)
{
for (int i = 0; i < n - 1; ++i)
{
for (int j = i + 1; j < n; ++j)
{
if (A[i] > A[j])
std::swap(A[i], A[j]);
}
}
}
The actual bubble sort algorithn (the "pedantic" bubble sort), swaps only occur on neighboring values.
void sortas(int A[], int n)
{
for (int i = 0; i < n - 1; ++i)
{
for (int j = 0; j < (n - i) - 1; ++j)
{
if (A[j] > A[j + 1])
std::swap(A[j], A[j + 1]);
}
}
}
Use one or the other, for integers, the performance is identical.
For some odd reason, I am getting a segmentation fault when I call the merge function. I am using g++ to compile and have tried passing in different data for the parameters, but I still get this issue.
#include <iostream>
using namespace std;
// Merges two sorted subarrays of A[].
// First sorted subarray is A[l..m].
// Second sorted subarray is A[m+1..r].
// You might want to call this function in function mergeSort().
void merge(int A[], int l, int m, int r) {
int i = 1; //Starting index for left sub array
int j = m + 1; //Starting index for right sub array
int k = 1; //starting index for temp
int *temp = new int[r];
while (i <= m && j <= r) {
if (A[i] <= A[j]) {
temp[k] = A[i]; //A[i] is actually smoler than A[j]
i++;
k++;
}
else {
if (A[i] <= A[j]) {
temp[k] = A[i]; //A[j] is actually smoler than A[i]
j++;
k++;
}
}
//Copy all elements from left sbuarray to temp
while(i<=m){
temp[k] = A[i];
i++;
k++;
}
//Copy all elements from right subarray to temp
while(j<=r){
temp[k] = A[j];
i++;
k++;
}
for(int z =0; z <r; z++){
A[z] = temp[z];
}
}
}
// using mergeSort to sort sub-array A[l..r]
// l is for left index and r is right index of the
// sub-array of A[] to be sorted
void mergeSort(int A[], int l, int r) {
if (l < r) {
int middle = l + (r - l) / 2;
mergeSort(A, l, middle);
mergeSort(A, middle + 1, r);
merge(A, l, middle, r);
}
}
int main() {
cout << "Please enter the length (number of elements) of the input array: ";
int n;
cin >> n;
if (n <= 0) {
cout << "Illegal input array length!" << endl;
return 0;
}
int *A = new int[n];
cout << "Please enter each element in the array" << endl;
cout << "(each element must be an integer within the range of int type)."
<< endl;
for (int i = 0; i < n; i++) {
cout << "A[" << i << "] = ";
cin >> A[i];
}
cout << "Given array A[] is: ";
for (int i = 0; i < n - 1; i++)
cout << A[i] << ",";
cout << A[n - 1] << endl;
mergeSort(A, 0, n - 1);
cout << "After mergeSort, sorted array A[] is: ";
for (int i = 0; i < n - 1; i++)
cout << A[i] << ",";
cout << A[n - 1] << endl;
delete[] A;
return 0;
}
The merge function is the problem of my program. I have tried debugging and whatnot but cannot determine the problem.
Try using the below code :-
#include<iostream>
using namespace std;
void merge(int arr[],int l,int m,int h)
{
int n1=m-l+1;
int n2=h-m;
int L[n1],M[n2];
for(int i=0;i<n1;i++)
L[i]=arr[l+i];
for(int i=0;i<n2;i++)
M[i]=arr[m+1+i];
int i=0,j=0,k=l;
while(i<n1&&j<n2)
{
if(L[i]<=M[j])
arr[k++]=L[i++];
else
arr[k++]=M[j++];
}
while(i<n1)
arr[k++]=L[i++];
while(j<n2)
arr[k++]=M[j++];
}
void mergesort(int arr[],int l,int h)
{
if(l>=h)
return;
int m=l+(h-l)/2;
mergesort(arr,l,m);
mergesort(arr,m+1,h);
merge(arr,l,m,h);
}
int main()
{
int n;
cout<<"Enter the no of element to be sorted:- ";
cin>>n;
int arr[1000000];
for(int i=0;i<n;i++)
arr[i]=rand();
mergesort(arr,0,n-1);
for(int i=0;i<n;i++)
cout<<arr[i]<<endl;
}
here is the output on online compiler:-
The problem is in this block of code.
while (j <= r) {
temp[k] = A[j];
i++; // Here it should be j++ instead of i++
k++;
}
You are incrementing i whereas you should increment j. This still produces the wrong output though.
Use debugger to find what's wrong with your code.
void Numbers()
{
do
{
cout << "Enter the value for the sequence: ";
cin >> K;
if ( K <= 3)
{
cout << "Write a bigger number!" << endl;
}
} while(K <= 3);
cout << "Enter the first number: ";
cin >> N;
}
double Sum()
{
vector<double> arr(K);
arr.push_back(N);
for (int i=0; i < arr.size(); i++)
arr.at(i)=i;
cout << "Vector contains: ";
for (int i=0; i < arr.size(); i++)
cout << arr.at(i);
int main()
{
Numbers();
Sum();
return 0;
}
Write a program that generates sequence of K (K > 3) numbers as follows:
The members of the above sequence are obtained as follows:
the first element is N;
the second one is N + 1;
the third - N * 2.
In other words, we consistently add 1 to each element and put it to the end of the sequence, then multiply it by 2 and again, put the product to the end of the sequence. Choose and implement a suitable data structure that can be used to generate the above sequence of numbers.
The users should enter values for K and first element N.
This is my current code(in the code above). I don`t realy know where to go from here onward to be completely honest. Any suggestions on how to create the sequence from the condition above?
You can use this code to get what you want:
#include <iostream>
#include <vector>
using namespace std;
vector<double> createOutputArray (int K, int N)
{
vector<double> arr;
int tmp = N;
arr.push_back(tmp);
for(int i=1; i+2<=K; i+=2)
{
arr.push_back(++tmp);
arr.push_back(tmp * 2);
tmp *= 2;
}
if(K % 2 == 0)
arr.push_back(++tmp);
return arr;
}
int main()
{
int K;
double N;
do
{
cout << "Enter the value for the sequence: ";
cin >> K;
if ( K <= 3)
{
cout << "Write a bigger number!" << endl;
}
} while(K <= 3);
cout << "Enter the first number: ";
cin >> N;
vector<double> output = createOutputArray(K, N);
for (int i=0; i < output.size(); i++)
{
cout << output.at(i);
if(i < output.size()-1)
cout << ",";
else
cout << endl;
}
return 0;
}
Here is one possibility, using a generator to produce the next element in the sequence.
class Seq
{
public:
Seq(int n) : n(n) {}
int operator*() const { return n; }
Seq operator++(int)
{
Seq old(n);
n = fns[fn](n);
fn = 1 - fn;
return old;
}
private:
int n;
int fn = 0;
std::function<int(int)> fns[2] = {[](int x) { return x + 1; },
[](int x) { return x * 2; }};
};
int main()
{
int N = 1;
int K = 20;
Seq seq(N);
for (int i = 0; i < K; i++)
{
std::cout << *seq++ << ' ';
}
std::cout << std::endl;
}
I want to count how many times does algorithm makes comparisons and how many times algorithm makes copying.
#include <stdio.h>
#include <random>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <time.h>
void generuoti(int _N, const char *_file);
void nuskaityti(const char *_file);
int ps = 0;
int ks = 0;
void heapify(double arr[], int n, int i)
{
int largest = i; // Initialize largest as root
int l = 2 * i + 1; // left = 2*i + 1
int r = 2 * i + 2; // right = 2*i + 2
// If left child is larger than root
if (l < n && arr[l] > arr[largest])
largest = l;
ps+=1;
// If right child is larger than largest so far
if (r < n && arr[r] > arr[largest])
largest = r;
ps += 1;
// If largest is not root
if (largest != i)
{
std::swap(arr[i], arr[largest]);
ps += 1;
ks += 1;
// Recursively heapify the affected sub-tree
heapify(arr, n, largest);
}
}
// pagr funkcija haep sortui
void heapSort(double arr[], int n)
{
// Build heap (rearrange array)
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// One by one extract an element from heap
for (int i = n - 1; i >= 0; i--)
{
// Move current root to end
std::swap(arr[0], arr[i]);
ks+=1;
// call max heapify on the reduced heap
heapify(arr, i, 0);
}
}
void insertion_sort(double arr[], int n)
{
int i, key, j;
for (i = 1; i < n; i++)
{
key = arr[i];
j = i - 1;
ks+=1;
while (j >= 0 && arr[j] > key)
{
arr[j + 1] = arr[j];
j = j - 1;
ks+=1;
ps+=1;
}
arr[j + 1] = key;
ks+=1;
}
}
using namespace std;
double *Data;
double* A;
double* B;
double N;
int main()
{
srand(time(NULL));
cout << "Generuojame atsitktinius duomenis" << endl;
generuoti(20000, "duom.txt");
cout << "Nuskaitome duomenis" << endl;
nuskaityti("duom.txt");
A = new double[(int)N];
B = new double[(int)N];//jeigu algoritmui reikia papildomo masyvo
for (int i = 0; i < N; i++) {
A[i] = Data[i];
}
cout << "Pradine skaiciu seka:" << endl;
for (int i = 0; i < N; i++)
cout << A[i] << " ";
cout << endl;
//
insertion_sort(A, N);
//heapSort(A, N);
//truksta veiksmu sk
cout << "Surusiuota skaiciu seka:" << endl;
for (int i = 0; i < N; i++)
cout << A[i] << " ";
cout << endl;
cout << "Kopijavimu skaicius " << ks << endl;
cout << "Palyginimu skaicius " << ps << endl;
system("pause");
return 0;
}
void generuoti(int _n, const char *_file) {
ofstream os(_file);
os << _n << endl;
for (int i = 0; i<_n; i++)
os << " " << 500+ (double)(rand() % 3001) ;
os.close();
}
void nuskaityti(const char *_file) {
ifstream is(_file);
if (is.fail()) {
cout << "Failo nera" << endl;
exit(1);
}
is >> N;
Data = new double[(int)N];
for (int i = 0; i < N; i++) {
is >> Data[i];
}
}
This is my code, and ps - is equal to a number of comparisons, and ks - is equal to number of copying. I want to ask if I counted all comparisons and all copying in the algorithms? Thanks for answers.
No
if (l < n && arr[l] > arr[largest])
largest = l;
ps+=1;
There are two problems here. Assuming you are talking about double comparisons (rather than integer), the comparison may or may not occur.
Secondly your indentation is deeply misleading. (You always increment.)
You need
if (l < n) {
ps++; // About to compare
if (arr[l] > arr[largest])
largest = l;
}
There are probably other errors, but it is impossible to tell because I can't read your language, so the printed text, comments, and names are meaningless.
Given you are writing in C++, I would write a class with operator <() and operator =, and a copy constructor, and instrument those. That way you cannot possibly get it wrong.
I am trying to learn C++, arrays and pointers. I decided to implement the insertion sort algorithm. So, here is my code and my wrong output. What should I do to correct it? Can you please tell me what is my mistake and what should I avoid if it is a common error?
My code:
// InsertionSort.cpp
#include "stdafx.h"
#include <iostream>
int DeclareAnInteger();
int* DeclareAndShowTheArray(int n);
int* InsertionSort(int *A, int n);
int main()
{
int n = DeclareAnInteger();
int *A;
A = DeclareAndShowTheArray(n);
int *B;
B = InsertionSort(A, n);
system("PAUSE");
return 0;
}
int DeclareAnInteger()
{
int n;
std::cout << "Please enter a positive integer n: ";
std::cin >> n;
return n;
}
int* DeclareAndShowTheArray(int n)
{
int *A;
A = (int *)alloca(sizeof(int) * n);
for (int i = 0; i < n; i++)
{
std::cout << "Please enter the value of A[" << i + 1 << "]: ";
std::cin >> A[i];
}
std::cout << "The unsorted array is: ";
for (int i = 0; i < n; i++)
{
std::cout << A[i];
std::cout << "\t";
}
std::cout << "\n";
return A;
}
int* InsertionSort(int *A, int n)
{
int k;
//int *A = new int[n];
for (k = 1; k < n; k++)
{
int key = A[k];
int m = k - 1;
while (m >= 0 & A[m] > key)
{
A[m + 1] = A[m];
m = m - 1;
}
A[m + 1] = key;
}
std::cout << "The sorted array is: ";
for (int i = 0; i < n; i++)
{
std::cout << A[i];
std::cout << "\t";
}
std::cout << "\n" << std::endl;
return A;
}
My output:
This here is a big problem:
A = (int *)alloca(sizeof(int) * n);
The alloca function allocates on the stack, and it will be lost when the function returns which gives you a stray pointer and undefined behavior when you dereference this pointer.
If you're programming C++ then use new, if you program C then use malloc.