Поиск производной функции, хранящейся в массиве символов

Мне нужно прочитать файл, содержащий уравнения. Мне нужно взять производную от каждого уравнения, а затем записать эти производные уравнения в другом .txt-файле. Я прочитал все уравнения в массив массивов символов, и теперь я не знаю, что делать, как только я их сохранил в массиве. Мне действительно не нужна помощь в написании уравнений в другом файле; Я знаю, что смогу это понять.

Мне нужна помощь, чтобы найти способ взять производную от функций. Тип уравнений, которые будут считаться, не так уж сложен; они будут полиномами, которым не требуется правило цепочки или правило частного. Однако будет существовать sin x , cos x и tan x . Некоторые образцовые уравнения, которые будут прочитаны, являются.

-2x^2+2x-3 -2x+sinx-3 -x+sin2x-tanx 

Триггерные функции не будут иметь скобок, и переменная всегда будет «x». Пожалуйста, пожалуйста, мне нужен толчок в правильном направлении.

То, что вы действительно просите, это парсер . Парсер в основном представляет собой набор правил для чтения этих уравнений и изменения / чтения (parsingа) каждого из них. Я бы попытался выполнить итерацию по каждой строке файла и дифференцировать ее, учитывая, что у вас есть определенный набор символов (т.е. ^ означает мощность, x – параметр и т. Д.);

Например, некоторый псевдокод:

 Open the file. While there's lines to read: Read a line - Seperate it by the operands (+,-,/,*) For each part: Find the power of x, Reduce it by one, ...(derivating rules) // no way around, you have to implement each function if you want this to work as others mentioned in the comments. Reconnect the parts into a string, Add it to a list. Print each element of the list. 

Если вам нужна помощь в переводе на C, просто попросите об этом; Я с радостью помогу вам.

То, что вам нужно сделать, по внешнему виду вещей, – это разделить выражение на отдельные термины, чтобы вы могли найти производную каждого по очереди.

Вы можете определить термин как самую большую последовательность символов, не содержащих разделителей терминов, таких как (в ваших примерах) + и - .

Следовательно, условия для ваших примеров:

 -2x^2+2x-3 => 2x^2 2x 3 -2x+sinx-3 => 2x sinx 3 -x+sin2x-tanx => x sin2x tanx 

Для каждого термина вам необходимо оценить форму этого термина. Форма будет определять, как вы создаете производную.


Например, вы можете определить, содержит ли она тригонометрическую функцию вида [n]sin[m]x где n и m – необязательные числа. Чтобы упростить вещи, вы можете добавить эти термины, если их там нет, таких как 1sin1x становясь 1sin1x (я назову это полной формой этого термина). Способность предполагать, что все подтермы присутствуют, значительно облегчит вычисление производных.

Допустим, что термин sin4x . Расширение, которое даст вам 1sin4x который затем можно разбить на терм-множитель 1 , функцию sin и x-множитель 4 . Тогда, используя стандартное производное знание nsinmx => (n*m)cosmx , это станет 4cos(4x) и этот термин будет выполнен.


Если он не содержит тригонометрическую функцию, вы можете использовать один и тот же полный трюк, чтобы по очереди включить все выражения мощности / константы со следующими правилами:

  • если это константа (все числовые), добавьте x^0 (умножьте на 1).
  • если он заканчивается на x , добавьте ^1 , поэтому 4x станет 4x^1 .
  • если он начинается с x , префикс его равен 1 , поэтому x^3 становится 1x^3 .

Как только это будет сделано, у вас будет полная форма ax^b и тогда вы сможете создать производную (ab)x^(b-1) и обработать ее следующим образом:

  • если бит после x равен ^0 , удалите все x^0 .
  • если бит после x равен ^1 , удалите ^1 .
  • если бит до x равен 1 , удалите его.
  • если бит до x равен 0 , удалите весь термин (и предыдущий разделитель терминов, если он есть).

Итак, принимая сложную комбинацию ваших тестовых данных:

 -2x^2 + 5x + 4sin3x - 3 

который можно рассматривать как:

 0 - 2x^2 + 5x + 4sin3x - 3 

Следующие действия происходят с каждым термином:

 0 [0x^1] (derives as) 0, remove it. 2x^2 [2x^2] (derives as) (2*2)x^(2-1) => 4x^1 => 4x 5x [5x^1] (derives as) (5x1)x^(1-1) => 5x^0 => 5 4sin3x [4sin3x] (derives as) 12cos3x 3 [3x^0] (derives as) 0, remove it and preceding '-' 

Таким образом, вы - 4x + 5 + 12cos3x , хотя мое образование в области исчисления составляет около тридцати лет в прошлом (и я не думаю, что использовал его с тех пор, хотя , без сомнения, буду использовать его в следующем году, когда старшая студентка средней школы), Вольфрам Альфа, похоже, согласен со мной 🙂

Эта функция будет анализировать текст, вырезать его в разные части, идентифицированные type[i] , хранится в структуре. Он распознает x , +, – и числа. Его можно расширить, включив другие операторы и т. Д.

 #define maxlen 50 #define idx 0 //X variable #define idnumber 1 //number #define idplus 2 //+ sign #define idminus 3 //- sign struct foo { int type[10];//each type can be a number (idnum), +, -, etc. int num[10];//if type[i] is number then num[i] identifies that number int count;//total number of parts }; void parse_one_line(struct foo *v, const char *s) { char buf[maxlen]; memset(buf, 0, maxlen); int j = 0; //remove white spaces for (int i = 0, len = strlen(s); i < len; i++) { if (s[i] == ' ') continue; buf[j] = s[i]; j++; } char part[maxlen]; v->count = 0; for (int i = 0, len = strlen(buf); i < len; i++) { char c = buf[i]; if (c == 'x') { v->type[v->count] = idx; v->count++; } else if (c == '+') { v->type[v->count] = idplus; v->count++; } else if (c == '-') { v->type[v->count] = idminus; v->count++; } else if (c >= '0' && c <= '9') { int j = 0; memset(part, 0, maxlen); for (; i < len; i++) { c = buf[i]; if (c >= '0' && c <= '9') { part[j] = c; j++; } else { break; } } i--; v->num[v->count] = atoi(part); v->type[v->count] = idnumber; v->count++; } } for (int i = 0; i < v->count; i++) { switch (v->type[i]) { case idnumber: printf("%d", v->num[i]); break; case idx: printf("X"); break; case idplus: printf("+"); break; case idminus: printf("-"); break; default:break; } } printf("\n"); } int main() { struct foo st; parse_one_line(&st, "-23x + 2 + 2x - 3"); return 0; } по #define maxlen 50 #define idx 0 //X variable #define idnumber 1 //number #define idplus 2 //+ sign #define idminus 3 //- sign struct foo { int type[10];//each type can be a number (idnum), +, -, etc. int num[10];//if type[i] is number then num[i] identifies that number int count;//total number of parts }; void parse_one_line(struct foo *v, const char *s) { char buf[maxlen]; memset(buf, 0, maxlen); int j = 0; //remove white spaces for (int i = 0, len = strlen(s); i < len; i++) { if (s[i] == ' ') continue; buf[j] = s[i]; j++; } char part[maxlen]; v->count = 0; for (int i = 0, len = strlen(buf); i < len; i++) { char c = buf[i]; if (c == 'x') { v->type[v->count] = idx; v->count++; } else if (c == '+') { v->type[v->count] = idplus; v->count++; } else if (c == '-') { v->type[v->count] = idminus; v->count++; } else if (c >= '0' && c <= '9') { int j = 0; memset(part, 0, maxlen); for (; i < len; i++) { c = buf[i]; if (c >= '0' && c <= '9') { part[j] = c; j++; } else { break; } } i--; v->num[v->count] = atoi(part); v->type[v->count] = idnumber; v->count++; } } for (int i = 0; i < v->count; i++) { switch (v->type[i]) { case idnumber: printf("%d", v->num[i]); break; case idx: printf("X"); break; case idplus: printf("+"); break; case idminus: printf("-"); break; default:break; } } printf("\n"); } int main() { struct foo st; parse_one_line(&st, "-23x + 2 + 2x - 3"); return 0; }