Collecting same words in an array, C [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 8 years ago.
Improve this question
If I had an array that looks like :
'A\t2\nB\t5\nC\t6\nB\t2\n' <- alphabet and numbers are separated by a tab(\t) and a new line(\n) after the number.
I need to collect the same alphabet together also summing the number behind of alphabet. If printing out the output should looks like:
'A\t2\nB\t7\nC\t6'.
I thought of using a strcmp function, but the input array may change so I wont be able to know what alphabet is in it.
edit: sorry, I think my question is not clear. My array is not only a character, but it can be a sequence of character+numbers too. such as: 'THIS\t25\nTHESE\t67\nTHOSE\t2\nTHESE\t102\nTHOSE23\t55\n'

You can read the current line's alphabet into char c and the number into int i and have a int alpha[26] defined with all entries initialised to 0. Then you just have to:
alpha[c - 'A'] += i;
then just print out all non-zero entries in alpha

You can collect each character at a time and use a switch to produce the desire output...
like...
getch(c);
switch(c)
{
//case for alphabets
//case for numbers
}

I think you should first find smallest letter (by ASCII code number ex. A=65), search input strings for this letter (maybe using strchr) and summ (in separate variable) all numbers relative to this letter, at the end, write letter and number in new string and proceed with next letter (B=66).
Then you'll have new string sorted and summarized.
char *input;
char *output;
char *p, *cur;
int nums, num;
char min;
char temp[20];
//search for minimal letter
for(int i = 0; i < strlen(input); i++){
if(input[i] > 65 && input[i] < 90)
if(input[i] < min)
min = input[i];
}
//parsing input string
for(int i = 0; i < strlen(input)/4; i++){
//strlen(input)/4 because each sequense at least 4 letters
p = input;
num = 0;
nums = 0;
while(cur = strchr(p, min)){
sscanf(cur+2, "%d", &num);
nums += num;
p = cur+1;
}
//filling new string
sprintf(temp, "%c\t%d\n", min, nums);
strcat(output, temp);
min++;
}

Related

C Expected Output Failure [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Here is my program.I am trying to find the frequency of each character of a string and display it. While answering please see to it that I don't want to try the ASCII concept and I want to know whats wrong with this concept.
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
int l=0,j,k,m,count[10000];
char string[10000];
printf("Enter the string : \n");
scanf("%s",string);
l=strlen(string);
printf("%d",l);
for(j=0;j<l;j++)
{
for(k=j+1;k<l;k++)
{
if(string[j]==string[k])
{
count[j]++;
}
}
}
for(m=0;m<l;m++)
{
printf("%d",count[m]);
}
return 0;
}
So you wish to find the frequency of characters in your string.
About the mistakes in your code:
Consider the string lalal Here you would be counting the last l twice, once corresponding to first l and second time corresponding to third l. Hence your logic is faulty.
Similar is the case of count[]. You haven't initialized the array hence it holds garbage values.
So another approach to your problem could be declaring a 26-element array(English alphabet), iterate through the entire list and increment count corresponding to each element when that element is found.
int frequencyChar[26] = {0};//stores frequency of characters [a-z], initialized to zero
for( i=0; i<strlen(str); i++) //iterate through the entire string
{
frequencyChar[str[i] - 'a']++; //increment count corresponding to each element
}
for( i=0; i<26; i++)
{
printf("%d\n",frequencyChar[i]);
}
P.S.Above code assumes only lowercase characters in string. Minor changes would allow inclusion of uppercase letters!
Here are the problems:
You have written: I am trying to find the frequency of each character, but you code is attempting to calculate histogram of correlations between pairs of characters.
as an index for count you are using j, which iterates over constitutive characters in string. This means that your table count have lots of 0 and only some 1 and nothing else.
So currently this is NOT histogram of pairs of characters nor histogram of characters.
Character histogram can be created like this:
void makeStrHistogram(char *str, int histogram[256])
{
memset(histogram, 0, sizeof(histogram));
while (*str) histogram[*str++]++;
}
void printHistogram(int histogram[256])
{
for (int i=0; i<256; ++i) {
if (histogram[i]) {
printf("%c - %d\n", (char)i, histogram[i]);
}
}
}
To generate character correlation matrix:
void correlationMatrixForStr(char *str, int matrix[256][256])
{
memset(matrix, 0, sizeof(matrix));
int len = strlen(str);
for (int i=0; i<len; ++i) {
for (int j=i+1; j<len; ++j) {
matrix[i][j]++;
}
}
}

Why my answer always gets wrong [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am solving a question on Codechef BUY1GET1.Here is the question.
One day Alice visited Byteland to purchase jewels for her upcoming wedding anniversary.
In Byteland, every Jewelry shop has their own discount methods to attract the customers. One discount method called Buy1-Get1 caught Alice's attention. That is, Alice buys one jewel, then she can get one additional jewel with the same color without charge by Buy1-Get1.
Alice lists the needed jewels as a string S, each letter denotes one jewel, and the same letters denote the same colors of jewels, and the different letters denote the different colors of jewels. The cost of each jewel is 1. Your task is to calculate the minimum cost for getting all the jewels Alice listed.
Input
The first line of input contains a single line T, which represents the number of test cases. Then T lines will follow, and each contains a string S, which represents the jewels Alice needed.
Output
Output the minimum cost for each test case.
Constraints
1 ≤ T ≤ 100
1 ≤ |S| ≤ 200, where |S| represents the length of the string S.
The string S is case sensitive, and will contain only English characters in the range [a-z], [A-Z].
Sample
Input:
4
ssss
ssas
sa
s
Output:
2
3
2
1
I am always getting wrong answer on Codechef but on my PC it give the same output as the sample cases. I can't figure out why?
Here is my code.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
int t;
scanf("%d\n",&t);
while(t--)
{
int i,j,n,m=0,k=0;
char a[201];
scanf("%s",a);
n=strlen(a);
int count=0;
for(i=0;i<n;i++)
{
count=0;
if(isalpha(a[i]))
{
count++;
for(j=i+1;j<n;j++)
{
if(a[j]==a[i])
{
count++;
a[j]=++k;
}
}
}
//printf("%dc\n",count );
if(count%2==0)
{
m+=(count/2);
//printf("%dm1\n",m);
}
else if(count%2!=0)
m+=(1+count/2);
}
printf("%d\n",m );
}
return 0;
}
OK
just replace the following line:
a[j]=++k;
with
a[j]= '\0';
and submit again.
Explanation
for certain cases the value of k comes to the range 65-90 and 97-122
then k is treated as a character as it obtains the ascii value of a character.
so assign a null value to the array a[] every time and i think it will work.
int sum = 0;
//search number of occurences for each alphabet in the string
for (i=0; i<26; i++) {
sum += (numchar(str, 'a' + i) +1) / 2; //round up
}
You could write your own numchar function that finds how many characters c exist in a string s:
int numchar(char[] s, char c) {
int i = 0, n = 0;
while ( s[i] != '\0' ) {
if (s[i] == c) n++;
i++;
}
return n;
}
solution:
#include<stdio.h>
int main()
{
int t,h[256],i,cost;
scanf("%d",&t);
char s[201];
while(t--)
{
for(i=0;i<256;i++)
h[i]=0;
scanf("%s",s);
i=0;
while(s[i])
{
h[s[i]]++;
i++;
}
cost = 0;
for(i='A';i<='z';i++)
if(h[i]&1)
cost += h[i]/2 + 1;
else
cost += h[i]/2;
printf("%d\n",cost);
}
return 0;
}

Convert String to Integer without library function in C [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have to write a program that converts an user input (which is a string) to an Integer. In the same time it should check, if the user input really is a number.
And also everything in one method.
and NO LIBRARY FUNCTIONS allowed.
I can't figure any idea how to do it. All I got for the beginning is just this pathetic structure
#include <stdio.h>
void main()
{
char input[100];
int i;
int sum = 0;
printf("Type a String which will be converted to an Integer: ");
scanf("%c, &input");
for (i = 0; i < 100; i++)
{
}
}
I appreciate any help, thanks
The conversion is the easy part...
But if you must not use library functions,
there is only one way to take a string, and that is argv;
there is only one way to give an integer, and that is the exit code of the program.
So, without much ado:
int main( int argc, char * argv[] )
{
int rc = 0;
if ( argc == 2 ) // one, and only one parameter given
{
unsigned i = 0;
// C guarantees that '0'-'9' have consecutive values
while ( argv[1][i] >= '0' && argv[1][i] <= '9' )
{
rc *= 10;
rc += argv[1][i] - '0';
++i;
}
}
return rc;
}
I did not implement checking for '+' or '-', and did not come up with a way to signal "input is not a number". I also just stop parsing at the first non-digit. All this could probably be improved upon, but this should give you an idea of how to work around the "no library functions" restriction.
(Since this sounds like a homework, you should have to write some code of your own. I already gave you three big spoons of helping regarding argv, the '0'-'9', and the conversion itself.)
Call as:
<program name> <value>
(E.g. ./myprogram 28)
Check return code with (for Linux shell):
echo $?
On Windows it's something about echo %ERRORLEVEL% or somesuch... perhaps a helpful Windows user will drop a comment about this.
Source for the "'0'-'9' consecutive" claim: ISO/IEC 9899:1999 5.2.1 Character sets, paragraph 3:
In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.
I'm sure this is preserved in C11, but I only have the older C99 paper available.
Take hightes digit and add it to number, multiply the number by 10 and add the next digit. And so on:
#include <stdio.h> // scanf, printf
void main()
{
char input[100];
printf("Type a String which will be converted to an Integer: ");
scanf("%s", input);
int number = 0;
int neg = input[0] == '-';
int i = neg ? 1 : 0;
while ( input[i] >= '0' && input[i] <= '9' )
{
number *= 10; // multiply number by 10
number += input[i] - '0'; // convet ASCII '0'..'9' to digit 0..9 and add it to number
i ++; // step one digit forward
}
if ( neg )
number *= -1;
printf( "string %s -> number %d", input, number );
}
input[i] - '0' works, because ASCII characters '0'..'9' have ascending ASCII codes from 48 to 57.
So basically you want to know how something like the standard library atoi works. In order to do this, you need to consider how strings represent numbers.
Basically, a string (that represents a number) is a list o digits from 0 to 9. The string abcd (where a, b, c, d are placeholders for any digit) represents the number a*10 ^ 3 + b*10^2 + c * 10 + d (considering base 10 here, similar for other bases). So basically you need to decompose the string as shown above and perform the required arhitmetic operations:
// s - the string to convert
int result = 0;
for (int index = 0; index < strlen(s); index++) {
result = result * 10 + s[index] - '0';
}
The operation s[index] - '0' converts the character that represent a digit to its value.
// the function returns true for success , and false for failure
// the result is stored in result parameter
// nb: overflow not handled
int charToInt(char *buff,int *result){
*result=0;
char c;
while(c=*buff++){
if((c < '0') || (c >'9')) // accept only digits;
return 0;
*result *= 10;
*result += c-'0';
}
return 1;
}
Lot of things which are missed. Firstly taking a string in is done by scanf("%s",input); By the way in which you are receiving it, it only stores a character, secondly run the loop till the length of the string recieved. Check the below code.
#include <stdio.h>
#include<string.h>
void main()
{
char input[100];
int i;
int sum = 0;
printf("Type a String which will be converted to an Integer: ");
scanf("%s", input);
for (i = 0; i < strlen(input); i++)
{
if(input[i]>=48 && input[i]<=57)
{
//do something, it is a digit
printf("%d",input[i]-48);
//48 is ascii value of 0
}
}
Try it:
#include <stdio.h>
void main()
{
char input[100];
int i,j;
int val = 0;
printf("Type a String which will be converted to an Integer: ");
scanf("%s",input);
for(j=0; input[j] != '\0'; j++); // find string size
for (i = 0; i < j; i++)
{
val = val * 10 + input[i] - 48;
}
}
If you want your code to be portable to systems that don't use ASCII, you'll have to loop over your char array and compare each individual character in the source against each possible number character, like so:
int digit;
switch(arr[i]) {
case '0':
digit=0; break;
case '1':
digit=1; break;
// etc
default:
// error handling
}
Then, add the digit to your result variable (after multiplying it by 10).
If you can assume ASCII, you can replace the whole switch statement by this:
if(isdigit(arr[i])) {
digit=arr[i] - '0';
} else {
// error handling
}
This works because in the ASCII table, all digits are found in a single range, in ascending order. By subtracting the ordinal value of the zero character, you get the value of that digit. By adding the isdigit() macro, you additionally ensure that only digit characters are converted in this manner.

C, Dividing a string into string by whitespaces with pointers [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I want to divide a string into strings by whitespaces with pointers. I wrote the code below, but it does not work. Do you have any idea?
char sentence [] = "Thank you very much";
char * words [4]; //number of words
int i=0, charCounter=0, wordCounter=0;
while(sentence[i]){
char temp [5]; //maximum character count
while(sentence[i] != ' ' && sentence[i] != '\0'){
temp[charCounter] = sentence[i];
charCounter++;
i++;
}
temp[charCounter] = '\0';
words[wordCounter] = &temp[0];
wordCounter++;
charCounter = 0;
i++;
}
//there I want to write first word to check
int k;
for(k=0; k<12; k++)
printf("%c ", *(words[0]+k));
I think there isn't too much wrong aside from your output loops:
// write word by word
int k;
for(k=0; k < wordCounter; k++)
printf("%s ", words[k]);
// write first word byte by byte
k;
for(k=0; ((words[0])[k])!=0; k++)
printf("%c", (words[0])[k]);
Check this this code pad example based on your code above.
Only thing I changed was to allocate memory for words and copy the string using strcpy:
words[wordCounter] = malloc(sizeof(char) *(charCounter +1));
strcpy(words[wordCounter], &temp[0]);
Otherwise you assign always the same address (compare wrong example).
char temp[5] not need to save the start address of the word.
like as follows
char sentence [] = "Thank you very much";
char *words[sizeof(sentence) / 2] = {0};
int i=0, wordCounter=0;
while(sentence[i]){
while(sentence[i] == ' '){
++i;//skip space
}
if(sentence[i] == '\0')
break;
words[wordCounter++] = &sentence[i];//set top of word
while(sentence[i] != ' ' && sentence[i] != '\0'){
i++;//skip word
}
}
int k;
for(k=0; k<wordCounter; k++){
while(*words[k] != ' ' && *words[k] != '\0')
printf("%c", *words[k]++);
printf("\n");
}
You are adding a 6th char to an array of size 5!
Thats the error!
Also! You never reset the counter to 0, so as you keep going through words, you keep increasing the index added to temp as well
EDIT: I saw the temp[5]; above the while loop xD my Mistake!\
I believe your error lies in never declaring the temp[] array. In C, you must always provide an array with its size, as well.
Add this the line after you define sentence:
char temp[strlen(sentence)];
Also, a space and whitespace are two very different things.
Not all spaces are literally just a space!
However, to get a more accurate reading of any kind of space, using the function isspace, like so, is a much better practice:
while ((isspace(&sentence[i]) != 0) && (sentence[i] != '\0'))
hope this helps! :)

Finding the common characters present in all strings [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Compare each string and find the number of common lowercase letter in all the strings.
Each string is represented by a lowercase letter from 'a' to 'z'.
Example Input:
4
abcf
aghb
acbl
bamn
Example Output:
2 // a and b
Code:
#include<stdio.h>
#include<string.h>
int main() {
int n;
scanf("%d\n",&n);
char str[n][100];
char var[0][100];
for(int i=0; i<n; i++) { // strings
scanf("%99s/n",str[i]);
}
for(int i=0;i<100;i++) { // comparison of first 2 strings
for(int k=0;k<100;k++)
if(str[0][i]==str[1][k])
for(int j=0;j<strlen(str[0]);j++) {
var[0][j]=str[0][j]; // storing the common letters in a var array
}
}
for(int l=0; l<strlen(str[1]); l++) { // comparing letters in var array with the letters of all other strings
int x;
if(var[0][l]==str[l+2][l]);
x=strlen(var[0]); // counting the common letters
printf("%d\n",x);
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
int n;
scanf("%d",&n);
char str[n][100];
char var[n][26];
memset(&var[0][0], 0, sizeof(var));
for(int i=0; i<n; i++) {
scanf("%99s", str[i]);
char ch;
for(int j=0; ch=str[i][j]; ++j){
if(islower(ch)){
var[i][ch-'a']=1;//depend on the sequence of character codes
}
}
}
int x = 0;
for(int i=0; i<26; ++i){
int num = 0;
for(int j=0;j<n;++j)
if(var[j][i])
++num;
if(num==n)//all string has character of ('a'+i)
++x;
}
printf("%d\n",x);
return 0;
}
Not sure why you would want to special-case the first two strings here? How about an approach like this (in pseudocode):
- create a set of characters, name it letters_in_all_strings
- add every lowercase letter to letters_in_all_strings
- for each input string
- create a set of characters, name it letters_in_this_string
- add every character in the input string to letters_in_this_string
- remove all letters from letters_in_all_strings that are not present in letters_in_this_string
- print out the size of letters_in_all_strings
You could use an array of 0s and 1s, indexed by char, to implement a set of chars in C. Or you could use glib (https://stackoverflow.com/a/2502721/2186890). Or maybe consider using a more modern programming language?

Resources