没看明白
不知道输入输出
不知道输入输出
不知道输入输出
2012-09-07 19:52
程序代码:/*stophin*/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <iostream>
using namespace std;
#define M 100 //最大输入字符元素个数
#define N 80 //元素表中最大元素个数
#define NL 0 //无任何元素属性
#define CR 1 //关键字属性
#define ST 2 //字符串属性
#define BR 3 //括号属性
#define ER 4 //错误的属性
//用于创建表达式元素链表
struct exp
{
exp():pre(NULL),signum(0),attrib(NL),elenum(0),quonum(0),next(NULL) //构造函数
{
sig[0]='\0';
}
struct exp *pre; //前驱结点
char sig[N]; //结点数据
int signum; //结点数据个数
int attrib; //结点属性标识
int elenum; //标记个数,可用于标记括号对数
int quonum; //标记个数,可用于标记引号对数
struct exp *next; //后继结点
void insig(char c,int at=ST) //向结点数据写入字符,并做一些标记
{
if (signum>=N) //如果写满了,则不再写入,并标记属性错误
{
attrib=ER;
return;
}
if (at==BR) //如果是写入括号内的内容,则统计括号个数
{
if (c=='(')
elenum++;
else if (c==')')
elenum--;
}
if (at==ST) //如果是写入字符,则标记是否有括号和引号,有则置1
{
if (!elenum&&c=='(')
elenum=1;
else if (elenum&&c==')')
elenum=0;
if (!quonum&&c=='\"')
quonum=1;
else if (quonum&&c=='\"')
quonum=0;
}
sig[signum++]=c; //写入数据
sig[signum]='\0';
attrib=at; //设置写入数据的属性
return;
}
};
typedef struct exp E;
void freelink(E **ph) //释放结点
{
E * p = *ph;
E * q ;
while(NULL != p )
{
q = p->next ;
free(p);
p = q;
}
*ph=NULL;
return;
}
void viewlink(E *ph) //打印节点
{
while(ph!=NULL)
{
cout<<ph->sig<<"■";
ph=ph->next;
}
cout<<endl;
return;
}
E *creat(char *expr) //创建文字元素
{
E *head=NULL,*pre=NULL,*last=NULL,*old=NULL;
int i=0;
int l=strlen(expr); //获取文字元素长度
if (expr[i]!='\0')
{
head=new E; //创建头结点
if (!head)
{
printf("0293 创建字串链表头结点时内存空间分配失败!\n");
return NULL;
}
old=last=head;
while (i<l)
{
if (expr[i]==' ') //略去前面的空格
{
i++;
continue;
}
pre=new E;
if (!pre)
{
printf("0294 为 \"%c\" 创建字串链表时内存空间分配失败!\n",expr[i]);
pre=old;
}
//核心--------------------------------------------------------------
if (expr[i]=='(') //如果是开括号
{
do //则一直写入,并统计括号匹配情况
{
if (expr[i]!=' ')
pre->insig(expr[i],BR);
i++;
//直到括号完全匹配,或者遇到关键字停止,同样关键字要满足一些条件
//该条件与下面的"其余情况"中的if条件相差无几,详见下面的说明
if (!pre->elenum||(expr[i]=='i')&&(i<=l-1&&expr[i+1]=='n')&&(i&&(expr[i-1]==' '||expr[i-1]==')'||expr[i-1]=='\"'))&&(i<=l-2&&expr[i+2]==' '||expr[i+2]=='('||expr[i+2]=='\"'))
{
break;
}
}while(expr[i]!='\0');
i--;
}
else if (expr[i]=='\"') //如果是引号
{
do //则一直写入
{
pre->insig(expr[i]);
i++;
if (expr[i]=='\"') //直到遇到下一个引号停止
{
pre->insig(expr[i]);
break;
}
}while(expr[i]!='\0');
}
else if ((expr[i]=='i')&&(i<=l-1&&expr[i+1]=='n')) //如果是关键字,则写入逗号,并标记关键字属性
{
// pre->insig(expr[i++],CR);
// pre->insig(expr[i],CR);
pre->insig(',',CR);
i++;
}
else //其余情况
{
do //则一直写入,并标记是否有引号和括号
{
if (expr[i]!=' '||pre->quonum) //如果有引号则引号中的字符不能略去空格
pre->insig(expr[i]);
i++;
//这里容错机制比较复杂
//首先在引号和括号未完成时不能跳出,即使遇到关键字,因为引号或括号中的"in"应该只是字符串或者变量之类的
//如果上述满足,则考虑是否是关键字,关键字前后必须有空格,或者"前面是闭括号或引号"并且"后面是开括号或引号"
//否则,认为是函数名之类的,形如 ")in(" 是关键字,而 "fin(" 不是关键字
if (!pre->elenum&&!pre->quonum&&(expr[i]=='i')&&(i<=l-1&&expr[i+1]=='n')&&(i&&(expr[i-1]==' '||expr[i-1]==')'||expr[i-1]=='\"'))&&(i<=l-2&&expr[i+2]==' '||expr[i+2]=='('||expr[i+2]=='\"'))
break;
}while(expr[i]!='\0');
i--;
}
//--------------------------------------------------------------
if (pre!=old)
{
last->next=pre;
pre->pre=last;
last=pre;
old=last;
i++;
}
else
{
freelink(&head);
break;
}
}
}
else
{
return NULL;
}
return head;
}
void getres(char *res,E * exp)
{
E *p=exp->next;
int i=0;
strcpy(res,"is_in(");
//要生成is_in(is_in(A,B),is_in(C,D))
//则已经生成了 (A , B) , (C , D)
//只要加上is_in(就行了
//先将(A , B)以及(C , D)联合,再将联合后的加个外壳is_in(进行最后联合
while(p!=NULL)
{
i=0;
p->elenum=0;
//这里有一个假设,即如果一个节点中的字符串括号是匹配的,
//则不需要加is_in(,比如(a) in b生成is_in((a),b),而不是is_in(is_in(a),b)
//而如果不匹配(一般来说应该是开括号多于闭括号),则将不匹配数目
//作为即将加上的is_in(数目,但is_in(的数目也受到连续开括号数目的限制
//如((a)in b)in c
//得到((a) , b) , c
//a的括号不匹配,所以应该加一个is_in(,即is_in((a)
//而b的括号也不匹配,但由于b的是闭括号,因此没有加任何东西(看下面循环里面的解释)
//这个假设将应用于带括号的算术表达式中
while(p->sig[i]!='\0') //检测括号匹配,开括号为正,闭括号为负
{
if (p->sig[i]=='(')
p->elenum++;
if (p->sig[i]==')')
p->elenum--;
i++;
}
if (p->elenum<0) //如果闭括号多,则将负值改为正,以配合下面的递减操作
p->elenum=-p->elenum;
i=0;
while(p->elenum--&&p->sig[i]!='\0') //如果括号不匹配,则进行加is_in(操作
{
if (p->sig[i]=='(') //这里要求开括号必须是字符开头连续的,否则退出循环,例如 b) 一进来就进入break了
strcat(res,"is_in(");
else
break;
i++;
}
strcat(res,p->sig+i); //将加完is_in(后剩下的部分添加进结果
p=p->next;
}
strcat(res,")");
return;
}
void link(char *str)
{
char* res=new char[2*M];
cout<<str<<"\n";
E *expre=creat(str);
viewlink(expre);
getres(res,expre);
cout<<res<<endl;
cout<<endl;
freelink(&expre);
delete res;
return;
}
int main()
{
char input1[M]="fun1(a1 ,\"in or not in\", \"((( (((((\") in fun2(\"(( (\\\"(in (\' ((\")";
char input2[M]="(A1 + A2) in (B1+B2)";
char input3[M]="(((( A1 + A2 )* (A3 + A4))/A5) in (B1+B2))in d";
char input4[M]="fun1llinij(\"((( A1 + A2 )* (A3 + A4))/A5)\") in fun2(\"if A in B\")";
char input5[M]="\"(A1)\" in ((A1)(B2))";
char input6[M]="A in join(B1, B2)";
char input7[M]="(a in b))in((c in d)in(e in f))";
char input8[M]="(r in((ain in b)in(((c in d)in(e in f))in g)))in h";
char input9[M]="((A)in B) in (C in D)";
link(input1);
link(input2);
link(input3);
link(input4);
link(input5);
link(input6);
link(input7);
link(input8);
link(input9);
getch();
return 0;
}
2012-09-08 18:07
2012-09-08 22:05
2012-09-08 22:37
程序代码:#include <stdio.h>
#include <string.h>
#include <ctype.h>
/* 表示一个字符串的开始和结束的索引 */
typedef struct {
int start; /* 包括 */
int end; /* 不包括 */
} Region;
char* strrcat(char* buffer, const char* expr, Region* region)
{
char* p = buffer;
int i = region->start, j = region->end;
for (; *p != '\0'; ++p) ;
for (; i < j; *p++ = expr[i++]) ;
*p = '\0';
return buffer;
}
char* resolve(const char* expr, char* buffer)
{
int length = strlen(expr);
int i, j;
/* 查找in关键字的索引 */
for (i = 0; i < length - 4; ++i)
if (isspace(expr[i]) && expr[i+1] == 'i' && expr[i+2] == 'n' && isspace(expr[i+3]))
break;
/* if (A in B)
* ^ ^
* i j
*/
j = i + 3;
Region A = {0, i}, B = {j + 1, length};
for (; expr[A.start] != '('; ++A.start) ;
++A.start;
for (; expr[B.end] != ')'; --B.end ) ;
strcpy(buffer, "if(is_in("); /* A,B)) */
strrcat(buffer, expr, &A);
strcat(buffer, ",");
strrcat(buffer, expr, &B);
strcat(buffer, "))");
return buffer;
}
void test(char** expr, int size)
{
int i; char buffer[1024];
for (i = 0; i < size; ++i)
puts(resolve(expr[i], buffer));
}
int main(void)
{
char* expr[] = {
"if((A1+A2) in (B1+B2))",
"if(\"(A1)\" in \"(A1)(B2)\")",
"if(A in join(B1, B2))",
"if((A1 + A2) in (B1+B2))",
"if(((( A1 + A2 )* (A3 + A4))/A5) in (B1+B2))",
"if(fun1(\"((( A1 + A2 )* (A3 + A4))/A5)\") in fun2(\"if A in B\"))"
};
test(expr, sizeof expr / sizeof *expr);
return 0;
}输出:
程序代码:if(is_in((A1+A2),(B1+B2)))
if(is_in("(A1)","(A1)(B2)"))
if(is_in(A,join(B1, B2)))
if(is_in((A1 + A2),(B1+B2)))
if(is_in(((( A1 + A2 )* (A3 + A4))/A5) , (B1+B2)))
if(is_in(fun1("((( A1 + A2 )* (A3 + A4))/A5)") , fun2("if A in B")))
2012-09-09 01:54
2012-09-10 04:27