Смекни!
smekni.com

Обратная пользовательская запись в языке Си (стр. 2 из 2)

Рассмотрим работу функций: ChartoInt , Scobka, Sumit.

3.4 Детальное описание основной функции ChartoInt

Функция ChartoInt преобразует набор символов из строки, набранной пользователем в числа. Преобразование происходит следующим образом, имеем некоторые символы XYZ, программа преобразует их так:

Определяется разрядность числа, скажем сотни, следовательно, 1 число умножается на 100 + следующее число, умноженное на 10 + следующее число, умноженное на 1.

Пример:

x,y,z - x*100+y*10+z*1 = xyz

1,2,3 - 1*100+2*10+3*1 = 123

3.5 Детальное описание основной функции процедуры Scobka

Функция Scobka преобразует все выражения в скобках в числа, например (2+4/2) будет преобразовано в 4.

Получаем массив данных и знаков через указатели, сканируем массив знаков на открытые и закрытые скобки и обозначаем начало скобок через N, а конец через N1. Числа и знаки, входящие в этот промежуток, образуют два новых массива данных и знаков, но уже без скобок, после чего вызывается функция Sumin и возвращается численное значение скобок, которое вставляется в исходный массив чисел с проведением сдвига данных и чисел.

Пример:

Как мы видим, вначале раскрывается 1 скобка, выражение в ней рассчитывается и следовательно в массивах значений и чисел происходит сдвиг. Затем тоже проделывается со второй скобкой. В конце мы имеем массив значений состоящий только из знаков +, -, * и /.

3.6 Детальное описание основной функции процедуры Sumin

Функция Sumin производит компоновку числовых и знаковых массивов с использованием приоритета операций и последуйщего расчёта результата.

Т.е в выражении последовательно выполняются все операции, сперва с умножением "*", затем с делением "/", затем с сложением "+" и затем с вычитанием "-".

Пример: 12+2*7-10/2 - 12+14-10/2 -12+14-5 - 6-5 - 21

Детально работа функций описана в приложении 1.

3.7 Общая структура программного средства

4. Блок схема

4.1 Основная блок схема

4.2 Блок схема функции ChartoInt

4.3 Блок схема функции Sumin

4.4 Блок схема функции Scobka

5. Заключение

Данный метод не является оптимальным, так как:

· Не использует классы.

· "Сдвиг" не вынесен в отдельную функцию, что затрудняет модернизацию.

· Сложность при попытке включения вложенных скобок

· Сложность при попытке включения математических операций таких как cos(), sin(), степень и другие.

· Строгое ограничение числового диапазона расчётов

· Отсутствие "дружественного" - оконного интерфейса.

Возможное решение данных проблем – это переход на другую платформу, Microsoft® Visual C++ или Borland® Delphi.

Приложение 1

Основной код программы

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <math.h>

int ChartoInt (int*,int,int);

double Sumin (int*,int *,int ,int );

void Scobka (int*,int *,int ,int );

char OTLADKA[1];

void main (void)

/*======================[Начало]=======================*/

{

char S[125];

int i, iKol,m, buf[125],a[100],b[100],k,*p,l,*a1,*b1,u1,u2,s,ABC;

double c;

mr:

puts("Do Want to look the debugging information? (y/Any key)");

if (getch()!='y') {puts("Debugging information OFF"); OTLADKA[1]='N'; }

else {puts("Debugging information ON");printf("&bsol;a"); OTLADKA[1]='Y'; }

ABC=1;

m1:

printf("&bsol;rЭ <<<-------------[ Расчёт N:%i ]------------->>> Э &bsol;n",ABC);

scanf("%s",&S);

if (OTLADKA[1]=='Y') printf("&bsol;n**** Отладочная информация *****&bsol;n");

m=strlen(S);

p=buf;a1=a; b1=b; //указатели

k=0;iKol=0;l=0;u1=0;u2=0;

/*Получение числа спомощью функции и запись в массив а, где l-счетчик-длинны числа*/

for (i=0; i<(m+1); i++)

{

if (S[i]=='1'){ buf[i]=1;l++;}

else if (S[i]=='2'){ buf[i]=2;l++;}

else if (S[i]=='3'){ buf[i]=3;l++;}

else if (S[i]=='4'){ buf[i]=4;l++;}

else if (S[i]=='5'){ buf[i]=5;l++;}

else if (S[i]=='6'){ buf[i]=6;l++;}

else if (S[i]=='7'){ buf[i]=7;l++;}

else if (S[i]=='8'){ buf[i]=8;l++;}

else if (S[i]=='9'){ buf[i]=9;l++;}

else if (S[i]=='0'){ buf[i]=0;l++;}

else { if (l!=0) {

a[iKol]=ChartoInt (p,i,l);

iKol++; //счетчик кол-ва чисел

l=0; //обнуление счетчика длинны числа

}

}

/*Вылавливание знака и присваивания ему номера 1-6 */

switch (S[i]) {

case '+' :b[k]=1; k++; break;

case '-' :b[k]=2; k++; break; // к-счетчик кол-ва знаков

case '*' :b[k]=3; k++; break;

case '/' :b[k]=4; k++; break;

case '&bsol;0' : break; //Завершение сканирования если конец

case '(' :b[k]=5; u1++; k++; break;

case ')' :b[k]=6; u2++; k++; break;

default :break;}

if(S[i]=='=') { break;} // Завершение сканирования

}

if(u1!=u2){goto m1;} // Проверка на кол-во скобок

Scobka(a1,b1,iKol,k); // получение ответа

c=Sumin(a1,b1,iKol,k);// присваивание ответа

s=(int)c; // округление до целого числа

if (OTLADKA[1]=='Y') printf("&bsol;n ***** OTLADKA INFO [END]*******&bsol;n");

puts("Э ---------------------------- Э");

printf("&bsol;r OTBET=[ %i ]&bsol;n",s); // вывод ответа

puts("Э ---------------------------- Э");

printf("&bsol; [ 3AHOBO? (Any key/n) ]&bsol;r"); if (getch()!=='n') {goto m1;}

}

}

/*==================[Конец программы]==================*/

int ChartoInt (int *p, int i, int l)

{

int a,j,b,b2,m;

a=0;

m=i+1-l;//Вычисление начала работы с массивом данных xx>[m]YYY>xxx

for (j=m; j<= (i+1); j++) // ‘1 2 3’ => 100+20+3=123

{

b=pow(10,(i-j)); //кол-во нулей

b2=p[j-1]; // извлекаемая цифра

a=a+(b2*b); //число1+ число2+… числоN= число

}

return (a);

}

double Sumin (int *pa1,int *pb1,int j,int k)

{

int i, buf1,l;

double s;

/* начало сканирования массива данных и чисел с опредилением приоретета */

for (i=0;i<=(k+1); i++)

{

if ( pb1[i]==3) //"*"

{

buf1=pa1[i]*pa1[i+1];//умножение x*y

pa1[i]=buf1; //присвоение нового числа

for(l=(i+1);l<=(j+1);l++) //сдвиг на кол-во xxx-cc*dd

{

pa1[l]=pa1[l+1]; // сдвиг цифр

if (l==j)

{

pa1[l+1]=0;

pa1[j-1]=0;//для всех

l++;

j--; //уменьшение для того, чтобы цикл не съел знаки и числа

//X*Y-u X*Y=a => <a>-<u> "-"съелся

}

}

for(l=i;l<=(k+1);l++)

{

pb1[l]=pb1[l+1]; //сдвиг знаков

if (l==k)

{

pb1[l+1]=0;

l++;

k--;// уменьшение для того, чтобы цикл не съел знаки и числа

i--; // уменьшение для того, чтобы цикл не съел знаки и числа }

}

}

if ( pb1[i]==4) //"/"

{

buf1=pa1[i]/pa1[i+1];

pa1[i]=buf1;

for(l=(i+1);l<=(j+1);l++)

{

pa1[l]=pa1[l+1];

if (l==j)

{

pa1[l+1]=0;

l++;

j--;

}

}

for(l=i;l<=(k+1);l++)

{

pb1[l]=pb1[l+1];

if (l==k)

{

pb1[l+1]=0;

l++;

k--;

i--;

}

}

}

}

s=pa1[0];

l=0;

for (i=0; i<=(k+1);i++)//Выполнение действий согласно знаку

{

if (pb1[l]==1) //"+"

{

s=s+pa1[i+1];

l++;

}

else if (pb1[l]==2) //"-"

{

s=s-pa1[i+1];

l++;

}

}

int j1=0;

return (s);

}

void Scobka (int *a1,int *b1,int l,int k1)

{

int i,n,n1,j,array[126],barray[126],*par,*pbr,iShift,p,j3,iPar,iSk;

double c1;

int as,as1;//для отладки

par=array;// указатели на массивы для передачи в функцию

pbr=barray;

iPar=0; iSk=0;

for (i=0;i<=k1;i++)//основной цикл

{

if (b1[i]==5)//поиск скобок открытых

{

if (iPar==0) n=i; // указывает на начало скобок

iPar++;

}

if (b1[i]==6) //поиск скобок закрытых

{

if (iPar!=1)

{

iPar--;

iSk++;

continue;

}

n1=i;// указывает на конец скобок

p=0;//индекс для новых массивов

for(j=n;j<n1;j++)

{

array[p]=a1[j]; //создание временных массивов чисел

p++;

as=p; //для отладки

}

p=0;

for(j=(n+1);j<n1;j++)

{

barray[p]=b1[j];//создание временных массивов знаков

p++;

as1=p; //для отладки

}

if(iSk!=0)

{

if (OTLADKA[1]=='Y') Scobka(par,pbr,as,as1);

}

iShift=n1-n; //"Сдвиг"следует обратить внимание – 1

c1=Sumin(par,pbr,iShift,(iShift-1)); //возвращаемая сумма в скобках

if (OTLADKA[1]=='Y') printf("&bsol;n Разное количество скобок N=%f&bsol;n",c1);

a1[n]=(int)c1;

for(j3=0;j3<=iShift;j3++) //очистка массивов возможно ненужна

{

par[j3]=0;

pbr[j3]=0;

}

/*====================[сдвиг]==========================*/

if(l>n1)//l-количество чисел в массиве a1 если за скобками ничего нет то для упращения не нужно

{

for(j=(n+1);j<l;j++)

{

a1[j]=a1[j+iShift-1]; //сдвиг чисел

if (j==(l-iShift+1)) //учтено что массив начинается с нуля и точто сдвиг-1

{

for (j3=(l-iShift+1);j3<l;j3++) //обнуление вышедших за предел данных

{

a1[j3]=0;

}

j=l; //Выход из сдвига цикла для массива чисел

}

} //закрытия цикла сдвига чисел

l-=(iShift-1); //количество чисел уменьшилось

for(j=n;j<k1;j++)

{

b1[j]=b1[j+iShift+1]; //сдвиг знаков

if (j==(k1-iShift-2))

{

for (j3=(k1-iShift-1);j3<k1;j3++) //обнуление вышедших за предел данных

{

b1[j3]=0;

}

j=k1;//Выход из сдвига массива }

}

k1-=(iShift+1); //количество знаков уменьшилось

i=0; //пробежать цикл с начала

}//закрывает скобки проверки на на необходимость сдвига

else if(l==n1)

{

a1[n+1]=0;

b1[n]=0;

}

}

}

}

Приложение 2

Вывод результатов.