Mình đã thành công khi ko cần thuật toán ký pháp BaLan để làm được bài này. Hjx mừng quá xá lun. Chắc người tiên phong làm bài dạng này mà ko cần dùng STACK
Thuật toán:
B1:Tối ưu biểu thức bằng cách bỏ đi khoảng trắng dư thừa
B2: Xác định 2 vị trí start là dấu ngoặc đơn mở cuối cùng và vị trí end là dấu ngoặc đơn đóng đầu tiên trong chuỗi tính từ trái qua.
B3: Thực hiện tính trong đoạn giữa từ start đến end.
B4: Xóa các ký tự trong đoạn từ start đến end.
B5: Chèn kết quả tính được từ B3 vào vị trí start sau khi xóa.
B6. Lặp lại bước 2 cho đến khi chuỗi không còn ngoặc đơn nào
#include <iostream>
#include <string>
using namespace std;
int Vtngoacmocuoi(char* s)
{
int len = strlen(s);
for(int i = len - 1; i >= 0; i--)
{
if(s[i] == '(')
return i;
}
}
int Vtngoacdongdau(char *s)
{
int len = strlen(s);
for(int i = Vtngoacmocuoi(s); i < len; i++)
{
if(s[i] == ')')
return i;
}
}
void XoaKyTu(char *s, int vt)
{
int len = strlen(s);
int i;
for(i = vt; i < len- 1 ; i++)
{
s[i] = s[i+1];
}
s[len - 1] = NULL;
}
void XoaKhoangTrangThua(char *s, int vtbatdau, int vtketthuc)
{
for(int i = vtbatdau; i < vtketthuc - 1; i++)
{
if(s[i] == ' ' && s[i+1] == ' ')
{
XoaKyTu(s,i);
i--;
}
}
if(s[vtbatdau] == ' ')
XoaKyTu(s, vtbatdau);
if(s[vtketthuc-1] == ' ')
XoaKyTu(s, vtketthuc-1 -1);
}
int tinhdoan(char *s,int vtbatdau, int vtketthuc)
{
XoaKhoangTrangThua(s, vtbatdau,vtketthuc);
int num1 = 0,num2 = 0, i = vtbatdau + 1;
bool checkam1 = false, checkam2 = false;
if(s[i] == '-')
{
checkam1 = true;
i++;
}
while(s[i] >= '0' && s[i] <= '9')
{
num1 = num1 * 10 + (s[i] - 48);
i++;
}
if(checkam1 == true)
num1 *= -1;
if(s[i+1] == '+')
{
int j = i + 3;
if(s[j] == '-')
{
checkam2 = true;
j++;
}
while(s[j] >= '0' && s[j] <= '9')
{
num2 = num2 * 10 + (s[j] - 48);
j++;
}
if(checkam2 == true)
num2 *= -1;
return (num1 + num2);
}
if(s[i+1] == '-')
{
int j = i + 3;
if(s[j] == '-')
{
checkam2 = true;
j++;
}
while(s[j] >= '0' && s[j] <= '9')
{
num2 = num2 * 10 + (s[j] - 48);
j++;
}
if(checkam2 == true)
num2 *= -1;
return (num1 - num2);
}
if(s[i+1] == '*')
{
int j = i + 3;
if(s[j] == '-')
{
checkam2 = true;
j++;
}
while(s[j] >= '0' && s[j] <= '9')
{
num2 = num2 * 10 + (s[j] - 48);
j++;
}
if(checkam2 == true)
num2 *= -1;
return (num1 * num2);
}
if(s[i+1] == '/')
{
int j = i + 3;
if(s[j] == '-')
{
checkam2 = true;
j++;
}
while(s[j] >= '0' && s[j] <= '9')
{
num2 = num2 * 10 + (s[j] - 48);
j++;
}
if(checkam2 == true)
num2 *= -1;
return (num1 / num2);
}
}
void ChenKyTu(char *s, char kytuchen, int vtchen)
{
int len = strlen(s);
for(int i = len; i > vtchen; i--)
{
s[i] = s[i-1];
}
s[vtchen] = kytuchen;
s[len + 1] = NULL;
}
bool KiemtracoNgoac(char *s)
{
for(int i = 0; i < strlen(s); i++)
{
if(s[i] == '(' || s[i] == ')')
return true;
}
return false;
}
bool KiemTraKhoangTrang(char *s)
{
for(int i = 0; i < strlen(s); i++)
{
if(s[i] == ' ')
return true;
}
return false;
}
int TinhBieuThuc(char *&s)
{
int vtbatdau = Vtngoacmocuoi(s);
int vtketthuc = Vtngoacdongdau(s);
if(KiemtracoNgoac(s)==false && KiemTraKhoangTrang(s) == true)
{
ChenKyTu(s,'(',0);
ChenKyTu(s,')',strlen(s));
vtbatdau = Vtngoacmocuoi(s);
vtketthuc = Vtngoacdongdau(s);
}
int c = tinhdoan(s, vtbatdau, vtketthuc);
char *a = new char[50];
itoa(c,a,10);
int lena = strlen(a);
if(KiemtracoNgoac(s)==false )
return atoi(s);
for(int j = 0; j < vtketthuc - vtbatdau + 1; j++)
{
XoaKyTu(s,vtbatdau);
}
for(int i = 0; i < lena; i++)
{
ChenKyTu(s,a[i],vtbatdau);
vtbatdau++;
}
TinhBieuThuc(s);
}
void main()
{
char *bieuthuc = new char[50];
cout<<"Nhap bieu thuc:\n";
fflush(stdin);
gets(bieuthuc);
cout<<endl<<"Ket qua bieu thuc la "<<TinhBieuThuc(bieuthuc);
system("pause");
}