//for循环里定义的变量会在函数里保留
细分的情况有很多种
//空出所需的空格,以便加上括号,再消去空格
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
int panduan(char *buff,int len);//可以加括号返回1否则0
int four(char c);//是那4个联结词就返回1否则0
void hanshu(char *buff,int len);
void jia(char *b,int g,int i,int sum);//加括号
void jia_left(char *b,int g,int sum);//联结词前加左括号
//void fei_jia_right(char *b,int g,int sum);/非!前加右括号
void jia_right(char *b,int g,int sum);/用来处理那4种联结词后面的右括号;
void yasuo_shuchu(char *buff,char *b);/压缩和输出
void main()
{
char buff[256];
puts("非 ! 与 ^ 或 | 条件 > 双条件 ~ \n");
scanf("%s",buff);
int len=strlen(buff);
if (!panduan(buff,len))
{
puts("此字符串不能加括号啊!");
}
else
{
hanshu(buff,len);
}
}
int panduan(char *buff,int len)//可以加括号返回1否则0
{
// 和下面一行等价 if ( !( (buff[0]=='!' || isalpha(buff[0]) ) && isalpha(buff[len-1]) ) )
if( four(buff[0]) || !isalpha(buff[len-1]) )
{判断头和尾
return 0;
}
for (int i = 0; i < len-1; ++i)
{
if (isalpha(buff[i]) && !four(buff[i+1]))return 0;//字母后面是4种联结词
if (four(buff[i]) && !(isalpha(buff[i+1]) || buff[i+1]=='!') )return 0;//4种后面是字母或非
if ( buff[i]=='!' && !(isalpha(buff[i+1]) || buff[i+1]=='!') )return 0;//非后面是字母或非
}
return 1;
}
int four(char c)//是那4个联结词就返回1否则0
{
return (c=='^' || c=='|' || c=='>' || c=='~');
}
void hanshu(char *buff,int len)
{
char b[128];够大吧?
for (int i = 0; i < 128; ++i)b[i]=' ';//全是空格
b[127]='\0';
int a[6]={0},sum=0;
char c[6];存放联结词,与int a数组相关联
c[1]='!';c[2]='^';c[3]='|';c[4]='>';c[5]='~';
for ( i = 0; i < len; ++i)
{
switch(buff[i])
{
case '!':++a[1];break;
case '^':++a[2];break;
case '|':++a[3];break;
case '>':++a[4];break;
case '~':++a[5];break;
}
}
//非 !与 ^ 或 | 条件 > 双条件 ~
sum=a[1]+a[2]+a[3]+a[4]+a[5];
for ( i = 0; i < len; ++i)b[(i+1)*sum]=buff[i];///每个字符之间均有sum个空格
int t=0;//用来指出未处理的最右边的联结词
for ( i = 1; i < 6; ++i)//int a数组顺序处理 非 !与 ^ 或 | 条件 > 双条件 ~
{
for (int j = a[i]; j>0 ; --j)//每个联结词的数量
{
for (int g = 0; g < 128; ++g)//b大数组,找联结词
{
if (b[g]==c[i])
{
++t;
if (t==j)//找到这个联结词的未处理的最右边的那个
{
jia(b,g,i,sum);//加括号
t=0;
break;
}
}
}
}
}
yasuo_shuchu(buff,b);/压缩和输出
}
void jia(char *b,int g,int i,int sum)/加括号,,g是b大数组的指位,i表示联结词种类
{
if (1==i)///!p
{
b[g-1]='(';
jia_right(b,g,sum); //非!前加右括号
}
else//a*b
{
jia_left(b,g,sum);那4种联结词前加左括号
jia_right(b,g,sum);//用来处理那4种联结词后面的右括号;
}
}
void jia_left(char *b,int g,int sum)联结词前加左括号
{
int left=0,right=0;
for (int i = 1; i < sum; ++i)
if ( b[g-i]==')' )++right;获取前面的右括号
if (right==0) b[g-sum-1]='(';//无右括号就在左边的字母后面加上左括号
else ((....))加括号
{
right=0;/重新来过
for ( i = g-1; i >0; --i)
{
if (b[i]=='(')++left;
if (b[i]==')')++right;
if(left==right && i < g-sum)//g-sum是防止小段区间里的空格的影响
{
b[i-1]='(';
break;
}
}
}
}
/*void fei_jia_right(char *b,int g,int sum)//非!前加右括号
{
int left=0,right=0;
for (int i = 1; i <= sum; ++i)//只是在后面的一小段空格里找左括号
if ( b[g+i]=='(' )++left;获取后面的左括号
if (left==0) b[g+sum+1]=')';//无左括号就在左边的字母后面加上右括号
else ((....))加括号
{
for ( i = g+sum; i < 128; ++i)
{
if (b[i]==')')++right;
if(left==right)
{
b[i+1]=')';
break;
}
}
}
}
*/
void jia_right(char *b,int g,int sum)//用来处理那4种联结词后面的右括号;
{
int left=0,right=0;
for (int i = 1; g+i < 128; ++i)
if ( b[g+i]=='(' )++left;获取后面的所有左括号
if (left==0) b[g+sum+1]=')';//无左括号就在右边的字母后面加上右括号
else ((....))加括号
{
left=0;//重新来过
for ( i = g+1; i < 128; ++i)
{
if (b[i]==')')++right;
if (b[i]=='(')++left;
if(left==right && i > g+sum)//g+sum是防止小段区间里的空格的影响
{
b[i+1]=')';
break;
}
}
}
}
void yasuo_shuchu(char *buff,char *b)/压缩和输出
{
int j=0;
for (int i = 0; i < 127; ++i)
if (b[i] != ' ')
buff[j++]=b[i];
buff[j]='\0';
puts(buff);
puts(b);
}
给条件语句加上括号
最新推荐文章于 2022-10-31 20:44:09 发布