Counting sort not sorting correctly - c++

I have written this counting sort algorithm, but am not sure why it isn't working... Could anyone check and give me a few pointers on what to fix? Thanks!
#include <iostream>
using namespace std;
int main(){
int arr[10] = {1434, 1415, 1217, 4218, 3618, 176, 1021, 3785, 1891, 1522};
int C[4219];
for (int i = 0; i < 4219; ++i) {
C[i] = 0;
}
for (int j = 0; j < 10; ++j) {
C[arr[j]] = C[arr[j]] + 1;
}
for (int k = 10; k > 0; --k) {
C[k] = C[k] + C[k + 1];
}
int B[10];
for (int l = 0; l < 10; ++l) {
B[C[arr[l]] - 1] = arr[l];
C[arr[l]] = C[arr[l]] - 1;
}
for (int m = 0; m < 10; ++m) {
cout << B[m] << " ";
}
return 0;
}

The problem is in the third loop. You iterate only through 10 elements of the array C.

You had created small mistake in the code.....
#include <iostream>
using namespace std;
int main(){
int arr[10] = {1434, 1415, 1217, 4218, 3618, 176, 1021, 3785, 1891, 1522};
int C[4219];
for (int i = 0; i < 4219; ++i) {
C[i] = 0;
}
for (int j = 0; j < 10; ++j) {
C[arr[j]] = C[arr[j]] + 1;
}
for (int k = 1; k < 4219; ++k) { // mistake
C[k] = C[k] + C[k - 1];
}
int B[10];
for (int l = 9; l >=0; --l) { // suggestion
B[C[arr[l]] - 1] = arr[l];
C[arr[l]] = C[arr[l]] - 1;
}
for (int m = 0; m < 10; ++m) {
cout << B[m] << " ";
}
return 0;
}
Beside that I would like to give you one suggestion that in the loop traverse from right to left as it will maintain the stability of the sort..
Stability means suppose if array has two or more same element then in the stable sort,element which is before in unsorted array will occur first in sorted array.

Related

Return matrix from function with variable lenght

I want to return the matrix from the function, but I can't find a way how. I've found some ways, but they can't be used for VLA. I've read about using std::vector, but that also didn't work.
int gengrid(int gridsize)
{
gridsize = 10 - 1;
int grid[gridsize+3][gridsize+3];
srand(time(NULL));
int count = 0;
std::fill_n(grid[0], 12, 0);
for(int i = 1; i < gridsize + 2; i++)
{
grid[i][0] = 0;
for(int j = 1; j < gridsize + 2; j++)
{
grid[i][j] = rand()%2;
}
grid[i][gridsize+2] = 0;
}
std::fill_n(grid[gridsize+2], gridsize + 3, 0);
return grid;
}
Okay, I found out my solution.
I initialize vector matrix with
static std::vector<std::vector<int>> grid(gridsize+3, std::vector<int>(gridsize+3));
which sets 0 by default for all elements.
(honestly, I don't know, how it's working, maybe somebody would comment explanation of this behavior.)
Complete code here:
#include <iostream>
#include <time.h>
#include <vector>
std::vector<std::vector<int>> gengrid(int gridsize)
{
gridsize = 10 - 1;
static std::vector<std::vector<int>> grid(gridsize+3, std::vector<int>(gridsize+3));//[gridsize+3][gridsize+3];
srand(time(NULL));
int count = 0;
for(int i = 1; i < gridsize + 2; i++)
{
grid[i][0] = 0;
for(int j = 1; j < gridsize + 2; j++)
{
grid[i][j] = rand()%2;
}
grid[i][gridsize+2] = 0;
}
return grid;
}
int main()
{
std::vector<std::vector<int>> grid = gengrid(10);
for(int i = 0; i < 9 + 3; i++)
{
for(int j = 0; j < 9 + 3; j++)
{
std::cout << grid[i][j];
}
std::cout << std::endl;
}
return 0;
}

unable to sort an array, wrong output

#include<bits/stdc++.h>
using namespace std;
int
main ()
{
int a[3] = { 3, 2, 1 }, i, j, t = 0, k = 0;
int m;
for (int i = 0; i < 2; i++)
{
m = a[i];
for (int j = i++; j < 3; j++)
{
if (m > a[j])
{
m = a[j];
k = j;
}
}
t = a[i];
a[i] = m;
a[k] = t;
}
for (int i = 0; i < 3; i++)
{
cout << a[i];
}
return 0;
}
You seem to want to implement an insertion sort algorithm by hand. For this task, you should consider using std::sort. I refactored your code such that it basically does the same thing as you wanted and included some tips to make the code more readable and easier to debug for you and others:
#include <algorithm> //only include necessary headers
#include <iostream>
//do not use "using namespace std"
int main ()
{
int a[3] = { 3, 2, 1 };
/*
Declare local variables at the first point they are used an as local as possible.
It is much easier to read, if a no longer necessary variables leaves scope.
*/
for (int i = 0; i < 2; i++) {
int min = a[i]; //use names that tell something about what you are doing
int bestIndex = i;
for (int j = i+1; j<3; j++) { //here was your major bug: i++ also increcments i
if (a[j] < min){
min = a[j];
bestIndex = j;
}
}
std::swap(a[i], a[bestIndex]);
//try to use standard algorithms as often as possible. They document your code, are optimized and easier to read.
}
for (int i = 0; i < 3; i++){
std::cout << a[i];
}
return 0;
}
Look at this:
for (int i = 0; i < 2; i++)
{
for (int j = i++; j < 3; j++)
{
}
}
On the first iteration of the outer loop:
i is 0.
Then the inner loop increments it to 1.
Then the outer loop increments it to 2.
Then the outer loop is done, after just one iteration.
You want i+1 in the inner loop, not i++.
#include<bits/stdc++.h>
using namespace std;
int main ()
{
int a[3] = { 3,2,1}, t = 0, k = 0;
int m=0;
bool flag_change =false;
for (int i = 0; i < 2; i++)
{
m = a[i];
for (int j = i+1; j < 3; j++)
{
if (m < a[j]) //changing sing (<>) sort by ascending/sort by descending order
{
m = a[j];
k = j;
flag_change = true;
}
}
if(flag_change)
{
t = a[i];
a[i] = m;
a[k] = t;
flag_change = false;
}
}
for (int i = 0; i < 3; i++)
{
cout << a[i];
}
return 0;
}
I'm done correct you code. Code is working.But it is not good implementation.

unable to change value of integer after looping, C++

At the start of my program I declare the variables i and j.
int i, j;
In the course of execution, I use the variable names i and j as a oop index variables too. I realize this is probably not the best choice in terms of clarity, but as this is a toy project I thought it wouldn't matter.
The problem is, after the following loop that prints the contents of an array to a txt file, i == N == 29:
ofstream a_file("2d_array.txt");
for (int i = 0; i<N; ++i) {
for (int j = 0; j<N; ++j)
a_file << m[i][j] << ' ';
a_file << endl;
}
When I try to use i again later in the program:
for (int num_slices_processed = h + 1; num_slices_processed < N;
num_slices_processed++){
i = 0;
j = num_slices_processed;
...
i remains set to 29, even after the line that should set it to 0. j is set correctly though. What is happening here?
Here is all the code up to the problem section:
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
int smallest(int x, int y, int z);
bool basesMatch(char b1, char b2);
int main() {
const int N = 29;
int h, l, mm;
int i, j;
l = 10;
mm = 2;
h = 5;
int m[N][N];
//initialize m
for (int i = 0; i < N; i++){
for (int j = i; j < N; j++) {
if (j-i <= h)
m[i][j] = 0;
}
}
ofstream a_file("2d_array.txt");
for (int i = 0; i<N; ++i) {
for (int j = 0; j<N; ++j)
a_file << m[i][j] << ' ';
a_file << endl;
}
for (int num_slices_processed = h + 1; num_slices_processed < N; num_slices_processed++){
//while j is in bounds, ie j < N. This fills in one diagonal slice of m from L->R top -> bottom.
i = 0; //************ i is not being set here
j = num_slices_processed;
while (j < N) {
if (basesMatch(seq[i], seq[j])) {
t = m[i + 1][j - 1];
m[i][j] = m[i + 1][j - 1];
}
else {//bases don't match
m[i][j] = smallest(m[i + 1][j] + 1, m[i][j - 1] + 1, m[i + 1][j - 1] + 1);
}
i++;
j++;
}
}
Check to see if it even enters the loop. num_slices_processed could be null or already < N, so you are never hitting the assignment statement.

C++: Sorting strings using LSD radix sort crashing

I have written some code that is meant to sort an array of strings using the radix sort, starting with the least significant digit. This function assumes all of the strings are the same length and each character is lowercase.
I am encountering crashes whenever I get to the loop in which I assign values to the temporary array. You can see my function here:
#ifndef RADIX_H
#define RADIX_H
#include <string>
#include <iostream>
using namespace std;
void lsd_string_radix(string array[], int array_size, int max_chars)
{
string *temp = new string[array_size];
for(int i = max_chars - 1; i >= 0; i--)
{
int count[26] = {0};
for(int j = 0; j < array_size; j++)
{
count[static_cast<int>(array[j][i]) - 97]++;
}
for(int j = 1; j <= 26; j++)
{
count[j] += count[j - 1];
}
for(int j = 0; j < array_size; j++)
{
temp[count[static_cast<int>(array[j][i])]++] = array[j]; // crashes here
}
for(int j = 0; j < array_size; j++)
{
array[j] = temp[j];
}
}
}
#endif
I'm guessing I have a failing in logic but I can't figure it out for the life of me.
After the second loop, count[0] should be zero, and the third loop is missing a -97. This example fixes the problem using count of size 27 instead of 26. The first loop in this example uses -96, so count[0] = 0, count[1] = # instances of 'a's, count[2] = # instances of 'b's, ... . count[26] = # instances of 'z's but it's only used in the first loop. It's not needed, but it's simpler to put a count of 'z's there rather than adding an if statement to avoid storing a count at count[26].
#include<iomanip>
#include<iostream>
#include <string>
using namespace std;
void lsd_string_radix(string array[], int array_size, int max_chars)
{
string *temp = new string[array_size];
for(int i = max_chars - 1; i >= 0; i--)
{
int count[27] = {0};
for(int j = 0; j < array_size; j++)
count[static_cast<int>(array[j][i]) - 96]++;
for(int j = 2; j < 26; j++)
count[j] += count[j - 1];
for(int j = 0; j < array_size; j++)
temp[count[static_cast<int>(array[j][i]) - 97]++] = array[j];
for(int j = 0; j < array_size; j++)
array[j] = temp[j];
}
}
int main()
{
string a[6] = {"mnop", "ijkl", "efgh", "uvwx", "qrst", "abcd"};
lsd_string_radix(a, 6, 4);
for(size_t i = 0; i < 6; i++)
cout << a[i] << endl;
return 0;
}
If the size of count[] is to be 26, the first loop needs to be modified:
for(int j = 0; j < array_size; j++){
if(array[j][i] == 'z')continue;
count[static_cast<int>(array[j][i]) - 96]++;
}
or the first two loops are modified:
for(int j = 0; j < array_size; j++)
count[static_cast<int>(array[j][i]) - 97]++;
int m = 0;
int n;
for(int j = 0; j < 26; j++){
n = count[j];
count[j] = m;
m += n;
}

Find a subarray of m*m (2<=m<n) having largest sum; out of an n*n int array(having +ve, -ve, 0s)

I have written a solution for the above problem but can someone please suggest an optimized way.
I have traversed through the array for count(2 to n) where count is finding subarrays of size count*count.
int n = 5; //Size of array, you may take a dynamic array as well
int a[5][5] = {{1,2,3,4,5},{2,4,7,-2,1},{4,3,9,9,1},{5,2,6,8,0},{5,4,3,2,1}};
int max = 0;
int **tempStore, size;
for(int count = 2; count < n; count++)
{
for(int i = 0; i <= (n-count); i++)
{
for(int j = 0; j <= (n-count); j++)
{
int **temp = new int*[count];
for(int i = 0; i < count; ++i) {
temp[i] = new int[count];
}
for(int k = 0; k < count; k++)
{
for(int l = 0; l <count; l++)
{
temp[k][l] = a[i+k][j+l];
}
}
//printing fetched array
int sum = 0;
for(int k = 0; k < count; k++)
{
for(int l = 0; l <count; l++)
{
sum += temp[k][l];
cout<<temp[k][l]<<" ";
}cout<<endl;
}cout<<"Sum = "<<sum<<endl;
if(sum > max)
{
max = sum;
size = count;
tempStore = new int*[count];
for(int i = 0; i < count; ++i) {
tempStore[i] = new int[count];
}
//Locking the max sum array
for(int k = 0; k < count; k++)
{
for(int l = 0; l <count; l++)
{
tempStore[k][l] = temp[k][l];
}
}
}
//printing finished
cout<<"------------------\n";
//Clear temp memory
for(int i = 0; i < size; ++i) {
delete[] temp[i];
}
delete[] temp;
}
}
}
cout<<"Max sum is = "<<max<<endl;
for(int k = 0; k < size; k++)
{
for(int l = 0; l <size; l++)
{
cout<<tempStore[k][l]<<" ";
}cout<<endl;
}cout<<"-------------------------";
//Clear tempStore memory
for(int i = 0; i < size; ++i) {
delete[] tempStore[i];
}
delete[] tempStore;
Example:
1 2 3 4 5
2 4 7 -2 1
4 3 9 9 1
5 2 6 8 0
5 4 3 2 1
Output:
Max sum is = 71
2 4 7 -2
4 3 9 9
5 2 6 8
5 4 3 2
This is a problem best solved using Dynamic Programming (DP) or memoization.
Assuming n is significantly large, you will find that recalculating the sum of every possible combination of matrix will take too long, therefore if you could reuse previous calculations that would make everything much faster.
The idea is to start with the smaller matrices and calculate sum of the larger one reusing the precalculated value of the smaller ones.
long long *sub_solutions = new long long[n*n*m];
#define at(r,c,i) sub_solutions[((i)*n + (r))*n + (c)]
// Winner:
unsigned int w_row = 0, w_col = 0, w_size = 0;
// Fill first layer:
for ( int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) {
at(r, c, 0) = data[r][c];
if (data[r][c] > data[w_row][w_col]) {
w_row = r;
w_col = c;
}
}
}
// Fill remaining layers.
for ( int size = 1; size < m; size++) {
for ( int row = 0; row < n-size; row++) {
for (int col = 0; col < n-size; col++) {
long long sum = data[row+size][col+size];
for (int i = 0; i < size; i++) {
sum += data[row+size][col+i];
sum += data[row+i][col+size];
}
sum += at(row, col, size-1); // Reuse previous solution.
at(row, col, size) = sum;
if (sum > at(w_row, w_col, w_size)) { // Could optimize this part if you only need the sum.
w_row = row;
w_col = col;
w_size = size;
}
}
}
}
// The largest sum is of the sub_matrix starting a w_row, w_col, and has dimensions w_size+1.
long long largest = at(w_row, w_col, w_size);
delete [] sub_solutions;
This algorithm has complexity: O(n*n*m*m) or more precisely: 0.5*n*(n-1)*m*(m-1). (Now I haven't tested this so please let me know if there are any bugs.)
Try this one (using naive approach, will be easier to get the idea):
#include <iostream>
#include<vector>
using namespace std;
int main( )
{
int n = 5; //Size of array, you may take a dynamic array as well
int a[5][5] =
{{2,1,8,9,0},{2,4,7,-2,1},{5,4,3,2,1},{3,4,9,9,2},{5,2,6,8,0}};
int sum, partsum;
int i, j, k, m;
sum = -999999; // presume minimum part sum
for (i = 0; i < n; i++) {
partsum = 0;
m = sizeof(a[i])/sizeof(int);
for (j = 0; j < m; j++) {
partsum += a[i][j];
}
if (partsum > sum) {
k = i;
sum = partsum;
}
}
// print subarray having largest sum
m = sizeof(a[k])/sizeof(int); // m needs to be recomputed
for (j = 0; j < m - 1; j++) {
cout << a[k][j] << ", ";
}
cout << a[k][m - 1] <<"\nmax part sum = " << sum << endl;
return 0;
}
With a cumulative sum, you may compute partial sum in constant time
std::vector<std::vector<int>>
compute_cumulative(const std::vector<std::vector<int>>& m)
{
std::vector<std::vector<int>> res(m.size() + 1, std::vector<int>(m.size() + 1));
for (std::size_t i = 0; i != m.size(); ++i) {
for (std::size_t j = 0; j != m.size(); ++j) {
res[i + 1][j + 1] = m[i][j] - res[i][j]
+ res[i + 1][j] + res[i][j + 1];
}
}
return res;
}
int compute_partial_sum(const std::vector<std::vector<int>>& cumulative, std::size_t i, std::size_t j, std::size_t size)
{
return cumulative[i][j] + cumulative[i + size][j + size]
- cumulative[i][j + size] - cumulative[i + size][j];
}
live example