2
. xxxxx/x ..
< >
. .
< >
-
.
:
- . ( ).
- - - "wrong format" ,
- . 16. xyz..za_< >, , .
- , , , long int
- 5 (+-*/%), .
-
, , LIFO (. last in first out, ).
( ).
. , , , 1 . , .
. , NULL.
. 1
: ( , push), (pop) (peek).
(push) , , . .
(pop) , , ( ). .
:
- :
.
, .
, .
, .
|
|
:
, , . , . , . , , , , .
1, :
1)
( o1 -) o1 ,
( o1 , -) o1 ,
;
2) o1 .
, . ; , .
. . -5 0 5. 0 5, , .
.2. .
.3. .
.4. .
, 5 (+-%/*). - - "wrong format" , .
- , , LIFO.
#include <stdio.h>
#include <conio.h>
#include <locale>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#define M 4096
typedef struct STACK{
long int data;
STACK *next;
}STACK;
struct STACK * push(struct STACK * top, long int x)
{
STACK *tmp = (STACK*)malloc(sizeof(STACK));
tmp->data = x;
tmp->next = top;
return(tmp);
}
long int pop(STACK ** top)
{
STACK *vr;
long int a;
if (*top == NULL) return '\0';
else
{
vr = *top;
a = vr->data;
*top = vr->next;
vr->next = NULL;
free(vr);
return a;
}
}
void print_s(struct STACK *top)
{
if (top == NULL) return;
else
{
long int k = 0;
char f = 0;
k = pop(&top);
f = (char)k;
putchar(f);
print_s(top);
}
}
void print_n(struct STACK *top)
{
if (top == NULL) return;
else
{
long int k = 0;
k = pop(&top);
printf("%i ", k);
|
|
print_n(top);
}
}
long int get_ch(unsigned int & p, char *str,bool &error)// , , ,
{
long int new_numb = 0, ct = 0, z = 0, z1 = 0;
unsigned int i = p;
int syst_check = 0;
int numb[100];
int sist = 0;
while (str[i]!= '(' && str[i]!= ')' && str[i]!= '/' && str[i]!= '*' && str[i]!= '%' && str[i]!= '+' && str[i]!= '-' && syst_check == 0 && i < strlen(str))
{
if (str[i] == '_')
{
i++;
while (str[i]!= '(' && str[i]!= ')' && str[i]!= '/' && str[i]!= '*' && str[i]!= '_' && str[i]!= '%' && str[i]!= '+' && str[i]!= '-' && i < strlen(str))
{
sist = sist * 10 + str[i] - 48;
i++;
}
syst_check++;
}
else
{
if (str[i] == 'A' || str[i] == 'a') numb[ct] = 10;
else if (str[i] == 'B' || str[i] == 'b') numb[ct] = 11;
else if (str[i] == 'C' || str[i] == 'c') numb[ct] = 12;
else if (str[i] == 'D' || str[i] == 'd') numb[ct] = 13;
else if (str[i] == 'E' || str[i] == 'e') numb[ct] = 14;
else if (str[i] == 'F' || str[i] == 'f') numb[ct] = 15;
else numb[ct] = str[i] - 48;
i++;
ct++;
}
}
if (sist == 0) sist = 10;
if (sist > 1 && sist < 17)
{
for (int k = 0; k < ct; k++)
{
if (numb[ct - k - 1] < sist && numb[ct - k - 1] >= 0 && error==0)
{
z = pow(sist, k);
z1 = numb[ct - k - 1];
new_numb += z*z1;
}
else
{
error = 1;
printf("wrong_format\n");
p = i - 1;
break;
}
}
}
else
{
error = 1;
printf("wrong_format\n");
}
p = i - 1;
return(new_numb);
}
int proverka(char *str)
{
int bracket_ct = 0;
int dl = strlen(str);
char symb[5]{ '+', '*', '/', '%', '-' };// .
char numb[23]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F', '_'};// .
if (str[0] == '+' || str[0] == '/' || str[0] == '*' || str[0] == '%' || str[0] == ')' || (str[0] == '(' && str[1] == ')')) return(0);// ,
if (str[0] == '(') bracket_ct++;
for (unsigned int k = 1; k < dl - 1; k++)
{
int z = 0;
if (str[k] == '(')
{
for (int ct = 0; ct < 22; ct++)// ...
if (str[k - 1] == numb[ct]) return(0);
if (str[k - 1] == ')') return(0);//... .
for (int ct = 0; ct < 4; ct++)// ( , )...
if (str[k + 1] == symb[ct]) return(0);
if (str[k + 1] == ')') return(0);//... .
}
else if (str[k] == ')')
{
for (int ct = 0; ct < 22; ct++)// ...
if (str[k + 1] == numb[ct]) return(0);
if (str[k + 1] == '(') return(0);//... .
for (int ct = 0; ct < 5; ct++)// ...
if (str[k - 1] == symb[ct]) return(0);
if (str[k - 1] == '(') return(0);//... .
}
else if (str[k] == '+' || str[k] == '-' || str[k] == '/' || str[k] == '%' || str[k] == '*')
{
for (int ct = 0; ct < 5; ct++)// ...
if (str[k - 1] == symb[ct]) return(0);
for (int ct = 0; ct < 5; ct++)
if (str[k + 1] == symb[ct]) return(0);//... .
if (str[k - 1] == '(' && str[k]!= '-') return(0);// ( )...
if (str[k + 1] == ')') return(0);//... ( ).
}
else
{
bool prov = 0;
for (int z = 0;z<23;z++)
|
|
if(str[k] == numb[z]) prov=1;// , , .
if (prov == 0)
{
return(0);
}
}
if (str[k] == '(') bracket_ct++;// ...
if (str[k] == ')') bracket_ct--;
if (bracket_ct < 0) return(0);//... ...
}
if (str[dl-1] == '+' || str[dl - 1] == '/' || str[dl - 1] == '*' || str[dl - 1] == '%' || (str[dl - 2] == '(' && str[dl - 1] == ')'))return(0);
if (str[dl-1] == '(') bracket_ct++;
if (str[dl-1] == ')') bracket_ct-=1;
if (bracket_ct!= 0) return(0);//... .
return(1);
}
long int preobr(long int oper, long int ch_1, long int ch_2)
{
long int rez = 0;
if (oper == 42) rez = ch_1 * ch_2;
else if (oper == 43) rez = ch_1 + ch_2;
else if (oper == 45) rez = ch_1 - ch_2;
else if (oper == 47) rez = ch_1 / ch_2;
else if (oper == 37) rez = ch_1 % ch_2;
return(rez);
}
void calc(struct STACK **symb, struct STACK **numb, bool &error)
{
long int first_ch = 0, second_ch = 0, rez = 0;
long int s = 0;
s = pop(symb);
second_ch = pop(numb);
first_ch = pop(numb);
if ((second_ch == 0 && (s == 47 || s == 37)) || ((first_ch < 0 || second_ch < 0) && s == 37))
{
printf("wrong_format\n");
error = 1;
}
else
{
rez = preobr(s, first_ch, second_ch);
*numb = push(*numb, rez);
}
return;
}
void main(void)
{
while (1)
{
bool error = 0;
unsigned int i = 0;
struct STACK *symb = NULL;//
struct STACK *numb = NULL;//
setlocale(LC_ALL, "Russian");
char str[M];
gets_s(str);
if (proverka(str) == 0)//
{
printf("wrong_format\n");
}
else// ,
{
for (i = 0; i < strlen(str); i++)
{
if (symb == NULL && (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' || str[i] == '%'))
{
symb = push(symb, str[i]);
}
else if (error == 1) break;
else if (str[i] == '(') symb = push(symb, str[i]);
else if (str[i] == ')')
{
long int k = 0;
while (symb->data!= 40)
{
calc(&symb, &numb, error);
}
k = pop(&symb);
}
else if (str[i] == '*' || str[i] == '/' || str[i] == '%')
{
long int k = symb->data;
if (k == 42 || k == 47 || k == 37)
{
calc(&symb, &numb, error);
symb = push(symb, str[i]);
}
else symb = push(symb, str[i]);
}
else if (str[i] == '+' || str[i] == '-')
{
if (str[i] == '-' && ((i > 0 && str[i - 1] == '(') || i == 0))
{
numb = push(numb, 0);
symb = push(symb, str[i]);
}
else
{
while (symb!= NULL && symb->data!= 40)
{
calc(&symb, &numb, error);
}
symb = push(symb, str[i]);
}
}
else if (str[i] == '_')
{
printf("wrong_format\n");
error=1;
break;
}
else numb = push(numb, get_ch(i, str,error));
}
if (error!= 1)
{
while (symb!= NULL && error!= 1)
calc(&symb, &numb, error);
if (error!= 1)
{
long int rezult = 0;
rezult = pop(&numb);
printf("%i\n", rezult);
free(numb);
free(symb);
}
}
}
_getch();
}
}