equation solver
Posted: Tue Nov 10, 2009 1:13 pm
ugly and not clean, just what it is.
wont work if there are white spaces in equation.
h
code
wont work if there are white spaces in equation.
h
Code: Select all
/*
* cMathExp.h
* objects
*
* Created by avansc on 11/6/09.
* Copyright 2009 avansc. All rights reserved.
*
*/
#ifndef _cMathExp_h
#define _cMathExp_h
class cMathExp
{
public:
cMathExp();
char *solve(char *data);
void setPrecision(int x);
private:
char *pGetExp();
char *splitInner(char *data);
char *splitInnerWithBraces(char *data);
char *replace(const char *subject, const char *search, const char *replace);
char *trigFunc(char *data, int f);
int precision;
};
#endif
Code: Select all
/*
* cMathExp.cpp
* objects
*
* Created by avansc on 11/6/09.
* Copyright 2009 avansc. All rights reserved.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "cMathExp.h"
cMathExp::cMathExp()
{
this->precision = -1;
}
void cMathExp::setPrecision(int x)
{
if(x <= 0)
{
this->precision = -1;
}else if(x <= 10)
{
this->precision = x;
}else{
this->precision = 10;
}
}
char *cMathExp::solve(char *data)
{
printf("%s\n", data);
char *test = (char*)malloc(sizeof(char)*strlen(data));
test = strdup(data);
test = strtok(test, "^*/+-(");
test = strtok(NULL, "^*/+-(");
if(!test)
return data;
//////////// trig code ///////////
char *trig[] = {"sin", "cos", "tan", "asin", "acos", "atan"};
for(int a = 0;a < 6;a++)
{
if( (test =strstr(data, trig[a])))
{
char *f = (char*)malloc(sizeof(char)*strlen(test));
f[0] = '\0';
char *test2 = (char*)malloc(sizeof(char)*strlen(test));
test2 = strdup(test);
int count = 0;
while(*test2)
{
if(*test2 == ')')
{
count--;
if(count == 0)
break;
}
if(count > 0)
{
strncat(f, test2, 1);
}
if(*test2 == '(')
{
count++;
}
test2++;
}
test2[0] = '\0';
strncat(test2, test, strlen(f)+5);
return this->solve(this->replace(data, test2, this->trigFunc(this->solve(f),a)));
}
}
//////////// end trig code ///////////
//////////// braces /////////////
if(strchr(data, '('))
{
return this->solve(this->replace(data,this->splitInnerWithBraces(data), solve(this->splitInner(data))));
}
//////////// end braces ///////////
/////////// ^,multi,div,add,sub ///////////
int mdcount = 0;
char set[] = "1234567890.";
char signset[] = "^*/+-";
for(int a = 0;a < strlen(data);a++)
{
if(strchr(signset, data[a]))
{
mdcount++;
}
}
if(mdcount > 1)
{
for(int a = 0;a < 5;a++)
{
int c1 = 0;
char *numbers = (char*)malloc(sizeof(char)*strlen(data));
numbers = strdup(data);
char *ops = (char*)malloc(sizeof(char)*strlen(data));
ops = strdup(data);
ops = strtok(ops, set);
while(ops)
{
if(*ops == signset[a])
{
char *temp_op = strdup(ops);
numbers = strtok(numbers, signset);
for(int b = 0;b < c1;b++)
{
numbers = strtok(NULL, signset);
}
//printf("%s%s%s\n", numbers, temp_op, strtok(NULL, signset));
char *t1 = strdup(numbers);
numbers = strtok(NULL, signset);
char *t2 = strdup(numbers);
strcat(t1, strdup(temp_op));
strcat(t1, strdup(t2));
return strdup(this->solve(strdup(this->replace(data, strdup(t1), strdup(this->solve(strdup(t1)))))));;
}
ops = strtok(NULL, set);
c1++;
}
}
}
///////// end multi & div /////////
char **num = (char**)malloc(sizeof(char*)*2);
num[0] = (char*)malloc(sizeof(char)*10);
num[0][0] = '\0';
char op;
int count = 0;
while(*data)
{
if(strchr(set, *data))
{
strncat(num[count], data, 1);
}else {
count++;
num[count] = (char*)malloc(sizeof(char)*10);
num[count][0] = '\0';
op = *data;
}
data++;
}
float a = atof(num[0]);
float b = atof(num[1]);
float c = 0;
if(op == '^')
{
c = pow(a,b);
}else if(op == '*')
{
c = a * b;
}else if(op == '/')
{
c = a / b;
}else if(op == '+')
{
c = a + b;
}else if(op == '-')
{
c = a - b;
}
char *alph = (char*)malloc(sizeof(char)*strlen(data)+11);
sprintf(alph,"%0.10f",(float)c);
alph[strlen(alph)-(10-this->precision)] = '\0';
free(num[0]);
free(num[1]);
free(num);
return alph;
}
char *cMathExp::splitInner(char *data)
{
char *ret = (char*)malloc(sizeof(char)*strlen(data));
ret[0] = '\0';
while(*data)
{
if(*data == ')')
{
return strdup(ret);
}
strncat(ret, data, 1);
if(*data == '(')
{
ret[0] = '\0';
}
data++;
}
return NULL;
}
char *cMathExp::splitInnerWithBraces(char *data)
{
char *ret = (char*)malloc(sizeof(char)*strlen(data));
ret[0] = '\0';
while(*data)
{
strncat(ret, data, 1);
if(*data == '(')
{
ret[0] = '\0';
strncat(ret, data, 1);
}
if(*data == ')')
{
return strdup(ret);
}
data++;
}
return NULL;
}
char *cMathExp::replace(const char *subject, const char *search, const char *replace)
{
if (search == NULL || replace == NULL || subject == NULL) return NULL;
if (strlen(search) == 0 || strlen(replace) == 0 || strlen(subject) == 0) return NULL;
char *replaced = (char*)calloc(1, 1), *temp = NULL;
char *p = (char*)subject, *p3 = (char*)subject, *p2;
int found = 0;
while ( (p = strstr(p, search)) != NULL) {
found = 1;
temp = (char*)realloc(replaced, strlen(replaced) + (p - p3) + strlen(replace));
if (temp == NULL) {
free(replaced);
return NULL;
}
replaced = temp;
strncat(replaced, p - (p - p3), p - p3);
strcat(replaced, replace);
p3 = p + strlen(search);
p += strlen(search);
p2 = p;
}
if (found == 1) {
if (strlen(p2) > 0) {
temp = (char*)realloc(replaced, strlen(replaced) + strlen(p2) + 1);
if (temp == NULL) {
free(replaced);
return NULL;
}
replaced = temp;
strcat(replaced, p2);
}
} else {
temp = (char*)realloc(replaced, strlen(subject) + 1);
if (temp != NULL) {
replaced = temp;
strcpy(replaced, subject);
}
}
return replaced;
}
char *cMathExp::trigFunc(char *data, int f)
{
float a = atof(data);
float c = 0;
switch(f)
{
case 0 :
{
c = sin(a);
break;
}
case 1 :
{
c = cos(a);
break;
}
case 2 :
{
c = tan(a);
break;
}
case 3 :
{
c = asin(a);
break;
}
case 4 :
{
c = acos(a);
break;
}
case 5 :
{
c = atan(a);
break;
}
}
char *alph = (char*)malloc(sizeof(char)*strlen(data));
sprintf(alph,"%0.10f",(float)c);
return alph;
}