I am trying to write a C program that takes a string input from a user and then looks into the input to count the frequency of all the integers in the string. So suppose if the user gives the input:
a11472o5t6
the output would be :
0 2 1 0 1 1 1 1 0 0
my approach involves comparing every character of the string to all 10 digits one by one and if any the character is equal to the digit, it would increment the isdigit number by 1.
the code I wrote for the same is as follows:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int is1 = 0; //initialise integers for checking
int is2 = 0;
int is3 = 0;
int is4 = 0;
int is5 = 0;
int is6 = 0;
int is7 = 0;
int is8 = 0;
int is9 = 0;
int is0 = 0;
int main()
{
char s[100]; //initialise array for string
scanf("%s", s); //scan string input
//now all characters of the string are stored in the array s
for (int i = 0; i < strlen(s); i++) //loop to iterate over all the elements in the array
{
if (strcmp(&s[i], "0") == 0)
{
is0 = is0 + 1;
}
if (strcmp(&s[i], "1") == 0)
{
is1 = is1 + 1;
}
if (strcmp(&s[i], "2") == 0)
{
is2 = is2 + 1;
}
if (strcmp(&s[i], "3") == 0)
{
is3 = is3 + 1;
}
if (strcmp(&s[i], "4") == 0)
{
is4 = is4 + 1;
//printf("%d", is4);
}
if (strcmp(&s[i], "5") == 0)
{
is5 = is5 + 1;
}
if (strcmp(&s[i], "6") == 0)
{
is6 = is6 + 1;
}
if (strcmp(&s[i], "7") == 0)
{
is7 = is7 + 1;
}
if (strcmp(&s[i], "8") == 0)
{
is8 = is8 + 1;
}
if (strcmp(&s[i], "9") == 0)
{
is9 = is9 + 1;
}
}
printf("%d ", is0);
printf("%d ", is1);
printf("%d ", is2);
printf("%d ", is3);
printf("%d ", is4);
printf("%d ", is5);
printf("%d ", is6);
printf("%d ", is7);
printf("%d ", is8);
printf("%d ", is9);
}
I expected the code to iterate over and over for the entire length of the string and and update values of the isdigit series every time a number was successfully found. However whenever I run the code only the last digit seems to find its place in the output .
for example if I type 54 as an input the expected output is
0 0 0 0 1 1 0 0 0 0
however the output my code seems to be giving is
0 0 0 0 1 0 0 0 0 0
likewise the number 45 also has the same expected output
0 0 0 0 1 1 0 0 0 0
but the output I am receiving is
0 0 0 0 0 1 0 0 0 0
which looks like the code overwrites any operation that occurred in the previous iteration, but I can't seem to understand why and how to fix it.
On my part I checked if the characters were being called properly one by one and that all characters were being compared, where I found no problem. I also looked up other answers on stack overflow and elsewhere, but was I am a beginner and most answers were written in reference to languages that I can't understand, so I was unable to relate to the solution they were being told. the closest I got was someone who was using a single variable repetitively thus overwriting it in each iteration. however I have declared sufficient variables( one for each digit from 0-9), so that shouldn't be the problem in my code either.
while I know this question could be solved easily using arrays, I would like to know what I was doing wrong here to avoid any such mistakes in the future.
When you do if (strcmp(&s[i],"1")==0) you are comparing strings, not individual characters, which is why only the last character is counted. It's the only one matching.
Example:
If s == "a11472o5t6" and you use strcmp(&s[1], "1"), you would be comparing the string "11472o5t6" with the string "1", which clearly will not be equal.
You want if(s[i] == '1') etc. to do the comparisons of individual characters instead.
And you are correct about using arrays instead. It'd certainly be easier.
Example:
#include <ctype.h>
#include <stdio.h>
int main() {
const char *str = "a11472o5t6";
int ints[10] = {0};
for (const char *chptr = str; *chptr != '\0'; ++chptr) {
if(isdigit((unsigned char) *chptr)) ++ints[*chptr - '0'];
}
for (int i = 0; i < 10; ++i) printf("%d %d\n", i, ints[i]);
}
Output:
0 0
1 2
2 1
3 0
4 1
5 1
6 1
7 1
8 0
9 0
Related
Suppose there is an array with 0, 1 and 5 in it. 5 can be replaced by either 0 or 1. How to find the length of longest continuing character?
Suppose array is 051. In this case we can replace 5 by 0 or 1. So it will become 001 or 011. In both the cases the length of longest continuing character is 2.
Suppose if array is 0511 now 5 has to be replaced with 1 to get longest continuing character in 0111. If 5 is replace by 0 we get 0011 and longest continuing character becomes 2, this is less than 3. Therefore length of longest continuing character is 3.
3. This has to be done in one iteration of array
Some Examples:
INPUT: 15015001. OUTPUT: 3
Explanation: 15015001 -> 11010001 -> we have 3 zeros together so length of longest continuing character is 3.
Please let me know if you need more details.
Check each character:
If it's a 0, increment my zero-counter and set my one-counter to 0
If it's a 1, increment my one-counter and set my zero-counter to 0
If it's a 5, increment both my zero-counter and my one-counter
Check the value of both counters. If either of them is greater than the current value of my longest-set , then update my longest-set to that value.
int getLongestContinousCharLength(int[] array) {
int count0 = 0;
int count1 = 0;
int maxCount1 = 0;
int maxCount0 = 0;
int i = 0;
while (i < array.length) {
if (array[i] == 0) {
count0++;
count1 = 0;
if (count0 > maxCount0)
maxCount0 = count0;
} else if (array[i] == 1) {
count1++;
count0 = 0;
if (count1 > maxCount1)
maxCount1 = count1;
} else {
count0++;
if (count0 > maxCount0)
maxCount0 = count0;
count1++;
if (count1 > maxCount1)
maxCount1 = count1;
}
i++;
}
return maxCount0 > maxCount1 ? maxCount0 : maxCount1;
}
#include <stdio.h>
void main(){
int i, j, n;
int num[5];
int serial;
for(i=0; i<5; ++i){
scanf("%d",&num[i]);
if(num[i]==num[i-1])
serial=i;
else
continue;
}
printf("Serial number of equal numbers next to each other:%d. %d.", serial-1, serial);
}
This may be hard to understand because I'm not a native English speaker.
If the numbers next to each other are equal the program should print the serial number of those numbers.
For example:
Input: 1 2 3 7 7 7 6;
Output: 3. 4. 5.
Input: 5 5 5 5 5
Output: 0. 1. 2. 3. 4.
I made some changes now it prints the serial of two equal numbers.
I: 1 2 2 3 4 - O: 1. 2.
But what if all the numbers are equal?
// ...
// deal with index 0
if (num[0] == num[1]) printf("0. ");
// deal with indexes 1 .. N - 2
for (int k = 1; k < n - 1; k++) {
if ((num[k - 1] == num[k]) || (num[k] == num[k + 1])) {
printf("%d. ", k);
}
}
// deal with index N - 1
if (num[n - 2] == num[n - 1]) printf("%d. ", n - 1);
// ... possibly with a printf("\n"); somewhere
You can solve this without storing the numers in an array, but you must keep track of how many equal numbers have been read before reading the present one:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int i = 0; // running index
int prev = 0; // previously read number
int iprev = 0; // start of range of equal numbers previously read
int n; // currently read number
while (scanf("%d", &n) == 1) {
if (n != prev) {
if (i - iprev > 1) {
while (iprev < i) printf("%d\n", iprev++);
}
iprev = i;
prev = n;
}
i++;
}
if (i - iprev > 1) {
while (iprev < i) printf("%d\n", iprev++);
}
return 0;
}
You consider stretches of equal numbers only after you read a number that terminates the current range of equal numbers. When all numbers are different, the size of that range is 1 and we don't print anything. If the range is larger than 1, print all indices in question.
Because you don't notice a change after reading the last number, you must check the last range separately after the main loop.
If you can put a non-numeric character in the [0] element of your array, you won't need a different test for the first element
int main (void)
{
/* non-numeric in position 0 of data array */
char myList[] = {'.','1','2','2','3','4','4','4','5','6','6'};
int listSz = strlen(myList) -1;
int n;
/* check everything except last */
for (n = 1; n < listSz; n++) {
if(( myList[n] == myList[n +1]) || ( myList[n] == myList[n -1] )) {
printf("%d . ", n);
}
}
/* check last */
if( myList[listSz] == myList[listSz -1] ) {
printf("%d", n);
}
printf("\n");
}
Output: 2 . 3 . 5 . 6 . 7 . 9 . 10
I need to write a function that accepts the length of series(0 and 1) and the user writes the series. The function tells the place of the longest same sun-series.
Example:
The function gets length = 12, and the user writes: 1 0 0 1 1 1 1 0 0 0 1 1
The answer for this one is 4 because the longest combination (four consecutive 1's) starts at 4th place.
Another example:
The length is: 12 and the user inputs : 1 0 0 0 1 1 0 1 1 1 0 0
The answer for this one is 2 (three consecutive 0's starting at position 2—if there are multiple sub-series with same length it returns the first one).
This is what I tried to do:
int sameNumbers(int seriaLength)
{
int i;
int place=0;
int num1, num2;
int sameCount;
int maxSameCount = 0;
printf("Please enter the seria: \n");
scanf("%d",&num1);
for(i = 1; i < seriaLength; i++)
{
scanf("%d",&num2);
while(num1 == num2)
{
sameCount++;
}
if(sameCount > maxSameCount)
{
maxSameCount = sameCount;
place = i;
}
scanf("%d",&num1);
}
return place;
}
Edit:
I need to do this without arrays.
Thanks!!
This seems to do what you want. To understand the logic, see the comments in the code.
#include <stdio.h>
int sameNumbers(int seriaLength)
{
int i, num, previousNum, length = 0, maxLength = 0, start = 0, startOfLongest = 0;
printf( "Please enter the series: " );
for( i = 0; i < seriaLength; i++ )
{
scanf( "%d", &num );
if( i > 0 && num == previousNum ) length++;
else { length = 1; start = i; } // if the number is not the same as the previous number, record the start of a new sequence here
if( length > maxLength ) { maxLength = length; startOfLongest = start; } // if we've broken (not equalled) the previous record for longest sequence, record where it happened
previousNum = num;
}
return startOfLongest + 1; // add 1 because the OP seems to want the resulting index to be 1-based
}
int main( int argc, const char * argv[] )
{
printf( "%d\n", sameNumbers( 12 ) );
return 0;
}
this program is "calculating" all subsets of the array source. I need to store the resulting values in another 2D filed named polje. If I just use the printf("%d %d %d ", source[i][0], source[i][1], source[i][2]); the code works fine but something fails when it is trying to copy everything into the resulting field. I suppose I am dogin something wrong in the indexing of the array polje.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
int f;
int i,j;
int source[2][3] = {{0,3,5},{3,4,2}};
int currentSubset = 3;
int polje[8][3];
for(i=0;i<8;i++){
for(j=0;j<3;j++){
polje[i][j]=0;
}}
int tmp;
while(currentSubset)
{
tmp = currentSubset;
for( i = 0; i<3; i++)
{
if (tmp & 1)
{
printf("%d %d %d ", source[i][0], source[i][1], source[i][2]); //writes out everything I want
polje[currentSubset][0]=source[i][0];
polje[currentSubset][1]=source[i][1];
polje[currentSubset][2]=source[i][2];
}
tmp >>= 1;
}
printf("\n");
currentSubset--;
}
for(i=0;i<8;i++){
for(j=0;j<3;j++){
printf("%d ", polje[i][j]);
}printf("\n");}
return (EXIT_SUCCESS);
}
The output field should be:
0 3 5
3 4 2
3 4 2
0 0 0
0 3 5
0 0 0
0 0 0
0 0 0
But instead it is:
0 3 5
3 4 2
3 4 2
0 0 0
*0 0 0*
0 0 0
0 0 0
0 0 0
tmp is a bit mask with only two bits, so the inner loop should be for ( i = 0; i < 2; i++ ).
Also the correct index into the polje array is polje[currentSubset * 2 + i][0] since each subset in polje takes two spaces and i is either 0 or 1.
I think you just have a logic error. Your loop's skeleton is:
currentSubset = 3;
while ( currentSubset )
{
// ...
polje[currentSubset][...] = ...;
// ...
currentSubset--;
}
So you never write to any rows except the first three.
I am supposed to make a dice game that plays multiple times. I am not really looking for the answer, kind of looking to see what I am doing wrong. I would expect the for loop to assign the int i a value of 0, then run the dice rolls, then add one to i, until i is > 50. Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
main(){
int rollDie1, rollDie2, keyValue = 0, win = 0, lose = 0, reroll = 0, i;
srand(time(NULL)); // call this only once – seed the random generator
for (i = 0 ; i < 50 ; i++);
{
rollDie1 = rand() % 6 + 1; // in the range of 1 - 6
rollDie2 = rand() % 6 + 1; // in the range of 1 - 6
keyValue = rollDie1 + rollDie2;
if ( keyValue == 7 || keyValue == 11 )
{
printf ("Player wins on the first roll \n");
}
if ( keyValue == 2 || keyValue == 3 || keyValue == 12 )
{
printf("Sorry, you lost on the first roll \n");
}
if ( keyValue == 4 || keyValue == 5 || keyValue == 6 || keyValue == 8 || keyValue == 9 || keyValue == 10 )
{
printf("Reroll! \n");
}
}
system("pause");
}
There's a ; at the end of the for loop that shouldn't be there.
for (i = 0 ; i < 50 ; i++);
should be
for (i = 0 ; i < 50 ; i++)
otherwise there is nothing in the for-loop and what's in the {} will only be executed once, as that's a separate statement.
You have a semicolon at the end of the loop:
for (i = 0 ; i < 50 ; i++);
So it does nothing 50 times. You simply need to remove the semicolon so that your brackets {} will actually encapsulate the lines of your code that are supposed to be in the for loop. If you don't have an open bracket { immediately following a for loop, the first complete statement following the for loop will be executed at each iteration. The semicolon is a complete statement that does nothing.
Actually it will run as long as i<50 which is from 0 to 49