Error implementing Radix sort in C++ - c++

I’m trying to implement Radix-Sort with arrays of long int.
My Algorithm has 2 inputs:
The number ’n’ of elements to be sorted
The number ‘b’ of bits per digit (So, insted of taking the last decimal number, I take the groups of ‘b’ digits, representing one digit)
But, when I try to sort the vector, I find 2 problems:
First one: It doesn’t sort the vector properly
Second one: I have implemented it for taking from the last group of bits to the first one. But it seems like it tries to sort in in the opposite direction.
Here is the code:
#define MAX_BITS sizeof(long int)*8
#define VectorL vector<long int>
struct Compare
{
int beg = 0;
int bits_per_digit = 2;
Compare(int x, int y){
beg = x;
bits_per_digit = y;
}
bool operator() (long& a, long& b){
int _begin = beg;
int _final = _begin + bits_per_digit - 1;
assert(_begin <= _final); // b==f if bits_per_digit = 1;
bitset<sizeof(long int)> _x(a), _y(b);
for(_begin; _begin <= _final; _begin++)
if(_x[_begin] != _y[_begin])
return (_x[_begin] < _y[_begin]) ? true : false;
return false;
}
};
void ALG(VectorL& nums, int n, int b)
{
assert(nums.size() == n);
assert(MAX_BITS%b == 0);
int _grupos = MAX_BITS/b;
Compare myobject(MAX_BITS,b);
for (int g = 1; g <= _grupos; g++)
{
myobject.beg -= b;
sort(nums.begin(), nums.end(), myobject);
}
}
Here’s the main:
int n=5, b=2;
VectorL nums(n);
nums[0] = 2;
nums[1] = 6;
nums[2] = 1;
nums[3] = 5;
nums[4] = 0;
ALG(nums, n, b);
And here’s the output:
Initial Vector: 2 6 1 5 0
From bit 62 to bit 63
Vector after the 1º sort: 2 6 1 5 0
From bit 60 to bit 61
Vector after the 2º sort: 2 6 1 5 0
From bit 58 to bit 59
Vector after the 3º sort: 2 6 1 5 0
From bit 56 to bit 57
Vector after the 4º sort: 2 6 1 5 0
From bit 54 to bit 55
Vector after the 5º sort: 2 6 1 5 0
From bit 52 to bit 53
Vector after the 6º sort: 2 6 1 5 0
From bit 50 to bit 51
Vector after the 7º sort: 2 6 1 5 0
From bit 48 to bit 49
Vector after the 8º sort: 2 6 1 5 0
From bit 46 to bit 47
Vector after the 9º sort: 2 6 1 5 0
From bit 44 to bit 45
Vector after the 10º sort: 2 6 1 5 0
From bit 42 to bit 43
Vector after the 11º sort: 2 6 1 5 0
From bit 40 to bit 41
Vector after the 12º sort: 2 6 1 5 0
From bit 38 to bit 39
Vector after the 13º sort: 2 6 1 5 0
From bit 36 to bit 37
Vector after the 14º sort: 2 6 1 5 0
From bit 34 to bit 35
Vector after the 15º sort: 2 6 1 5 0
From bit 32 to bit 33
Vector after the 16º sort: 2 6 1 5 0
From bit 30 to bit 31
Vector after the 17º sort: 2 6 1 5 0
From bit 28 to bit 29
Vector after the 18º sort: 2 6 1 5 0
From bit 26 to bit 27
Vector after the 19º sort: 2 6 1 5 0
From bit 24 to bit 25
Vector after the 20º sort: 2 6 1 5 0
From bit 22 to bit 23
Vector after the 21º sort: 2 6 1 5 0
From bit 20 to bit 21
Vector after the 22º sort: 2 6 1 5 0
From bit 18 to bit 19
Vector after the 23º sort: 2 6 1 5 0
From bit 16 to bit 17
Vector after the 24º sort: 2 6 1 5 0
From bit 14 to bit 15
Vector after the 25º sort: 2 6 1 5 0
From bit 12 to bit 13
Vector after the 26º sort: 2 6 1 5 0
From bit 10 to bit 11
Vector after the 27º sort: 2 6 1 5 0
From bit 8 to bit 9
Vector after the 28º sort: 2 6 1 5 0
From bit 6 to bit 7
Vector after the 29º sort: 2 6 1 5 0
From bit 4 to bit 5
Vector after the 30º sort: 2 6 1 5 0
From bit 2 to bit 3
Vector after the 31º sort: 2 1 0 6 5
From bit 0 to bit 1
Vector after the 32º sort: 0 2 6 1 5
As you can see in the output, the changes only happens in the 31st and 32nd sort (so, that means the significant bits are found in the last searchs).
Anyone can help me to find my mistake?
Thanks in advance.

Related

Triplet form of Sparse matrix, getting wrong output in first Row

Hello Friends, I was trying to make Triplet form of a sparse matrix using pointers and DMA but the output in first row is returning garbage values can anyone help me in resolving this issue.
int main(){
int k=0,z=0,arr[6][6]={
{15,0,0,22,0,-15},
{0,11,3,0,0,0},
{0,0,0,-6,0,0},
{0,0,0,0,0,0},
{91,0,0,0,0,0},
{0,0,28,0,0,0}
};
int **trip=new int *[3];
for(int i=0;i<6;i++){
for(int j=0;j<6;j++){
if (arr[i][j]==0){
z++;
}
else{
trip[k]=new int(1);
trip[k][0]=i;
trip[k][1]=j;
trip[k][2]=arr[i][j];
k++;
}
}
}
}
Output-
-65511600 22028 -65511568
0 3 22
0 5 -15
1 1 11
1 2 3
2 3 -6
4 0 91
5 2 28
Expected Output
0 0 15
0 3 22
0 5 -15
1 1 11
1 2 3
2 3 -6
4 0 91
5 2 28

All possible sum from a given of coins

You have n coins with certain values. Your task is to find all the money sums you can create using these coins.
Input
The first input line has an integer n: the number of coins.
The next line has n integers x1,x2,…,xn: the values of the coins.
Output
First print an integer k: the number of distinct money sums. After this, print all possible sums in increasing order.
Constraints
1≤n≤100
1≤xi≤1000
Example
Input:
4
4 2 5 2
Output:
9
2 4 5 6 7 8 9 11 13
I have written a code which works perfectly for the small inputs but gives the wrong answer to the large inputs. Please help to find the mistake and how do I correct it.
my code is:
#include <bits/stdc++.h>
using namespace std;
set<long long> s;
// Prints sums of all subsets of array
void subsetSums(long long arr[], long long n)
{
// There are totoal 2^n subsets
long long total = 1 << n;
// Consider all numbers from 0 to 2^n - 1
for (long long i = 0; i < total; i++)
{
long long sum = 0;
// Consider binary reprsentation of
// current i to decide which elements
// to pick.
for (long long j = 0; j < n; j++)
if (i & (1 << j))
sum += arr[j];
// Print sum of picked elements.
if (sum)
s.insert(sum);
}
}
// Driver code
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
long long n;
cin >> n;
long long arr[n];
for (long long i = 0; i < n; i++)
{
cin >> arr[i];
}
subsetSums(arr, n);
cout << s.size() << "\n";
for (auto it = s.begin(); it != s.end(); ++it)
cout << *it << " ";
return 0;
}
for example, it gives the wrong answer for
50
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
as
18
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36
the correct output should be:
50
1 2 3 4 ... 50
your code is simply too slow 2^n subsets gives ‭1,267,650,600,228,229,401,496,703,205,376‬ subsets in the worst case (when n=100) while C++ does on average about 1000,000,000 operations per second.
This problem can be solved with dynamic programming, consider having an array dp of size 100001, so that dp[x] denotes if sum of x is possible to achieve.
Base case is easy - sum of 0 is possible without using any coins: dp[0]=1
Then for each coin we can try to increase existing sums by coins value to fill up our table:
for each coinValue:
for coinSum = 100000 - coinValue; coinSum >=0; coinSum--)
if(dp[coinSum])
dp[coinSum + coinValue]=1
Notice that we are looping backwards, this is done on purpose so that each coin gets used only once.
Complexity: O(n^2*maxCoinValue)
Your algorithm is poor, but the reason you're getting wrong results is because you're overflowing int. long long total = 1<<n; shifts an int left by n places, and the fact you're assigning the result to a long long is irrelevant.
You can find problems like this using ubsan. Here's a reproduction of your problem, including warning messages from ubsan:
$ clang++ -fsanitize=undefined a.cpp -o a && ./a
50
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
a.cpp:11:25: runtime error: shift exponent 50 is too large for 32-bit type 'int'
a.cpp:22:24: runtime error: shift exponent 32 is too large for 32-bit type 'int'
18
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36

Why does this new [ ] and delete [ ] implementation break down for integers > 12?

The problem: I need to print the Pascal triangle for any (unsigned int) input passed as a command line argument. All the values must be stored in a LINEAR array and elements must only be manipulated as dereferenced pointers. Following this, the array elements must printed as a lower triangular matrix and subsequently deleted. My implementation functions perfectly for input ranging from 0 to 12 but produces spurious results for higher values.
I tried two different implementations.
Declare a pointer to an array of size (n+1)*(n+2)/2 (which is the number of elements in the triangle for input 'n'). Assign/print variables within a nested loop. Delete the pointer once both loops have been executed.
Run a nested loop, 0 <= i <= n, and 0 <= j <= i. Declare a pointer to an array of size (i+1) in the outer loop. Assign/print elements in the inner loop. Delete the pointer once the inner loop has been executed.
// VERSION 1
unsigned N = (n+1)*(n+2)/2;
unsigned* elements = new unsigned[N];
for(i = 0; i <= n; i++) {
for(j = 0; j <= i; j++) {
*(elements + j+(i*i+i)/2) = fact(i) / (fact(j) * fact(i-j));
// print statement
}
cout << endl;
}
delete [] elements;
// VERSION 2
for(i = 0; i <= n; i++) {
unsigned* elements = new unsigned[i+1];
for(j = 0; j <= i; j++) {
*(elements + j) = fact(i) / (fact(j) * fact(i-j));
// print statement
}
delete [] elements;
cout << endl;
}
Both these versions were tried separately on Xcode. In both cases, the triangle printed correctly until the 12th layer, i.e. n=12, but generated incorrect results for higher values.
0 | 1
1 | 1 1
2 | 1 2 1
3 | 1 3 3 1
4 | 1 4 6 4 1
5 | 1 5 10 10 5 1
6 | 1 6 15 20 15 6 1
7 | 1 7 21 35 35 21 7 1
8 | 1 8 28 56 70 56 28 8 1
9 | 1 9 36 84 126 126 84 36 9 1
10 | 1 10 45 120 210 252 210 120 45 10 1
11 | 1 11 55 165 330 462 462 330 165 55 11 1
12 | 1 12 66 220 495 792 924 792 495 220 66 12 1
13 | 1 4 24 88 221 399 532 532 399 221 88 24 4 1
14 | 1 0 1 5 14 29 44 50 44 29 14 5 1 0 1
15 | 1 1 0 0 2 4 7 9 9 7 4 2 0 0 1 1
16 | 1 0 0 0 0 4 0 1 1 1 0 4 0 0 0 0 1
The debugger, to the extent that I can use it, produced no error messages.
What is happening and how do I fix it?
fact(i) overflows really fast. I haven't checked the numbers, but I'm pretty sure that's what's happening.
Instead, use the fact that a number in Pascal's triangle is the sum of the two numbers above it.
Wikipedia has a nice animation for this.
When i is 13, fact(i) is 6227020800, which is too big to fit in a 32-bit unsigned integer, so integer overflow occurs.

Insertion in std::vector vs. insertion in std::deque

I was solving the puzzles in 2017 Advent of Code. It was necessary to fill in circular buffer using certain algorithm. For the buffer implementation I first used vector, and then I tried with deque. I am getting different results when printing values of the vector and the queue. Here's the code:
#include <iostream>
#include <vector>
void PrintBuffer(std::vector<int> a_CircularBuffer)
{
for (std::vector<int>::iterator it = a_CircularBuffer.begin(); it != a_CircularBuffer.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
}
int main()
{
std::vector<int> circularBuffer;
circularBuffer.reserve(20);
circularBuffer.push_back(0);
circularBuffer.push_back(1);
std::vector<int>::iterator currentPosition = circularBuffer.begin() + 1;
for (int i = 2; i < 20; ++i) {
int steps = 378;
if (steps >= i) {
steps = (steps % i);
}
if ((circularBuffer.end() - currentPosition) <= steps) {
currentPosition = circularBuffer.begin() + (((currentPosition - circularBuffer.begin()) + steps) % i);
circularBuffer.insert(currentPosition, i);
}
else {
currentPosition = currentPosition + steps;
circularBuffer.insert(currentPosition, i);
}
PrintBuffer(circularBuffer);
}
return 0;
}
This is the result when using vector:
0 2 1
0 3 2 1
0 3 2 4 1
0 5 3 2 4 1
0 6 5 3 2 4 1
0 7 6 5 3 2 4 1
0 7 6 8 5 3 2 4 1
0 7 6 9 8 5 3 2 4 1
0 10 7 6 9 8 5 3 2 4 1
0 10 7 6 9 11 8 5 3 2 4 1
0 10 7 6 9 11 8 5 3 2 4 12 1
0 10 7 6 9 11 8 5 3 2 4 12 13 1
0 10 7 6 9 11 8 5 3 2 4 12 14 13 1
15 0 10 7 6 9 11 8 5 3 2 4 12 14 13 1
...
and this is when using deque (just change "vector" to "deque" and comment out circularBuffer.reserve(20) line):
0 2 1
0 3 2 1
0 3 2 4 1
0 5 3 2 4 1
0 5 6 3 2 4 1
0 5 6 7 3 2 4 1
0 5 6 7 3 8 2 4 1
0 5 6 7 3 9 8 2 4 1
0 5 6 10 7 3 9 8 2 4 1
0 5 6 10 7 3 9 8 11 2 4 1
0 5 12 6 10 7 3 9 8 11 2 4 1
0 5 12 6 13 10 7 3 9 8 11 2 4 1
0 5 12 6 13 14 10 7 3 9 8 11 2 4 1
0 5 12 6 13 14 10 7 3 15 9 8 11 2 4 1
...
Why there are different results for vector and deque?
You get undefined behaviour when you insert an element causing reallocation, and then use the old iterator again.
Anything can happen.
Use index to store current position and it'll work the same way.

Pickuping the Common 1d sequence in 1d array's?

How to pick the best uniformed 1d array from the 2d arrays ?
I have two 2d array of : 11 x 10
Example :
4 8 12 12 12 14 16 18 4 1 0
5 7 11 12 13 11 15 18 3 2 1
8 3 12 14 18 19 20 21 8 5 4 ,
8 2 11 12 17 17 19 20 7 4 3 ,
4 7 11 11 11 15 17 19 5 1 1 ,
3 8 11 13 11 15 14 17 4 1 0 ,
4 7 12 13 13 14 16 19 3 1 1 ,
5 9 11 12 13 15 17 19 5 0 1 ,
9 7 25 22 24 18 23 17 3 3 3 ,
4 8 13 13 13 15 17 17 5 2 0 ,
here we have 2d arrays of size 11x10 - Need to analysis and have to find out the common 1d array which has common like.
find the best closing number and its difference- and keep doing for all the corresponding columns in an array .
below answer should be like - finding the corresponding very column and comparing with the next row column - if it has some difference below ( 5 ) take the both column of two rows are same and process for next column of the same row..process untill finding the 1 row where it has at least nearby matches of 5
4 8 11 12 13 13 15 18 4 1 0
why don't you do something like this
int[] count(int[][] array)
int result[11];
for(int x = o; x<= 11;x++)
{
int temp[10];
for(int y = o; y<= 10;y++)
{
temp[y] = array[y][x];
}
result[x] = getHighest(temp);
}
return result;
}
int getHighest(int[] array)
{
int size = array.length;
int[size][1] temp;
for(int x; x<= size;x++)
{
int z = array[x];
temp[z][0]++;
}
int highest = -1;
for(int z; z<= size;z++)
{
int z = array[x];
int h = temp[z][0];
if(h > highest)
{
highest = h;
}
}
return highest;
}
Something like this, but my C++ has gotten a bit of rusty so sorry if there are any mistakes.