Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

print string based on the frequency of character in C

I was solving the question of leet code in C

Question:

Given a string s, sort it in decreasing order based on the frequency of the characters. The frequency of a character is the number of times it appears in the string.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Return the sorted string. If there are multiple answers, return any of them.

Example 1:

Input: s = "tree"
Output: "eert"
Explanation: 'e' appears twice while 'r' and 't' both appear once.
So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer.

I tried to use the different approach instead taking the array[255] and increasing the array value in specific char ASCII index. But I m getting segmentation fault. I not understand why I m getting segmentation voilation. Only assumption I made here is input str always be in UPPER CASE.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *frequencySort(char *s)
{
    int strlenn = strlen(s);

    int fq[strlenn];

    // init with 1 because at least 1 time char occur in input str.
    for (int i = 0; i < strlenn; i++)
    {
        fq[i] = 1;
    }
    // count freq of string and replace dublicate char with *
    // ex: ABCDA => ABCD*
    for (int i = 0; i < strlenn - 1; i++)
    {
        if (s[i] == '*')
        {
            continue;
        }

        for (int j = (i + 1); j < strlenn; j++)
        {
            if (s[i] == s[j])
            {
                fq[i]++;
                s[j] = (char)'*';  // segmentation violation error shows here
                fq[j] = 0;
            }
        }
    }

    
    // sort freqency by in decending order and str char
    // ex: ABCDDDAA =  freq[3, 3, 1, 1] =  soredt str = [ A, D, B, C ]
    for (int i = 0; i < strlenn - 1; i++)
    {
        for (int j = i + 1; j < strlenn; j++)
        {
            if (fq[i] < fq[j])
            {
                // swap
                int temp = fq[i];
                fq[i] = fq[j];
                fq[j] = temp;

                // swap string char
                char temp1 = s[i];
                s[i] = s[j]; // segmentation violation error shows here
                s[j] = temp1;
            }
        }
    }
    char *result = (char *)calloc(strlenn + 1, sizeof(char));
    int l = 0;
    for (int i = 0; fq[i] != 0 && i < strlenn; i++)
    {
        int k = fq[i];

        while (k > 0)
        {
            printf("%c", s[i]);
            result[l++] = s[i];
            k--;
        }
    }
    result[l] = '\0';
    return result;
}

int main()
{

    char *s = "ABCDDDAA";
    frequencySort(s);

    return 0;
}

Thanks!

>Solution :

In frequencySort, you are modifying s (e.g.):

s[j] = (char)'*';  // segmentation violation error shows here

In main, the s argument comes from:

char *s = "ABCDDDAA";
frequencySort(s);

Here s is function scoped and goes on the stack.

But, because this is a pointer to a string literal, the actual string data goes into the .rodata section. This is mapped as read only. So, when we try to change it, we get a protection exception.

To fix this, define a string array:

char s[] = "ABCDDDAA";
frequencySort(s);

Now the literal data is [still] in the .rodata section. But, when main starts up, it is copied into the s array which is on the stack [which is writable].

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading