Why this radixSort doesn't work - c++

It look's like it's OK. But result is telling something different. Really, I don't know whats wrong with it. Maybe it's because I wrote it at 2 o'clock at night ...
EDIT:
template <class T>
void radixSort(T & arr, msize numberBase)
{
long maxValue = findMax(arr);
dynarray<long> tarr(arr,arr.size());
dynarray<long> presenceTable(numberBase+1);
for (register long i=0, max=presenceTable.size(); i<max; ++i)
{
presenceTable[i] = 0;
}
for (register long exp=1; maxValue/exp>0; exp*=numberBase)
{
for (register long i=0, max=tarr.size(); i<max; ++i)
{
++(presenceTable[(tarr[i]/exp)%numberBase]);
}
for (register long i=1, max=presenceTable.size(); i<max; ++i)
{
presenceTable[i] += presenceTable[i-1];
}
for (register long i=0, max=tarr.size(); i<max; ++i)
{
arr[ (--(presenceTable[(tarr[i]/exp)%numberBase])) ] = tarr[i];
}
tarr = arr;
for (register long i=0, max=presenceTable.size(); i<max; ++i)
{
presenceTable[i] = 0;
}
}
}

Try algorithm from this code:
#include<bits/stdc++.h>
using namespace std;
// Function to get maximum value in array a[].
int getmax(int a[], int n)
{
int max = a[0];
for (int x=1; x<n; x++)
if (a[x] > max)
max = a[x];
return max;
}
// Function to do counting sort according to significant digits repesented by
// exp (where exp is 10^i).
void CountSort(int a[], int n, int exp)
{
int result[n], i, count[10] = {0};
// Counting occurence of digits
for (i =0; i <n; i++)
count[(a[i] / exp) % 10]++;
// Changing the position of count so that it appears at actual position in result.
for (i =1; i<10; i++)
count[i] += count[i-1];
// Resultant output array
for (i =n-1; i>= 0; i--)
{
result[count[(a[i] / exp) % 10] - 1] = a[i];
count[(a[i] / exp) % 10]--;
}
for (i =0; i <n; i++)
a[i] = result[i];
}
// Radix Sort to sort a[] of given size.
void radixsort(int a[], int n)
{
int exp, i;
i = getmax(a, n);
for (exp = 1; i/exp > 0; exp *= 10)
CountSort(a, n, exp);
}
// Driver Program
int main()
{
int n;
cout<<" Enter the number of elements to be sorted: ";
cin>>n;
int a[n];
cout<<"\n Enter the elements: ";
for(int i =0; i <n; i++)
{
cin>>a[i];
}
radixsort(a, n);
// Printing the sorted list.
cout<<"\nSorted List: ";
for (int i = 0; i < n; i++)
cout<<a[i]<<", ";
return 0;
}
I changed it a bit and it worked for me

Related

swap alternate in an array

You have been given an array/list(ARR) of size N. You need to swap every pair of alternate elements in the array/list.
You don't need to print or return anything, just change in the input array itself.
#include <iostream>;
using namespace std;
void printArr(int arr[], int n)
{
for (int i = 0; i < n; i++)
cout << arr[i]<<i;
}
void UpdateArr(int arr[], int n)
{
int i = 0, j = n - 1;
while (i < j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i += 2;
j -= 2;
}
cout<<' printArr(arr[], n)';
}
int main()
{
int t;
cin>> t;
int n;
cin>> n;
int input[100];
for(int i=0; i<n; i++) {
cin >>input[i];
}
int arr[100] ;
n = sizeof(arr) / sizeof(arr[0]);
UpdateArr(arr, n);
return 0;
}
I'm not sure what are you exactly expecting the output to be (pls edit it and show the expected output) but I think this is what you need to do
#include <iostream>
#include <iomanip>
using namespace std;
void UpdateArray(int Arr[], size_t n) {
for (size_t i = 0; i < n / 2; i++) {
int Holder = Arr[i];
Arr[i] = Arr[~i + n];
Arr[~i + n] = Holder; } }
int main() {
int Arr[7] = { 1,2,3,4,5,6,7 };
UpdateArray(Arr, 7);
for (int i = 0; i < 7; i++) {
std::cout << Arr[i] << "\n"; }
return 0; }
size_t is like an int but it can't go into negative, but it can take bigger positive numbers, you can replace it with int, it shouldn't make a difference.
so we loop through half the array, replacing first items with last, the [~i + n] flips the value to the other side, so like index 4 in a array size of 20 will become 15

removing double elements in an array

I am trying to remove double elements in an array. I developed a simple code, but it is still not working. Is it possible to hint for some input maybe I haven't tried. I tried corner and test cases. The following is the problem statement:
A sequence of numbers given. Remove element’s doubles, leaving first copy.
Input: Contains a natural n (n ≤ 100000) – the n quantity numbers in a sequence, then n non-negative numbers – elements of the sequence which module is not greater than 999.
output: changed sequence.
It seems I can't get what might be the problem
#include <iostream>
//#include <cmath>
//#include <climits>
#define SIZE 100000
using namespace std;
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n, k, p;
bool tag; tag = false;
cin >> n;
long long int *a = new long long int[n];
long long int b[SIZE];
for (int i = 0; i < n; i++) { cin >> a[i]; }
for (int i = 0; i < n; i++) { k = 0;
for (int j = i + 1; j < n; j++) {
if (a[i] == a[j]) { b[k] = j-k; k++; tag = true; }
}
if (tag) {
for (int i = 0; i < k; i++) {
p = b[i];
for (int i = p; i < n; i++) { a[i] = a[i + 1]; }
n--;
}
tag = false;
}
}
for (int i = 0; i < n; i++) { cout << a[i] << " "; }
return 0;
}
Input: 6 1 2 2 4 3 4 Output: 1 2 4 3
You can use unordered_set and vector
int n; cin >> n;
long long int x;
unordered_set<long long int>myset;
vector<long long int>v1;
for (int i = 0; i < n; i++)
{
cin>>x;
if(myset.find(x)==myset.end())
{
myset.insert(x);
v1.push_back(x);
}
}
for(int i=0;i<v1.size();i++)
{
cout<<v1[i]<<" ";
}
You could use in you advantage the fact that input values are in the range from 0 to 999.
A simple bool used[1000]{} could be used to flag if the current value has been used already before pushing it to cout, thus ensuring both O(n) complexity and limited memory usage (1000 bytes for the bool[]}.
Here's a sample solution around this idea:
#include<iostream>
#define MAX_VALUE 999
using namespace std;
int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
bool used[MAX_VALUE + 1]{};
size_t n;
cin >> n;
for (size_t num, i = 0; i < n; ++i) {
cin >> num;
if (!used[num]) {
cout << num << " ";
used[num] = true;
}
}
return 0;
}
You could try creating a second array of unique numbers as you go. I will demonstrate with a vector for the sake of simplicity.
std::vector<int> v;
for (int i = 0; i < n; i++) {
if (std::find(v.begin(), v.end(), arr[i]) == v.end()) {
v.push_back(arr[i]);
}
}
Then, you just write the contents of the vector to the output file.
Here is my version of O(n) complexity. Your solution may exceed time-limit ( if it is low )
bool check[2000];
for (int i = 0; i < 2000; i++) check[i] = 0;
for (int i = 0; i < n; i++) {
cin >> a[i];
// +999 to avoid negative numbers
check[a[i] + 999] = 1;
}
bool isPrint = false;
for (int i = 0; i < n; i++) {
if (check[a[i] + 999]) {
// mark false if already printed
check[a[i] + 999] = 0;
if (isPrint) printf(" ");
printf("%d", a[i]);
isPrint = true;
}
}

Segmentation fault:11 MergeSort

I try to implement the merge sort algorithm and I get a segmentation fault. Why? The error seems to be in the MergeSort function. The merge sort function (on the 2nd call) when should check only an array of 4 numbers (the length should be 4) shows the length = 27. Why? (tested on an array with 8 elements)
#include<iostream>
using namespace std;
int n, A[1000];
void citire(int lungime) {
for (int i = 0; i < lungime; i++) cin >> A[i];
}
void afisare(int lungime) {
for (int i = 0; i < lungime; i++)
cout << A[i] << " ";
cout << '\n';
}
int lungime(int A[]) {
int i = 0;
while (A[i]) i++;
return i;
}
void Merge(int L[], int R[], int A[]) {
int nL = lungime(L);
int nR = lungime(R);
int i = 0, j = 0, k = 0;
while (i < nL && j < nR) {
if (L[i] <= R[j]) {
A[k] = L[i];
i++;
}
else {
A[k] = R[j];
j++;
}
k++;
}
while (i < nL) {
A[k] = L[i];
i++;
k++;
}
while (j < nR) {
A[k] = R[j];
j++;
k++;
}
}
void MergeSort(int A[]) {
int n1 = lungime(A);
if (n1 < 2) return;
else
{
int mid = (int)n1 / 2;
int L[mid];
int R[n - mid];
for (int i = 0; i < mid; i++)
L[i] = A[i];
for (int i = mid; i < n; i++)
R[i - mid] = A[i];
MergeSort(L);
MergeSort(R);
Merge(L, R, A);
}
}
int main() {
cin >> n;
citire(n);
MergeSort(A);
afisare(n);
return 0;
}
Changes made in this example. A[], L[], R[] are allocated using new. A[] is passed as a parameter. L[] and R[] are allocated in Merge(). Size and/or indices passed as parameters, and lungime() is no longer used to get size. Other changes noted in comments.
#include<iostream>
using namespace std;
void citire(int A[], int lungime) { // A is parameter
for (int i = 0; i < lungime; i++) cin >> A[i];
}
void afisare(int A[], int lungime) { // A is parameter
for (int i = 0; i < lungime; i++)
cout << A[i] << " ";
cout << '\n';
}
// A, low, mid, end are parameters
// L and R allocated here
void Merge(int A[], int low, int mid, int end) {
int sizeL = mid-low;
int sizeR = end-mid;
int *L = new int[sizeL];
int *R = new int[sizeR];
for(int i = 0; i < sizeL; i++)
L[i] = A[low+i]; // A[low+i]
for(int i = 0; i < sizeR; i++)
R[i] = A[mid+i]; // A[mid+i]
int i = 0, j = 0, k = low; // k = low
while (i < sizeL && j < sizeR) {
if (L[i] <= R[j]) {
A[k] = L[i];
i++;
}
else {
A[k] = R[j];
j++;
}
k++;
}
while (i < sizeL) {
A[k] = L[i];
i++;
k++;
}
while (j < sizeR) {
A[k] = R[j];
j++;
k++;
}
delete[] R;
delete[] L;
}
// A, low, end are parameters
void MergeSort(int A[], int low, int end) {
int sizeA = end - low;
if(sizeA < 2)
return;
int mid = low + (sizeA / 2); // mid = low + ...
MergeSort(A, low, mid);
MergeSort(A, mid, end);
Merge(A, low, mid, end);
}
int main() {
int n;
cin >> n;
int *A = new int[n]; // A is allocated
citire(A, n); // A, n are parameters
MergeSort(A, 0, n); // A, 0, n are parameters
afisare(A, n); // A, n are parameters
delete[] A;
return 0;
}
"The lungime function is the length of the string and this function works good. I've tested it on different arrays".
Well, this is purely accidental; uninitialized memory can contain zeros, and provide the array terminator by accident.
If you want to keep the current design, you should:
initialize A to zeros
make sure that there are no more than 999 elements in the input stream,
that no element has the value zero, as zero is reserved, and used as terminator, and
define L and R (in MergeSort) one element longer, and initialize the last element to zero.
Unless there are overwhelming reasons for a "roll your own" sort solution, you might have a look at prefab sort support. The vector class in C++ offers just that.

Why am i getting a runtime error after giving input for array and entering mergesort function?

#include<iostream>
using namespace std;
void merge(int *lArray, int nL, int *rArray, int nR, int *Array){
int i,j,k;
i=0; j=0; k=0;
//i,j,k are pointers for lArray, rArray & Array
// nL & nR are numbr of elements in lArray & rArray respectively
while(i<nL && j<nR)
{
if(lArray[i] <= rArray[j])
Array[k++] = lArray[i++];
else
Array[k++] = rArray[j++];
}
while(i<nL)
Array[k++] = lArray[i++];
while(i<nR)
Array[k++] = rArray[j++];
return;
}
void mergesort(int *Array, int n)
{
if (n<2)
return;
int mid = n/2;
int lArray[mid];
int rArray[n-mid];
for (int i=0;i<mid;i++)
lArray[i] = Array[i];
for (int i=mid;i<n;i++)
rArray[i-mid] = Array[i];
mergesort(lArray, mid);
mergesort(rArray,n-mid);
merge(lArray,mid,rArray,n-mid,Array);
delete(lArray);
delete(rArray);
}
int main()
{
int Array[10];
int n = 10;
cout<< "Enter Values :" << " ";
for(int i=0; i<10; i++)
cin>>Array[i];
mergesort(Array,n);
for(int i=0; i<n; i++)
cout<<Array[i]<< " ";
return 0;
}
Its a simple merge sort program but i cant find out where i went wrong.
After running the code i was able to enter the input for array but after entering into mergesort function the console just crashed.
I am using CodeBlocks on 64bit Windows 8.1.
I have done some changes in your mergesort function. Now your program shows the output on console but the output is not sorted. I think there is array indexing problem may be segmentation fault. There is a logical error too in the output.
#include<iostream>
using namespace std;
void merge(int *lArray, int nL, int *rArray, int nR, int *Array)
{
int i,j,k;
i=0; j=0; k=0;
//i,j,k are pointers for lArray, rArray & Array
// nL & nR are numbr of elements in lArray & rArray respectively
while(i<nL && j<nR)
{
if(lArray[i] <= rArray[j])
Array[k++] = lArray[i++];
else
Array[k++] = rArray[j++];
}
while(i<nL)
Array[k++] = lArray[i++];
while(i<nR)
Array[k++] = rArray[j++];
return;
}
void mergesort(int *Array, int n)
{
if(n>2)
{
int mid = (n+1)/2;
int lArray[mid];
int rArray[n-mid];
for (int i=0;i<mid;i++)
lArray[i] = Array[i];
for (int i=mid;i<n;i++)
rArray[i-mid] = Array[i];
mergesort(lArray, mid);
mergesort(rArray,n-mid);
merge(lArray,mid,rArray,n-mid,Array);
delete(lArray);
delete(rArray);
}
}
int main()
{
int Array[10];
int n = 10;
cout<< "Enter Values :" << " ";
for(int i=0; i<10; i++)
cin>>Array[i];
mergesort(Array,n);
for(int i=0; i<10; i++)
cout<<Array[i]<< " ";
return 0;
}

Finding the maximum value of every row in 2D array C++

I've managed to find the minimum value of every row of my 2D array with this
void findLowest(int A[][Cm], int n, int m)
{
int min = A[0][0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (A[i][j] < min)
{
min = A[i][j];
}
}
out << i << " row's lowest value " << min << endl;
}
}
I'am trying to find the maximum value of every row using the same way,but it only shows me first maximum value
void findHighest(int A[][Cm], int n, int m)
{
int max = A[0][0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (A[i][j] > max)
{
max = A[i][j];
}
}
out << i << " row's highest value " << max << endl;
}
}
I can't find what's wrong with the second function and why is it only showing me the first maximum value it finds. Any help ?
Both functions return the result (maximum or minimum) for the whole array rather than each row, because you set max once rather than once per row. You can get the result for each row as follows:
void findHighest(int A[][Cm], int n, int m)
{
for (int i = 0; i < n; i++)
{
int max = A[i][0];
for (int j = 1; j < m; j++)
{
if (A[i][j] > max)
{
max = A[i][j];
}
}
// do something with max
}
}
or, even better, use the standard library function max_element:
void findHighest(int A[][Cm], int n, int m)
{
if (m <= 0) return;
for (int i = 0; i < n; i++)
{
int max = *std::max_element(A[i], A[i] + m);
// do something with max
}
}
This should give you all values which is easy to check:
#include <algorithm>
#include <iostream>
enum { Cm = 2 };
void findHighest(int A[][Cm], int n, int m) {
if (m <= 0) return;
for (int i = 0; i < n; i++) {
int max = *std::max_element(A[i], A[i] + m);
std::cout << max << " ";
}
}
int main() {
int A[2][2] = {{1, 2}, {3, 4}};
findHighest(A, 2, 2);
}
prints 2 4.
If your compiler supports C++11, for concrete arrays you could use the following alternative, that's based on std::minmax_element:
template<typename T, std::size_t N, std::size_t M>
void
minmax_row(T const (&arr)[N][M], T (&mincol)[N], T (&maxcol)[N]) {
for(int i(0); i < N; ++i) {
auto mnmx = std::minmax_element(std::begin(arr[i]), std::end(arr[i]));
if(mnmx.first != std::end(arr[i])) mincol[i] = *(mnmx.first);
if(mnmx.second != std::end(arr[i])) maxcol[i] = *(mnmx.second);
}
}
Live Demo
Your test data is guilty for not clearly showing you the defect.
The row minima occur in decreasing values, so that they get updated on every row.
And the row maxima also occur in decreasing values, so that the first one keeps winning.
As others pointed, your function finds the global minimum/maximum, no the per-row extrema.
Move the initialization of the min/max variable inside the outer loop.
As mentioned your code only shows the maximum element in the whole array.
Here is the code which will help you.
void findHighest(int A[][Cm], int n, int m)
{
int max[n];
max[0]=A[0][0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (A[i][j] > max[i])
{
max[i] = A[i][j];
}
}
cout << i << " row's highest value " << max[i] << endl;
}
}
{
int i,j;
int arr[4][2]={(1,2),(3,4),(5,6),(7,8)};
int max;
max=arr[0][0];
for( int i=0; i<4; i++)
{
for(int j=0; j<2; j++)
{
if(max<arr[i][j])
{
max=arr[i][j];
}
}
}
int min;
min=arr[0][0];
for(int i=0; i<4; i++)
{
for(int j=0; j<2; j++)
{
if(min>arr[i][j])
{
min=arr[i][j];
}
}
}
cout<<"maximum number is:"<<max;
cout<<endl;
cout<<"Minimum Number is:"<<min;
}