Find character frequency in a string - c

Im trying to find character frequency in a string,i wrote the following code,but it does'nt show any output.All im trying is to fill the character array with respective counts.
When i tried to debug,it some how gives output,but prints some garbage value.
#include<stdio.h>
/* Program for printing character frequency in string */
charcount(char *,int *);
int main()
{
int n,i=0;
printf("Enter n :");
scanf("%d",&n);
char var[n];
int count[100]; // array for storing character frequency
printf("Enter string :");
fflush(stdin);
scanf("%s",var);
charcount(var,count); // calling frequeny function
for(i=0;i<strlen(count);i++)
{
printf("%d\n",count[i]);
}
getch();
return 0;
}
charcount(char *p,int *q)
{
for(;*p;p++)
{
q[*p]++;
}
}

You have few problems in your code:
count array is not initialized.
You are applying strlen() on an integer array.
count array should be 256 (count[256]) to cover all possible ascii chars. For example, if your input is abcd you'll go out of bound of array as d is 100.
You are printing the wrong count:
printf("%d\n",count[i]); should be printf("%d\n",count[var[i]]);
Declare proper prototype for charcount().
After fixing these:
#include<stdio.h>
/* Program for printing character frequency in string */
void charcount(char *,int *);
int main()
{
int n,i=0;
printf("Enter n :");
scanf("%d",&n);
char var[n];
int count[256]={0}; // array for storing character frequency
printf("Enter string :");
scanf("%s",var);
charcount(var,count); // calling frequeny function
for(i=0;i<strlen(var);i++)
{
printf("%d\n",count[var[i]]);
}
return 0;
}
void charcount(char *p,int *q)
{
for(;*p;p++)
{
q[*p]++;
}
}
Make sure to compile in C99 or C11 (e.g. gcc -std=c99 file.c) mode as VLAs are not supported in earlier standards of C.

You need to initialize your count array. Otherwise it will have garbage values in it by default. You can initialize the whole array to 0 like so:
int count[100] = {0};

Your count array may not be large enough to hold all printable values (even assuming ASCII), and it should be 0 initialized. Your for loop should be checking against the length of var, not count, since you cannot sensibly treat the count integer array as a string.
int count[1<<CHAR_BIT] = {};
/*...*/
for(i=0;i<strlen(var);i++)
{
printf("%d\n",count[var[i]]);
}
Well, it really depends on what you want to output. If you intend to output all of count, then:
for(i=0;i<sizeof(count)/sizeof(count[0]);i++)
{
printf("%d\n",count[i]);
}

int count is nothing but a hashmap
Your code will not work for this string "abcd"
count['a'] = val // Works fine ASCII value of a is 97
count['b'] = val // Works fine ASCII value of a is 98
count['c'] = val // Works fine ASCII value of a is 99
count['d'] = val ; // Undefined Behaviour ASCII value of d is 100
The size should be equal to ASCII set length
int count[128] = {};

JAVA program to print "*" as much times as the occurrence of a character in String.
Or char_in_String : frequency of char_in_String
Instead of * you can print frequency count
public class CharFreq
{
public static void main(String[] args)
{
String s = "be yourself "; System.out.println(s);
int r=0;
char[] str = s.toCharArray();
for (int i = 0; i < str.length; i++)
{
int cnt = 0;
if (str[i] != ' ')
{
for (int j = 0; j < str.length; j++)
{
if (str[i] == str[j])
{
cnt++; r=j;
}
}
if(i==r)
{
System.out.print(str[i] + ":");
for (int k = 1; k <=cnt; k++)
System.out.print("*");
System.out.println();
}
}
}
}
}
Output:
be yourself
b:*
y:*
o:*
u:*
r:*
s:*
e:**
l:*
f:*

Your count[100] is not large enough. Assume you only enter "A - Z" or "a - z" it's still not large enough because 'z' is 122, then your charcount will increase count[122].
You should consider change int count[100] to int count[128] = { 0 }

Related

How to check first letter of one string with last letter of another string inside of same char array

How can I complete the function canArrangeWords() ?
Question : Given a set of words check if we can arrange them in a list such that the last letter of any word and first letter of another word are same. The input function canArrangeWords shall contain an integer num and array of words arr. num denotes the number of word in the list (1<=num<=100). arr shall contain words consisting of lower case letters between 'a' - 'z' only . return 1 if words can be arranged in that fashion and -1 if cannot.
Input : 4 pot ten nice eye
output : 1
input : 3 fox owl pond
output: -1
Please help me complete this program .
**
#include<stdio.h>
#include<string.h>
int canArrangewords(int,char [100][100]);
void main(){
int n ,count=0 , i ;
char arrayS[100][100];
scanf("%d",&n);
for (i = 0; i < n; ++i)
{
scanf("%s",arrayS[i]);
}
for(i=0;i<n;i++)
{
printf("%s",arrayS[i]);
printf("\n");
}
printf("%c\n",arrayS[2][4]);
canArrangewords(n , arrayS);
}
int canArrangewords(int n,char arrayS[100][100]){
int i , j ;
for ( i = 0; i < n; i++)
{
for ( j = i+1 ; j < strlen(arrayS[j+1]); i++)
{
int flag = strlen(arrayS[j+1]) - 1;
int temp = strcmp(arrayS[i][0],arrayS[j][flag]);
}
}
}
}
Well, first of all think of the way you can reach that answer.
If you only need to know if they can or can not be arranged and you do not have to do so your self you can use an empty array of int array[26] for each letter a-z.
The rule is that from all the first and last letters for all the words only two MAY appear an odd amount of times - the first letter of first word in list and the last letter in the last word in the list, the rest MUST appear an even amount of times. I would add a check to make sure the letters are lowercase as well. good luck!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MINASCII 97
#define LETTERS 26
void UpdateArray(char letter, int* arr)
{
if(arr[letter - MINASCII] == 0)
{
++arr[letter - MINASCII];
}
else
{
--arr[letter - MINASCII];/*for each second time same letter is seen reduce back to zero */
}
}
int canArrangewords(int wordNum, char* wordArr[])
{
int arr[LETTERS] = {0};
int i = 0;
int count = 0 ;
char first;
char last;
char* string;
for (i= 0; i< wordNum; ++i)
{
string = wordArr[i];
first = string[0];
last = string[strlen(string)-1];
UpdateArray(first, &arr[0]);
UpdateArray(last, &arr[0]);
}
for(i = 0; i< LETTERS; ++i)
{
count+=arr[i];
}
if(count == 2 || count == 0)/*either once each or twice -see word1 example in main*/
{
return 1;
}
return -1;
}
int main()
{
int i = 0;
char* words[] = {"pot", "ten", "nice", "eye"};
char* words1[] = {"pot", "ten", "nip"};
char* words2[] = {"fox", "owl", "pond"};
i = canArrangewords(4,words);
printf("%d\n", i);
i = canArrangewords(3,words1);
printf("%d\n", i);
i = canArrangewords(3,words2);
printf("%d\n", i);
return 0;
}
Change your array of words into an array of pointers to words. Then you can simply exchange the pointers.
To speed things up, instead of a pointer to a word, have it point to a structure:
struct WORD {
char *firstchar; // begin of word
char *lastchar; // last char of word
} *words[100]; // array of 100 pointers to words
To read the words:
char buf[100];
for (i = 0; i < n; ++i)
{
scanf("%s",buf);
int len= strlen(buf);
words[i]= malloc(sizeof(struct WORDS));
words[i]->firstchar= malloc(len+1);
strcpy(words[i]->firstchar, buf);
words[i]->lastchar= words[i]->firstchar + len-1;
}
Now compare and sort:
if (*words[i]->lastchar == *words[j]->firstchar) {
struct WORDS *tmp= words[i+1];
words[i+1]= words[j];
words[j]= tmp;
}
Do this in a loop, a kind of bubble sort. I leave that to you.

Understanding returning values functions C

I'm trying to understand how the return value of a function works, through the following program that has been given to me,
It goes like this :
Write a function that given an array of character v and its dim, return the capital letter that more often is followed by its next letter in the alphabetical order.
And the example goes like : if I have the string "B T M N M P S T M N" the function will return M (because two times is followed by N).
I thought the following thing to create the function:
I'm gonna consider the character inserted into the array like integer thank to the ASCII code so I'm gonna create an int function that returns an integer but I'm going to print like a char; that what I was hoping to do,
And I think I did, because with the string BTMNMPSTMN the function prints M, but for example with the string 'ABDPE' the function returns P; that's not what I wanted, because should return 'A'.
I think I'm misunderstanding something in my code or into the returning value of the functions.
Any help would be appreciated,
The code goes like this:
#include <stdio.h>
int maxvolte(char a[],int DIM) {
int trovato;
for(int j=0;j<DIM-1;j++) {
if (a[j]- a[j+1]==-1) {
trovato=a[j];
}
}
return trovato;
}
int main()
{
int dim;
scanf("%d",&dim);
char v[dim];
scanf("%s",v);
printf("%c",maxvolte(v,dim));
return 0;
}
P.S
I was unable to insert the value of the array using in a for scanf("%c,&v[i]) or getchar() because the program stops almost immediately due to the intepretation of '\n' a character, so I tried with strings, the result was achieved but I'd like to understand or at least have an example on how to store an array of character properly.
Any help or tip would be appreciated.
There are a few things, I think you did not get it right.
First you need to consider that there are multiple pairs of characters satisfying a[j] - a[j+1] == -1
.
Second you assume any input will generate a valid answer. That could be no such pair at all, for example, ACE as input.
Here is my fix based on your code and it does not address the second issue but you can take it as a starting point.
#include <stdio.h>
#include <assert.h>
int maxvolte(char a[],int DIM) {
int count[26] = {0};
for(int j=0;j<DIM-1;j++) {
if (a[j] - a[j+1]==-1) {
int index = a[j] - 'A'; // assume all input are valid, namely only A..Z letters are allowed
++count[index];
}
}
int max = -1;
int index = -1;
for (int i = 0; i < 26; ++i) {
if (count[i] > max) {
max = count[i];
index = i;
}
}
assert (max != -1);
return index + 'A';
}
int main()
{
int dim;
scanf("%d",&dim);
char v[dim];
scanf("%s",v);
printf("answer is %c\n",maxvolte(v,dim));
return 0;
}
#include <stdio.h>
int maxvolte(char a[],int DIM) {
int hold;
int freq;
int max =0 ;
int result;
int i,j;
for(int j=0; j<DIM; j++) {
hold = a[j];
freq = 0;
if(a[j]-a[j+1] == -1) {
freq++;
}
for(i=j+1; i<DIM-1; i++) { //search another couple
if(hold==a[i]) {
if(a[i]-a[i+1] == -1) {
freq++;
}
}
}
if(freq>max) {
result = hold;
max=freq;
}
}
return result;
}
int main()
{
char v[] = "ABDPE";
int dim = sizeof(v) / sizeof(v[0]);
printf("\nresult : %c", maxvolte(v,dim));
return 0;
}

First Not Repeating Character Code

Here is the question:
Write a solution that only iterates over the string once and uses O(1) additional memory, since this is what you would be asked to do during a real interview.
Given a string s, find and return the first instance of a non-repeating character in it. If there is no such character, return '_'.
And here is my code:
char firstNotRepeatingCharacter(char * s) {
int count;
for (int i=0;i<strlen(s);i++){
count=0;
char temp=s[i];
s[i]="_";
char *find= strchr(s,temp);
s[i]=temp;
if (find!=NULL) count++;
else return s[i];
}
if (count!=0) return '_';
}
I dont know what's wrong but when given an input:
s: "abcdefghijklmnopqrstuvwxyziflskecznslkjfabe"
the output is for my code is "g" instead of "d".
I thought the code should have escaped the loop and return "d" soon as "d" was found.
Thx in advance!!!
In your program, problem is in this statement-
s[i]="_";
You are assigning a string to a character type variable s[i]. Change it to -
s[i]='_';
At the bottom of your firstNotRepeatingCharacter() function, the return statement is under the if condition and compiler must be giving a warning for this as the function is supposed to return a char. Moreover, count variable is not needed. You could do something like:
char firstNotRepeatingCharacter(char * s) {
for (int i=0;i<strlen(s);i++){
char temp=s[i];
s[i]='_';
char *find= strchr(s,temp);
s[i]=temp;
if (find==NULL)
return s[i];
}
return '_';
}
But this code is using strchr inside the loop which iterates over the string so, this is not the exact solution of your problem as you have a condition that - the program should iterates over the string once only. You need to reconsider the solution for the problem.
May you use recursion to achieve your goal, something like - iterate the string using recursion and, somehow, identify the repetitive characters and while the stack winding up identify the first instance of a non-repeating character in the string. It's implementation -
#include <stdio.h>
int ascii_arr[256] = {0};
char firstNotRepeatingCharacter(char * s) {
char result = '-';
if (*s == '\0')
return result;
ascii_arr[*s] += 1;
result = firstNotRepeatingCharacter(s+1);
if (ascii_arr[*s] == 1)
result = *s;
return result;
}
int main()
{
char a[] = "abcdefghijklmnopqrstuvwxyziflskecznslkjfabe";
printf ("First non repeating character: %c\n", firstNotRepeatingCharacter(a));
return 0;
}
In the above code, firstNotRepeatingCharacter() function iterates over the string only once using recursion and during winding up of the stack it identifies the first non-repetitive character. I am using a global int array ascii_arr of length 256 to keep the track of non-repetitive character.
Java Solution:
Time Complexity: O(n)
Space Complexity: with constant space as it will only use more 26 elements array to maintain count of chars in the input
Using Java inbuilt utilities : but for inbuilt utilities time complexity is more than O(n)
char solution(String s) {
char[] c = s.toCharArray();
for (int i = 0; i < s.length(); i++) {
if (s.indexOf(c[i]) == s.lastIndexOf(c[i]))
return c[i];
}
return '_';
}
Using simple arrays. O(n)
char solution(String s) {
// maintain count of the chars in a constant space
int[] base = new int[26];
// convert string to char array
char[] input = s.toCharArray();
// linear loop to get count of all
for(int i=0; i< input.length; i++){
int index = input[i] - 'a';
base[index]++;
}
// just find first element in the input that is not repeated.
for(int j=0; j<input.length; j++){
int inputIndex = input[j]-'a';
if(base[inputIndex]==1){
System.out.println(j);
return input[j];
}
}
return '_';
}

Load numbers from input into array

I have given input which contains data that I am going to process and saved into an array. The input looks like this :
{ [1, 10], [2,1] , [-10, 20] }
it can have more elements in it. I need to process it that I can load all numbers from [ number , number ] into 2d array , first number should be at 0th and second number should be at 1st index so this array should look like
[[1,10],[2,1],[-10,20]]
But I've failed to find the solution, how to process this input into my desired array. What is the right way to do it?
I tried to do as following:
int main()
{
long long int cisla[10][2];
int x;
int y;
int i;
int index=0;
int counter=0;
char c;
char zatvorka_one;
char zatvorka_three;
char ciarka;
char ciarka_two;
printf("Pozicia nepriatela\n");
c=getchar();
if(c!='{'){
return 0;
}
scanf(" %c%d,%d%c",&ciarka,&x,&y,&zatvorka_one);
cisla[index][0]=x;
cisla[index][1]=y;
index++;
while(1){
scanf("%c",&ciarka);
if(ciarka=='}'){
break;
}
scanf(" %c%d%,%d%c",&ciarka,&x,&y,&zatvorka_one);
cisla[index][0]=x;
cisla[index][1]=y;
index++;
}
for ( i = 0; i < index; i++){
printf("%d %d\n",cisla[i][0],cisla[i][1]);
}
}
But somehow it returns unexpected result, how can i fix it?
You should use gets instead of scanf. gets will return the entire string wich will be easear. Then you ahould read about strtok wich can be used to separate a string. For example: strtok(s,",") will separate your string into smaller strings. For the input {[12,4], [8,9]} will divide into: first string: {[12 second string: 4] third string [8 and fourth string 9]}. Now you will just have to remove the characters that are not numbers like { } and []. After that you will have strings only with the numbers so you can use another predefined fuction you should read abput called atoi. It recieves a string and turns it into an int (ascci to int). There is also an atof (ascci to float) if you need it. Tuturialpoints is a good place to look for examples on how to use these functions i mentioned.
I'm relatively new to C and SO. Maybe I shouldn't give you the solution, but I did. It follows the advice of sharp c student.
You could try to do it like this:
#include "stdafx.h"
#include "string.h"
#include "stdlib.h"
#define MAXNBRELM 10 // maximum number of elements; adjust as needed
int main()
{
int IntArr[MAXNBRELM][2]; // integer array to hold results
int s = 0; // subscript
int NbrElm; // number of elements found
char Buf[81]; // buffer to hold input
char * StrPtr; // pointer to string for fgets
char * TknChr; // each individual token
char * NxtTkn; // next token position (only needed for Visual C++)
StrPtr = fgets(Buf, 80, stdin);
TknChr = strtok_s(Buf, " {[,]}", &NxtTkn);
while (s <= MAXNBRELM && TknChr != NULL) {
IntArr[s][0] = atoi(TknChr);
TknChr = strtok_s(NULL, " {[,]}", &NxtTkn);
if (TknChr != NULL) {
IntArr[s][1] = atoi(TknChr);
TknChr = strtok_s(NULL, " {[,]}", &NxtTkn);
s++;
}
}
NbrElm = s;
for (s = 0; s < NbrElm; s++)
printf("%d %d\n", IntArr[s][0], IntArr[s][1]);
return 0;
}
This is for Visual Studio, is why I needed to use strtok_s and &NxtTkn.

find biggest index of something in c

I want to write a function that finds the biggest index of the character in a string. But when the index is already found once, it may not return it.
For example:
word: "hello"
character: l
indexset={};
expected return value = 3
when I do this function again:
word: "hello"
character: l
indexset={3};
expected return value = 2
This is how I allocated spaces for my indexset:
*indexset = (int*) malloc(strlen(am->transposition)*sizeof(int));
In my code, that's enough space for each index of each character.
My function to find the biggest index:
int findBiggestIndex(char karakter,char* woord,int* indexset, int *size){
int i=0,index;
for(i=0;i<strlen(woord);i++){
if(karakter==woord[i] && !inArray(indexset,i,*size)){
index=i;
printf("%d",*size);
indexset[*size]=index;
(*size)++;
}
}
return index;
}
And the method inArray():
#define TRUE 1
#define FALSE 0
int inArray(int* arr, int a, int size){
int i=0;
for(i=0;i<size;i++){
if(arr[i]==a){
return TRUE;
}
return FALSE;
}
}
The method inArray is also declared before findBiggestIndex so that's not the problem.
Please help
I want to write a function that finds the biggest index of the character in a string.
If you want to find the last occurrence of a character in a string...
loop through string and compare char elements:
Something like:
int findLastIndex(char *str, char c)
{
int keep = 0, i, len;
if(str)
{
len = strlen(str);
for(i=0;i<len ;i++)
{
if(str[i] == c) keep = i;
}
return keep;//0 means nothing found
}
return -1;//means problem with input string
}
int main(void)
{
int cnt= findLastIndex("only 1 g in line", 'g');
//cnt should return as 7 for these inputs
cnt= findLastIndex("2 g's in line(g)", 'g');
//cnt should return as 14 for these inputs
return 0;
}
literal string arguments:
|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|
|o|n|l|y| |1| |g| |i|n| |l|i|n|e|
^
|2| |g|'|s| |i|n| |l|i|n|e|(|g|)|
^
Therefore, should see index as 7 for first arg, 14 for second arg

Resources