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;
}