Can't decode a polynomial properly - c

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct polynomial{
int coeff;
char var;
int exp;
struct polynomial *link;
} poly;
poly* decode(char*);
main()
{
char polynomial[100];
poly *first, *second;
printf("\n---Enter 1st polynomial---\n\n");
scanf("%s",polynomial);
first=decode(polynomial);
printf("\n---Enter 2nd polynomial---\n\n");
scanf("%s",polynomial);
second=decode(polynomial);
//More statements further
return 0;
}
/*--- Decoding Polynomial ---*/
poly* decode(char *polynomial)
{
poly *p=NULL, *q=NULL, *temp=NULL;
int i=0, sign;
short coeff_entry=TRUE, exp_entry=FALSE, var_visited=FALSE, exp_visited=FALSE, coeff_visited=FALSE;
while(polynomial[i]!='\0')
{
temp=(poly*)malloc(sizeof(poly));
if(!temp)
{
printf("Error! Memory not allocated\n");
exit(1);
}
if(polynomial[i]==43) {i++; sign=1;}
if(polynomial[i]==45) {i++; sign=-1;}
while(1)
{
if((polynomial[i]>=48&&polynomial[i]<=57)&&coeff_entry==TRUE)
{
temp->coeff=10*(temp->coeff)+(polynomial[i]-48);
coeff_visited=TRUE;
}
else if((polynomial[i]>=65&&polynomial[i]<=90)||(polynomial[i]>=97&&polynomial[i]<=122))
{
temp->var=polynomial[i];
coeff_entry=FALSE;
exp_entry=TRUE;
var_visited=TRUE;
}
else if((polynomial[i]>=48&&polynomial[i]<=57)&&exp_entry==TRUE)
{
temp->exp=10*(temp->exp)+(polynomial[i]-48);
exp_visited=TRUE;
}
else if(polynomial[i]==43||polynomial[i]==45||polynomial[i]=='\0')
{
exp_entry=FALSE;
coeff_entry=TRUE;
if(var_visited&&!exp_visited)
{
temp->exp=1;
!var_visited;
!exp_visited;
}
if(!coeff_visited)
{
!coeff_visited;
temp->coeff=1;
}
temp->coeff*=sign;
break;
}
i++;
}
//These lines are for debugging purpose only
printf("\nCoefficient of the term is: %d\n",temp->coeff);
printf("Variable of the term is: %c\n",temp->var);
printf("Exponent of the term is: %d\n",temp->exp);
temp->link=NULL;
if(p==NULL) p=q=temp;
else
{
q->link=temp;
q=q->link;
}
}
return p;
}
In my code I am asking user to input a polynomial in the form like: -5x^2+7y^3-19z+5
Everything seems fine but two problems in decoding this polynomial and storing in the linked list form:
First bug comes when the first-most coefficient is positive in polynomial like 17x^3-13z+5
In this case a very long integer value (most probably garbage value) gets store in the respected node of linked list.
Second bug is when there is no first coefficient like x^7-18y^3+z-13
In this case 0 gets stored in the respected node of linked list. In other terms of polynomial, like z in example above, where there is no coefficient 1 gets stored in the coeffient part of the node.
So problem arises with the first coefficient only that too a 'positive coeff' or 'no coefficient' at all.

There are many errors in your code, the most important is the expresions like
!value;
you need to assign to it, lik
value = !value;
And you are not initializing sign when there is not '+' sign in front of the next token, you need to initialize it to 1, check if there is a '-' and set it to -1 otherwise ignore the '+'.
Now I appended the fixed code, try it
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct _polynomial {
int coeff;
char var;
int exp;
struct _polynomial *link;
} poly;
poly *decode(char*);
int
main()
{
char string[100];
printf("\n---Enter 1st polynomial---\n\n");
scanf("%99s", string);
decode(string);
printf("\n---Enter 2nd polynomial---\n\n");
scanf("%99s", string);
decode(string);
//More statements further
return 0;
}
/*--- Decoding Polynomial ---*/
poly* decode(char *polynomial)
{
poly *p = NULL, *q = NULL, *temp = NULL;
int i = 0, sign;
short coeff_entry=TRUE, exp_entry=FALSE, var_visited=FALSE, exp_visited=FALSE, coeff_visited=FALSE;
while (polynomial[i] != '\0')
{
temp = malloc(sizeof(poly));
if (temp == NULL)
{
printf("Error! Memory not allocated\n");
exit(1);
}
sign = 1;
if (polynomial[i] == 43)
i++;
if (polynomial[i] == 45)
{
i++;
sign=-1;
}
while (1)
{
if ((polynomial[i] >= 48 && polynomial[i] <= 57) && coeff_entry == TRUE)
{
temp->coeff = 10 * temp->coeff + polynomial[i] - 48;
coeff_visited = TRUE;
}
else if ((polynomial[i] >= 65 && polynomial[i] <= 90) || (polynomial[i] >= 97 && polynomial[i] <= 122))
{
temp->var = polynomial[i];
coeff_entry = FALSE;
exp_entry = TRUE;
var_visited = TRUE;
}
else if ((polynomial[i] >= 48 && polynomial[i] <= 57) && exp_entry == TRUE)
{
temp->exp=10*(temp->exp)+(polynomial[i]-48);
exp_visited=TRUE;
}
else if (polynomial[i] == 43 || polynomial[i] == 45 || polynomial[i] == '\0')
{
exp_entry=FALSE;
coeff_entry=TRUE;
if (var_visited && !exp_visited)
{
temp->exp = 1;
var_visited = !var_visited;
exp_visited = !exp_visited;
}
if (!coeff_visited)
{
coeff_visited = !coeff_visited;
temp->coeff = 1;
}
temp->coeff *= sign;
break;
}
i++;
}
printf("\nCoefficient of the term is: %d\n", temp->coeff);
printf("Variable of the term is: %c\n", temp->var);
printf("Exponent of the term is: %d\n", temp->exp);
temp->link = NULL;
if (p == NULL)
p = q = temp;
else
{
q->link = temp;
q = q->link;
}
}
return p;
}

Related

if statement doesn't work on a triangle type function

I'm a complete newbie, so please excuse me.
I tried using online compiler but they unresponsive, and I get no return value (or return 0 for whatever I enter)
I tried to write a function that check if triangle is right, isosceles or both, and return 1,2,3 respectively, all other cases should return 0.
int main() {
int TriangleType(unsigned angle1, unsigned angle2) {
unsigned angleSum = angle1 + angle2;
if (angleSum >= 180) {
return 0;
}
/* if triangle is right ---> */
if (angle1==90 || angle2==90 || angleSum==90) {
/*if it is also an isosceles --->*/
if (angle2==45 || angle1==45) {
return 3;
}
return 1;
}
/*check if it only a isosceles*/
if (angle1==(180-angle2)/2 ||
angle2== (180-angle1)/2 ||
angle1==angle2) {
return 2;
}
return 0;
}
TriangleType(110, 111);
}
First, don't try to use nested functions in C. Pulling that function out of main.
int TriangleType(unsigned angle1, unsigned angle2) {
unsigned angleSum = angle1 + angle2;
if (angleSum >= 180) {
return 0;
}
/* if triangle is right ---> */
if (angle1==90 || angle2==90 || angleSum==90) {
/*if it is also an isosceles --->*/
if (angle2==45 || angle1==45) {
return 3;
}
return 1;
}
/*check if it only a isosceles*/
if (angle1==(180-angle2)/2 ||
angle2== (180-angle1)/2 ||
angle1==angle2) {
return 2;
}
return 0;
}
int main() {
TriangleType(110, 111);
}
Second, this doesn't do anything with the return value from the function, so of course you see no output.
int main(void) {
switch (TriangleType(110, 111)) {
case 1:
printf("Right triangle\n");
break;
case 2:
printf("Isosceles triangle\n");
break;
case 3:
printf("Both types\n");
break;
default:
printf("None of the above\n");
}
return 0;
}
Code is functionally wrong
Even after re-organizing and moving the nested function, code attempts to be clever and not perform simple tests.
if (angle1 == (180 - angle2) / 2 || angle2 == (180 - angle1) / 2 || angle1 == angle2) fails in cases like TriangleType(45,89) --> 2 as (180 - angle2) / 2 rounds down. angle1 * 2 == (180 - angle2) would make more sense.
TriangleType(90, 90), where the 3rd angle is 0, returns 0. That is asymmetric. TriangleType(0, 90), TriangleType(90, 0) do not return 0.
TriangleType(0, 0) returns 2. I would expect that to return 0, a rejected triangle.
Below is a test harness for OP to use and test TriangleType().
#include <stdio.h>
int TriangleType(unsigned angle1, unsigned angle2) {
unsigned angleSum = angle1 + angle2;
if (angleSum >= 180) {
return 0;
}
/* if triangle is right ---> */
if (angle1 == 90 || angle2 == 90 || angleSum == 90) {
/*if it is also an isosceles --->*/
if (angle2 == 45 || angle1 == 45) {
return 3;
}
return 1;
}
/*check if it only a isosceles */
if (angle1 == (180 - angle2) / 2 || angle2 == (180 - angle1) / 2
|| angle1 == angle2) {
return 2;
}
return 0;
}
int my_TriangleType(unsigned angle1, unsigned angle2) {
unsigned angle3 = 180 - angle1 - angle2;
if (angle1 >= 180 || angle2 >= 180 || angle3 >= 180) {
return 0;
}
if (angle1 == 0 || angle2 == 0 || angle3 == 0) {
return 0;
}
int retval = angle1 == 90 || angle2 == 90 || angle3 == 90 ? 1 : 0;
if (angle1 == angle2 || angle2 == angle3 || angle3 == angle1)
retval += 2;
return retval;
}
#include <string.h>
#define MAX_LIMIT 127
int main() {
printf("score:%d my_score:%d\n", TriangleType(45,89), my_TriangleType(45,89));
int error_count = 0;
int flags[4][4] = {0};
for (unsigned angle1 = 0; angle1 <= 181; angle1++) {
for (unsigned angle2 = 0; angle2 <= 181; angle2++) {
int score = TriangleType(angle1, angle2);
int my_score = my_TriangleType(angle1, angle2);
if (score != my_score) {
error_count++;
if (flags[score][my_score] == 0) {
flags[score][my_score] = 1;
printf("%3d angle1:%2u angle2:%2u score:%d my_score:%d\n", //
error_count, angle1, angle2, score, my_score);
}
}
}
}
printf("total errors:%d\n", error_count);
return 0;
}
Output:
score:2 my_score:0
1 angle1: 0 angle2: 0 score:2 my_score:0
2 angle1: 0 angle2:90 score:1 my_score:0
total errors:181
another_TriangleType() could be made that is more efficient than my_TriangleType(), yet it would needed to functionally match.
Well your questions is lacking some information, but I assume you got as inputs of your program, two angles.
THe fisrt thing we need to think is:
If you got a right triangle, than there is one of those values equals 90 degrees, instead the sum of them must be 90.
On the other hand, if you got an isosceles triangle you should have 2 equal values, instead you must have the 180 deg - sum of both angles should result in one of those two.
Let's try to code this out:
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define RIGHT 0x01
#define ISOSCELES 0x02
#define BOTH 0x03
// If you got a right triangle, than there is one of those values equals 90 degrees, instead the sum of them must be 90.
int bIsRightTriangle(int iAngDeg1, int iAngDeg2){
if ( iAngDeg1 == 90 || iAngDeg2 == 90 )
return TRUE;
if ( (iAngDeg1 + iAngDeg2) == 90 )
return TRUE;
return FALSE;
}
// On the other hand, if you got an isosceles triangle you should have 2 equal values,
// instead you must have the 180 deg - sum of both angles should result in one of those two.
int bIs_IsoscelesTriangle(int iAngDeg1, int iAngDeg2){
int iAngDeg3 = 180 - iAngDeg1 + iAngDeg2;
if ( iAngDeg1 == iAngDeg2 )
return TRUE;
if ( (iAngDeg3 == iAngDeg1) || (iAngDeg3 == iAngDeg2) )
return TRUE;
return FALSE;
}
int iGetTriangleTypeByAngles(int iAngDeg1, int iAngDeg2){
int iReturnType = 0;
iReturnType = bIsRightTriangle(iAngDeg1, iAngDeg2) ? (iReturnType | RIGHT) : iReturnType;
iReturnType = bIs_IsoscelesTriangle(iAngDeg1, iAngDeg2) ? (iReturnType | ISOSCELES) : iReturnType;
return iReturnType;
}
int main(int argc, char *argv[]){
if ( argc < 3 ){
return -1;
}
// In case you want an output
// printf("%d\n", iGetTriangleTypeByAngles(atoi(argv[1]), atoi(argv[2])));
return iGetTriangleTypeByAngles(atoi(argv[1]), atoi(argv[2]));
}

C, help continue..? in while loop - polynomial ADT

When the coef is 0, I used continue to not print, but only printTerm(a) comes out and the printTerm(b) part does not come out.
When I delete the (if & continue) statement, both printTerm(a) and printTerm(b) appear, so it seems that there is a problem here (if & continue) statement.
How can I solve this?
int main() {
a[0].coef = 2;
a[0].expon = 1000; // 2x^1000
a[1].coef = 1;
a[1].expon = 2; // x^2
a[2].coef = 1;
a[2].expon = 0; // 1
b[0].coef = 1;
b[0].expon = 4; // x^4
b[1].coef = 10;
b[1].expon = 3; // 10x^3
b[2].coef = 3;
b[2].expon = 2; // 3x^2
b[2].coef = 1;
b[2].expon = 0; // 1
printTerm(a);
printTerm(b);
return 0;
}
void printTerm(polynomial *p) {
int i=0;
printf("polynomial : ");
while(p[i].expon != -1) {
if(p[i].coef == 0) continue;
printf("%dx^%d", p[i].coef, p[i].expon);
i++;
if(p[i].expon != -1 && p[i].coef > 0) printf(" + ");
}
printf("\n");
}
Because you only increment i if p[i].coef is not equal to 0.
If p[i].coef == 0 it skips the increment part and function is stuck in infinite loop, always checking the same array item.
EDIT:
Way to fix this:
Instead of if(p[i].coef == 0) continue; use:
if (p[i].coef == 0)
{
i++;
continue;
}
This way while loop evaluetes next array item instead of being stuck on the same.

Infix to postfix conversion and evaluation including whitespaces and double quotes

I have the code below, but I need the code to account for white spaces and double digits, for example if i enter (7-3)/(2+2) it should come out 73-22+/ result: 1. If i enter (7 - 3) / (2 + 2) it should come out 7 3 - 2 2 + / result 1. If I enter (22 - 10)/(2 + 2) it should come out 22 10 - 2 2 + / Result: 3
Here is the code I have:
#include<stdio.h>
char stack[100];
int top = 0;
int eval_top = -1;
int eval_stack[100];
void push(char x) // Push char into stack
{
stack[top++] = x;
}
char pop() // Pop char to top of stack
{
if (top == -1)
return -1;
else
return stack[top--];
}
/* functions for evaluation of postfix expression */
// push function
void eval_push(int x) { // Find push result
eval_stack[++eval_top] = x;
}
// pop function
int eval_pop() { // Find pop result
if (eval_top == -1) {
return -1;
} else {
return eval_stack[eval_top--];
}
}
int priority(char x) // check priority order
{
if (x == '(')
return 0;
if (x == '+' || x == '-')
return 1;
if (x == '*' || x == '/')
return 2;
}
// function to evaluate the postfix expression
void EvalPostfix(char postfix[]) {
int A, B;
int val;
char ch;
int i;
//find postfix
for (i = 0; postfix[i] != ')'; i++) {
ch = postfix[i];
if (isdigit(ch)) {
eval_push(ch - '0');
} else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
A = eval_pop();
B = eval_pop();
switch (ch) {
case '*':
val = B * A;
break;
case '/':
val = B / A;
break;
case '+':
val = B + A;
break;
case '-':
val = B - A;
break;
}
eval_push(val); //send value on top of stack
}
}
printf("\n Result: %d \n", eval_pop());
}
main() {
int i = 0;
char * e, x;
char postfix[100]; // store postfix for later evaluation
char exp[100];
printf("Infix expression : ");
scanf("%s", exp); // asking the user to enter the infix expression
printf("Postfix expression: ");
e = exp;
while ( * e != '\0') {
if (isalnum( * e)) { // if character is alphabet or number , it is printed
printf("%c", * e);
postfix[i++] = * e;
} else if ( * e == '(') // if it is open parenthesis, it is pushed into the stack without any priority
push( * e);
else if ( * e == ')') // if it is closed parenthesis , pop the elements in the stack and print them until the we see ( symbol
{
while ((x = pop()) != '(') {
printf("%c", x);
postfix[i++] = x;
}
} else // if character is symbol like +, -, *, / then based on their priority character is pushed if it high priority otherwise high priority symbols are popped and it is pushed
{
while (priority(stack[top]) >= priority( * e)) {
x = pop();
printf("%c", x);
postfix[i++] = x;
}
push( * e);
}
e++;
}
while (top != -1) // printing remaining elements in the stack
{
x = pop();
printf("%c", x);
postfix[i++] = x;
}
postfix[i] = ')'; // this is to add at the end for detecting end by the evaluation function
EvalPostfix(postfix);
}
There are some problems in your code
your pop is not symmetric with your push, push post increment the index so pop must pre decrement the index, and because of that the first invalid index is not -1 but 0 :
char pop() // Pop char to top of stack
{
if (top == 0)
return -1;
else
return stack[--top];
}
priority does not return a value if all the tests are false, but probably the last test is useless
In
while (priority(stack[top]) >= priority( * e))
you missed to check if the stack is empty, must be :
while ((top != 0) && (priority(stack[top]) >= priority( * e))) {
Because the first invalid index for stack is 0 rather than -1
while (top != -1) // printing remaining elements in the stack
must be
while (top != 0) // printing remaining elements in the stack
When you make the postfix expression there is no separation between the numbers, for instance "12+3" becomes "123+" like "1+23", and in EvalPostfix you consider a number has only one digit (eval_push(ch - '0');), so you do not manage the numbers having more than 1 digit. To manage several digits add a separator after all numbers, for instance a space to have "12 3 +" or "1 23 +" and read the number with scanf etc
You do not make the right postfix expression in all the cases, for instance for 1+2*3 you make 12+3* but it must be 123*+
You do not detect the invalid infix expressions
in
while (priority(stack[top]) >= priority( * e))
I missed to say the top element is not stack[top] but stack[top - 1] so it must be replaced by
while ((top != 0) && (priority(stack[top - 1]) >= priority( * e))) {
adding that correction 1+2*3 produces the right postfix expression 123*+
Note it is more clear to introduce the function empty() and tops(), and in case of an invalid access into the stack print a message and exit rather than to return -1 as a char
int empty()
{
return (top == 0);
}
char tops()
{
if (top == 0) {
fputs("top() on the empty stack, abort", stderr);
exit(-1);
}
return stack[top - 1];
}
char pop() // Pop char to top of stack
{
if (top == 0) {
fputs("pop() on the empty stack, abort", stderr);
exit(-1);
}
return stack[--top];
}
also detect a possible overflow of the stack :
void push(char x) // Push char into stack
{
if (top == sizeof(stack)) {
fputs("stack overflow", stderr);
exit(-1);
}
stack[top++] = x;
}
so now you can do
while (!empty() && (priority(tops()) >= priority( * e))) {
Of course this is the same for the other stack
I need the code to account for white spaces and double digits
double digits is too restrictive, just manage any integer, for that you can extract the number using strtol. You cannot also read the full expression using scanf("%s", exp); because is stops on the first space, use fgets.

Check if a binary tree has a path equal to the given sum

I'm having an issue figuring out the solution for this problem:
"Given a binary tree (each node has an int value), and a sum, return 1 if the tree has a path equal to the given sum (from a node to a leaf, doesn't have to be the root), else return 0".
I've done a similar question, where the path has to start from the root.
But here, the question states that the path can start anywhere, as long as it ends with a leaf..
Tried searching online for a solution, but I found some that are only working by using the buffer.
Is there any possible solution for this, without the buffer?
Thanks in advance!
(Prefer in C,C++ syntax or even a pseudo code ^.^``)
This was my first try:
int hasPathSum(Tree tr, int sum){
return hasPathSumRec(tr.root, sum, 0);
}
int hasPathSumRec(TNode* node, int sum, int current){
int num1, num2;
current += node->data;
if (current > sum)
current = 0;
if (node->left == NULL && node->right == NULL){
if (current == sum)
return 1;
return 0;
}
else if (node->left == NULL){
return hasPathSumRec(node->right, sum, current);
}
else if (node->right == NULL){
return hasPathSumRec(node->left, sum, current);
}
else{
num1=hasPathSumRec(node->left, sum, current);
num2=hasPathSumRec(node->right, sum, current);
if (num1 > 0 || num2 > 0)
return 1;
else
return 0;
}
}
and this was the second: (but it doesn't go through all of the nodes, so it's not good..)
int hasPathSum(Tree tr, int sum){
return hasPathSumRec(tr.root, sum, 0);
}
int hasPathSumRec(TNode* node, int sum, int current){
int num, num1, num2;
num = node->data;
current = num + current;
if (current > sum)
current = num;
if (node->left == NULL && node->right == NULL){
if (node->data == sum || current == sum)
return 1;
else
return 0;
}
else if (node->left == NULL){
num2 = node->right->data;
if (current + num2 > sum)
return hasPathSumRec(node->right, sum, num);
else
return hasPathSumRec(node->right, sum, current);
}
else if (node->right == NULL){
num1 = node->left->data;
if (current + num1 > sum)
return hasPathSumRec(node->left, sum, num);
else
return hasPathSumRec(node->left, sum, current);
}
else{
num1 = node->left->data;
num2 = node->right->data;
/LEFT SIDE--------------------------------------------------/
if (current + num1 > sum)
num2 = hasPathSumRec(node->left, sum, num);
else
num2 = hasPathSumRec(node->left, sum, current);
/RIGHT SIDE--------------------------------------------------/
if (current + num2 > sum)
num1 = hasPathSumRec(node->right, sum,num);
else
num1 = hasPathSumRec(node->right, sum, current);
if (num1 > 0 || num2 > 0)
return 1;
else
return 0;
}
As you already mentioned, you compute the sum of a tree values as the sum of the sums of its subtrees plus the root value. It's clear that as soon as you can compute the sum of this tree you have computed the sums of all its subtrees. So the only thing left to do is adding a check if the sum is equal to the required one and return it. Here you can find an implementation for this idea and a Minimal, Complete, and Verifiable example, which you should have provided in the first place, saving people (me) the effort to write one.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct _TNode {
int data;
struct _TNode *left, *right;
} TNode;
typedef struct {
TNode *root;
} Tree;
typedef struct {
int sum;
bool found;
} hasPathSumRec_t;
hasPathSumRec_t hasPathSumRec(TNode* node, int sum)
{
hasPathSumRec_t ret = { 0, false };
if (!node)
return ret;
hasPathSumRec_t ret_left = hasPathSumRec(node->left, sum);
hasPathSumRec_t ret_right = hasPathSumRec(node->right, sum);
ret.sum = ret_left.sum + ret_right.sum + node->data;
ret.found = ret_left.found || ret_right.found || ret.sum == sum;
return ret;
}
int hasPathSum(Tree tr, int sum) {
return hasPathSumRec(tr.root, sum).found;
}
int main(void)
{
/*
1 / 2 / 3 / *
| | \ *
| \ 5 / *
| \ *
\ 4 / 6 / 7 / *
| | \ *
| \ *
\ 8 / *
\ 9 / *
\ *
*/
TNode n[] = {
{ 1, n + 4 - 1, n + 2 - 1 },
{ 2, n + 5 - 1, n + 3 - 1 },
{ 3, NULL, NULL },
{ 4, n + 8 - 1, n + 6 - 1 },
{ 5, NULL, NULL },
{ 6, NULL, n + 7 - 1 },
{ 7, NULL, NULL },
{ 8, n + 9 - 1, NULL },
{ 9, NULL, NULL },
};
Tree t = { n };
int tests[] = { 8, 9, 10, 12, 13, 17 };
size_t ntests = sizeof tests / sizeof *tests;
for (size_t i = 0; i < ntests; ++i)
printf("%i - %i\n", tests[i], hasPathSum(t, tests[i]));
}
Further improvements could allow an early exit if sum is found or exceeded.
I've done a similar question, where the path has to start from the root. But here, the question states that the path can start anywhere, as long as it ends with a leaf..Is there any possible solution for this, without the buffer?
If you already have a solution with root node, then isn't it just one more recursion required.
Assume your root-node based solution is called IsPathHasSum(root). This will return 1 if sum of nodes on any path from root to leaf matchs given sum. This function should only find paths from root to leaf and not intermediate paths starting from arbitrary nodes.
Now to cover all nodes,
-> Start with IsPathHasSum(root), if return value = 1, program terminates
-> If not, invoke IsPathHasSum(root->left). This ignore the root and right tree.
-> If not, invoke IsPathHasSum(root->right). This ignores root and left tree
This can be invoked recursively to start from each node of the tree down to the leaf. If at any point, the return value is 1, program terminates. This re-traversal on same paths again and again is required since your requirement is not to have any buffers.

Error in using atof() and strtod() when trying to convert numerical string into float

I've made code to read expressions from a file in postfix notation (RPN) and output the value. While it is correctly reading the values and displaying outputs for expressions without any numbers that use decimal places, it defaults to error for any expression containing a float value.
Basically, if a digit is found within a string read from file, it needs to be converted to a float.
I've unsuccesfully tried setting the data value equal to atof(str) and strtod(const char *str, char **endptr), but I'm still getting the error.
Here is my code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
int top = -1;
float stack[500];
/* push the given data into the stack */
void push (int data) {
stack[++top] = data;
}
/* Pop the top element from the stack */
float pop () {
float data;
if (top == -1)
return -1;
data = stack[top];
stack[top] = 0;
top--;
return (data);
}
int main() {
char str[500];
FILE *p;
if((p=fopen("testfile1.txt","r"))==NULL){
printf("\n Unable to open file string.txt");
return 1;
}
while(fgets(str,500,p)!='\0'){
float data = -1, operand1, operand2, result;
for (int i = 0; i < strlen(str); i++) {
if (isdigit(str[i])) {
/*
* if the i/p char is digit, parse
* character by character to get
* complete operand
*/
data = (data == -1) ? 0 : data;
data = (data * 10) + (str[i] - 48);
continue;
}
if (data != -1) {
/* if the i/p is operand, push it into the stack */
push(data);
}
if (str[i] == '+' || str[i] == '-'
|| str[i] == '*' || str[i] == '/') {
/*
* if the i/p is an operator, pop 2 elements
* from the stack and apply the operator
*/
operand2 = pop();
operand1 = pop();
if (operand1 == -1 || operand2 == -1)
break;
switch (str[i]) {
case '+':
result = operand1 + operand2;
/* push the result into the stack */
push(result);
break;
case '-':
result = operand1 - operand2;
push(result);
break;
case '*':
result = operand1 * operand2;
push(result);
break;
case '/':
result = operand1 / operand2;
push(result);
break;
}
}
data = -1;
}
if (top == 0)
printf("Output:%3.2f\n", stack[top]);
else
printf("have given wrong postfix expression\n");
return 1;
}
}
There are 5 postfix expressions in the file, and they are as follows:
13 1 - 2 / 3 155 + *
100 100 100 100 + + +
10.33 2 2 2 2 2 * * * * *
30 10 - 10 - 10 - 2 *
300 13.25 - 11 3 - / 4 5 - * 3 /
But, the output of the program denies the third expression because it contains 10.33, which is not an integer value.
Output:
Output: 948.00
Output: 400.00
have given wrong postfix expression
Output: 0.00
Output: 300.00
Does anyone know how to modify this code to handle floats?
Cheers.
You could try to manually process decimal values almost the same you process integers, but in C it would be simpler to directly iterate a number in a single pass:
while(fgets(str, sizeof(str), stdin) != NULL) {
unsigned int i;
for (i=0; i<strlen(str); i++) {
if (isdigit(str[i])) {
data = str[i++] - '0'; // initialize data with first digit
while(isdigit(str[i])) {
data = data * 10 + (str[i++] - '0'); // increment with other digits
}
if (str[i] == '.') { // decimal part
double mult = .1;
i++;
while(isdigit(str[i])) {
data = data + mult * (str[i++] - '0'); // increment with decimal part
mult *= .1;
}
}
push(data);
}
...
But in fact strtod does it for you...:
while(fgets(str, sizeof(str), stdin) != NULL) {
unsigned int i;
for (i=0; i<strlen(str); i++) {
if (isdigit(str[i])) {
char *end;
data = ::strtod(str+i, &end);
i = end - str; // that's all we are past the number...
push(data);
}
...

Resources