I am trying to count the number of ones in an array of characters that represent a binary number with a recursive type program. However, it seems as if my program is just counting the number of characters in the array. I do not know if I am just comparing wrong or not but I can't seem to find the problem
#include <stdio.h>
# include <stdlib.h>
#include <string.h>
#define SIZE 20
int determine (char array[SIZE], int count, int track );
int main()
{
int answer = 0;
char input[SIZE]={"1001001"};
int count = 0;
int track = 0;
answer = determine(input, count, track);
printf("The number of 1's is %d ", answer);
system("PAUSE");
return 0;
}
int determine(char array[], int count, int track)
{
if (array[track] != '\0')
{
if ( array[track] == '1');
{
count++;
}
return determine(array, count, track = track+1);
}
else
{
return count;
}
}
In method determine():
if ( array[track] == '1');
remove the semicolon ;. The semicolon makes the if condition to execute an empty block. So the count++ will always execute whether the if condition succeeded(true) or not(false).
I run your code with ; and get the output:
The number of 1's is 7
And without ; :
The number of 1's is 3
if ( array[track] == '1');
should be
if ( array[track] == '1')
remove the ;
If you have the ; then irrespective of the condition evaluation result (TRUE or FALSE) count++ will get executed
Have you tried a simple countif function?
=sum if (range="1")
Related
I'm trying to make a program that accepts the number of students enrolled to an exam, and how many points each of them got. I try to loop the inputs but it gives seemingly random numbers in output
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int studenti;
scanf("%d", &studenti);
printf("%d ", studenti);
int niza[studenti];
for (int i = 1; i <= studenti; i++){
scanf("%d", &niza[i]);
i++;
printf("%d ",niza[i]);
}
}
What am I doing wrong? Is there another way to add array elements without knowing how big the array will be beforehand because I don't know how big they are when I pass the checks on my uni website.
The primary issue is that the for loop begins with 1 and continues to i <= studenti. In C, arrays begin with index '0' and the final index in this example is studenti - 1.
Another issue is the for loop increments i and there is an i++; in the body of the loop. i is incremented twice.
Check the return from scanf. It returns the number of items successfully scanned. Here that would be 1, 0 or EOF.
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int studenti = 0; // initialize
if ( 1 == scanf("%d", &studenti)) { // successful scan
printf("%d ", studenti);
int niza[studenti]; // variable length array
for (int i = 0; i < studenti; i++) { // start from index 0
if ( 1 == scanf("%d", &niza[i])) {
printf("%d ",niza[i]);
}
else { // scanf returned 0 or EOF
fprintf ( stderr, "problem scanning array element\n");
return 2;
}
}
}
else { // scanf returned 0 or EOF
fprintf ( stderr, "problem scanning\n");
return 1;
}
printf("\n");
return 0;
}
If you don't know the length, you should probably create a linked list instead of a static array, and malloc another list element for each student.
I am making a program which requires the user to input an argument (argv[1]) where the argument is every letter of the alphabet rearranged however the user likes it. Examples of valid input is "YTNSHKVEFXRBAUQZCLWDMIPGJO" and "JTREKYAVOGDXPSNCUIZLFBMWHQ". Examples of invalid input would then be "VCHPRZGJVTLSKFBDQWAXEUYMOI" and "ABCDEFGHIJKLMNOPQRSTUYYYYY" since there are duplicates of 'V' and 'Y' in the respective examples.
What I know so far is, that you can loop through the whole argument like the following
for (int j = 0, n = strlen(argv[1]); j < n; j++)
{
//Place something in here...
}
However, I do not quite know if this would be the right way to go when looking for duplicates? Furthermore, I want the answer to be as simple as possible, right know time and cpu usage is not a priority, so "the best" algorithm is not necessarily the one I am looking for.
Try it.
#include <stdio.h>
#include <stddef.h>
int main()
{
char * input = "ABCC";
/*
*For any character, its value must be locate in 0 ~ 255, so we just
*need to check counter of corresponding index whether greater than zero.
*/
size_t ascii[256] = {0, };
char * cursor = input;
char c = '\0';
while((c=*cursor++))
{
if(ascii[c] == 0)
++ascii[c];
else
{
printf("Find %c has existed.\n", c);
break;
}
}
return 0;
}
assuming that all your letters are capital letters you can use a hash table to make this algorithm work in O(n) time complexity.
#include<stdio.h>
#include<string.h>
int main(int argc, char** argv){
int arr[50]={};
for (int j = 0, n = strlen(argv[1]); j < n; j++)
{
arr[argv[1][j]-'A']++;
}
printf("duplicate letters: ");
for(int i=0;i<'Z'-'A'+1;i++){
if(arr[i]>=2)printf("%c ",i+'A');
}
}
here we make an array arr initialized to zeros. this array will keep count of the occurrences of every letter.
and then we look for letters that appeared 2 or more times those are the duplicated letters.
Also using that same array you can check if all the letters occured at least once to check if it is a permutation
I don't know if this is the type of code that you are looking for, but here's what I did. It looks for the duplicates in the given set of strings.
#include <stdio.h>
#include <stdlib.h>
#define max 50
int main() {
char stringArg[max];
int dupliCount = 0;
printf("Enter A string: ");
scanf("%s",stringArg);
system("cls");
int length = strlen(stringArg);
for(int i=0; i<length; i++){
for(int j=i+1; j<length; j++){
if(stringArg[i] == stringArg[j]){
dupliCount +=1;
}
}
}
if(dupliCount > 0)
printf("Invalid Input");
printf("Valid Input");
}
This code snippet is used to count the duplicate letters in the array.
If you want to remove the letters, Also this code snippet is helpful .Set null when the same characters are in the same letter.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int count=0;
int array[]={'e','d','w','f','b','e'};
for(int i=0;i<array.Lenth;i++)
{
for(int j=1;j<array.Length;j++)
{
if(array[i]==array[j])
{
count++;
}
}
}
printf("The dublicate letter count is : %d",count);
}
I am solving this problem:
Given a string str containing alphanumeric characters, calculate sum
of all numbers present in the string.
Input:
The first line of input contains an integer T denoting the number of test cases. Then T test
cases follow. Each test case contains a string containing alphanumeric characters.
Output:
Print the sum of all numbers present in the string.
Constraints:
1 <= T<= 105
1 <= length of the string <= 105
Example:
Input:
4
1abc23
geeks4geeks
1abc2x30yz67
123abc
Output:
24
4
100
123
I have come up with the following solution:
#include <stdio.h>
#include <string.h>
int main() {
//code
int t,j;
char a[100000];
scanf("%d",&t);
while(t--)
{
int sum=0,rev=0,i=0,l;
scanf("%s",a);
l=strlen(a);
for(i=0;i<l;i++)
{
if (isdigit(a[i])){
while(isdigit(a[i])){
rev = rev *10 + (a[i]-48);
i++;
}
}
sum+=rev;
rev=0;
}
printf("%d\n",sum);
}
return 0;
}
This code is working fine.
BUT if loop termination condition is changed from i < l to a[i]!='\0', then code doesn't work. Why?
I would loop backwards over the string. No nested loops. Just take the 10s exponent as you move left
You have the length of the string, so there should be no reason to check for NUL char yourself
(untested code, but shows the general idea)
#include <math.h>
l=strlen(a);
int exp;
exp = 0;
for(i = l-1; i >= 0; i--)
{
if (isdigit(a[i])) {
rev = a[i]-48; // there are better ways to parse characters to int
rev = (int) pow(10, exp) * rev;
sum += rev; // only add when you see a digit
} else { exp = -1; } // reset back to 10^0 = 1 on next loop
exp++;
}
Other solutions include using regex to split the string on all non digit characters, then loop and sum all numbers
You will have to change the logic in your while loop as well if you wish to change that in your for loop condition because it's quite possible number exists at the end of the string as well, like in one of your inputs 1abc2x30yz67. So, correct code would look like:
Snippet:
for(i=0;a[i]!='\0';i++)
{
if (isdigit(a[i])){
while(a[i]!='\0' && isdigit(a[i])){ // this line needs check as well
rev = rev *10 + (a[i]-48);
i++;
}
}
sum+=rev;
rev=0;
}
On further inspection, you need the condition of i < l anyways in your while loop condition as well.
while(i < l && isdigit(a[i])){
Update #1:
To be more precise, the loop while(isdigit(a[i])){ keeps going till the end of the string. Although it does not cause issues in the loop itself because \0 ain't a digit, but a[i] != '\0' in the for loop condition let's you access something beyond the bounds of length of the string because we move ahead 1 more location because of i++ in the for loop whereas we already reached end of the string inside the inner while loop.
Update #2:
You need an additional check of a[i] == '\0' to decrement i as well.
#include <stdio.h>
#include <string.h>
int main() {
//code
int t,j;
char a[100000];
scanf("%d",&t);
while(t--)
{
int sum=0,rev=0,i=0,l;
scanf("%s",a);
l=strlen(a);
for(i=0;a[i]!='\0';i++)
{
if (isdigit(a[i])){
while(a[i] != '\0' && isdigit(a[i])){ // this line needs check as well
rev = rev *10 + (a[i]-48);
i++;
}
}
if(a[i] == '\0') i--; // to correctly map the last index in the for loop condition
sum+=rev;
rev=0;
}
printf("%d\n",sum);
}
return 0;
}
Update #3:
You can completely avoid the while loop as well as shown below:
#include <stdio.h>
#include <string.h>
int main() {
//code
int t,j;
char a[100005];
scanf("%d",&t);
while(t--)
{
int sum=0,rev=0,i=0,l;
scanf("%s",a);
l=strlen(a);
for(i=0;i<l;i++) {
if (isdigit(a[i])){
rev = rev * 10 + (a[i]-48);
}else{
sum += rev;
rev = 0;
}
}
printf("%d\n",sum + rev); // to also add last rev we captured
}
return 0;
}
Other answers have pointed out the correct loop conditions to ensure proper operation of your program.
If you are allowed to use library functions other than isdigit, I would recommend using strtol with the EndPtr parameter (output parameter that points to the character in the string that caused strtol to stop scanning a number):
char str[] = "1abc23def5678ikl";
int main()
{
char *pStop = str;
int n, accum = 0;
size_t len = strlen(str);
do
{
n = strtol(pStop, &pStop, 10);
pStop++;
if(n)
{
printf("%d\n", n);
accum += n;
}
}
while(pStop < &str[len]);
printf("Total read: %d\n", accum);
return 0;
}
Natural numbers are the set of positive integers, which ranges from 1 to infinity excluding fractional part. Natural numbers are whole numbers excluding zero. Zero is the only whole number which is not a natural number. An array is special if all the elements are natural numbers. Find whether the given array is special or not.
I've tried to use numbers without using scanf it worked and functioned as its supposed to function.
Ihis is the code I tried to write:
#include <stdio.h>
int main(){
int N,special[N] ;
scanf("%d",&N);
for(N;N>0;N++){
if(special[N]>0){
printf("yes/n");
}else{
printf("no/n");
}
}
return 0;
}
I expect the outout to be yes or no. But the actual output is nothing. There is no output to my code.
There are several issues with the code as pointed out in the comments.
One way of what you want to achieve is:
#include <stdio.h>
int main(){
int N;
int ret = scanf("%d",&N);
if(1 != ret || N < 0)
return 1;
int special[N] ;
for(int i=0;i<N;i++){
ret = scanf("%d", &special[i]);
if(1 != ret)
return 1;
if(special[i] == 0){
printf("array not special\n");
return 1;
}
}
printf("special array\n");
return 0;
}
I'm writing a program to check whether a string is palindrome or not using recursion.Palindrome string is the one that can be read backwards just the same as reading it forward. However following is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
printf("Enter the number of characters in your string\n");
scanf("%d",&num);
char string[num];
char string2[num];
int i;
printf("Enter your string\n");
for (i=0;i<num;i++)
{
scanf("%c",&string[i]);
}
fillString(string,string2,num);
int palin = isPalind(string,string2,num);
if (palin) printf("The string you entered is palindrome");
else printf("The string you entered is not palindrome");
return 0;
}
int isPalind(char string[],char string2[],int num)
{
int i=0;
while (i<num)
{
if (string[i]!=string2[i])
{
i++;
return 0;
}
else{
i++;
return 1*isPalind(string,string2,num);
}
}
}
void fillString(char string[],char string2[],int num)
{
int i;
for (i=1;i<num;i++)
string2[i-1]=string[num-i];
}
I have a logical error, the program compiles fine and executes but it always gives out "The string is not palindrome"
In the fillString the loop is iterating num-1 times (i is from 1 to num-1), so not the whole string is copied. The first character of the original string is omitted. You should do
for (i=1;i<=num;i++) ...
As for the recursive function, it is not really recursive. In recursive call modified input should be passed, but in your case exactly the same input is passed. So in case of true palindrome, it's likely you will get stack overflow due to non-termination. I would propose another approach, to work with single string recursively:
1) Base case: String is a palindrome if of length 0 or 1
2) Recursion step: String is a palindrome if the first character equals to the last and the string without first and last characters is palindrome.
Is your fillString() function reversing your string as expected? It looks like the first letter of string1 is not getting added into the last position of string2 because the for loop stops when i < num fails. Try switching it to i <= num and seeing if that helps.
Double-check this example:
Given: String1 = "Hello". String2 = null for now. num = 5.
void fillString(char string[],char string2[],int num)
{
int i;
for (i=1;i<num;i++)
string2[i-1]=string[num-i];
}
When i = 4, you have string2 = 'olle'. When i = 5, the for loop condition fails, so it doesn't populate string2[4] = 'H'.
updated:
void fillString(char string[],char string2[],int num)
{
int i;
for (i=1;i<=num;i++)
string2[i-1]=string[num-i];
}
The both functions are wrong. They can be written the following way
int isPalind( const char string[], const char string2[], int num )
{
return ( num == 0 ) ||
( string[0] == string[--num] && isPalind( string + 1, string2, num ) );
}
void fillString( const char string[], char string2[], int num )
{
int i;
for ( i = 0; i < num; i++ ) string2[i] = string[num-i-1];
}
If you need not necessary a recursive function then you could use simply standard function memcmp that to determine whether two strings are equal.