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.
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!
CodePudding user response:
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].