Sat递归的穷举法(有使用分治想法,但是本质上是穷举了)

如需转载请注明出处。——liurunjia

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define ARRAYLENGTH 20
#define SENTENCES 91
#define VARIABLE 3
#define SenLength 128
//定义数组存储变元个数
int array[ARRAYLENGTH];
//保存结果
int arrayTemp[ARRAYLENGTH];
//定义存储子句的数值的数组
int sent[SENTENCES][VARIABLE] ;
//初始化数组
void initialArray(int temp[],int length)
{
     int i=0;
     for(;i<length;i++)
     {
           temp[i]=0;
     }
}
/*本函数用来是初始化子句数组,其功能是把子句里面的数字从string类型转换为int类型,并存储在数据空间里面
@ptr字符指针,保存文件名
@temp[][VARIABLE] 保存子句里的数值
@ firLen 表示数组第一个下标
@ secLen 表示数组第二个下标
*/
void initalSentArray(char *ptr,int temp[][VARIABLE],int firLen,int secLen)
{
     FILE *fptr;
     int i,j,m,n;
     if(fptr=fopen(ptr,"r"))
     {
         char str[SenLength];
         char strTemp[SenLength];
         for(i=0,j=0;(fgets(str,SenLength,fptr))!=NULL;i++)
         {
                 //printf("%d%s%s\n",i,"  ",str);
                
              int k=0;
              if(str[0]!='c'&&str[0]!='0'&&str[0]!='%'&&str[0]!='p')   
              {    
                    //printf("%d%s%s",j,"  ",str);
                    for(m=0,n=0;m<strlen(str);m++)
                    {
                         if(str[m]==' '&&m!=0)
                         {
                               if(strlen(strTemp)>0)
                               {
                                     temp[j][k]=atoi(strTemp);
                                     k++;
                                     for(;n>=0;n--)
                                     {
                                         strTemp[n]=' ';
                                     }
                                     n=0;
                               }
                         }
                         else
                         {
                               strTemp[n]=str[m];
                               n++;
                         }
                    }  
                    j++;  
              }
         }
         fclose(fptr);  
     }
     else
     {
         printf("%s\n","打开文件失败");
        
     }
}
/*检查是否满足,满足则返回true,不满足则返回false*/
int isSat()
{
     int sum;
     int i,j;
     for(i=0;i<SENTENCES;i++)
     {
             sum=0;
             for(j=0;j<VARIABLE;j++)
             {
                   if(sent[i][j]>0)
                      sum+=array[sent[i][j]-1];
                   else
                      sum+=array[0-sent[i][j]-1]?0:1;
             }
             if(sum==0)
             {
                  return 0;
             }
     }
     return 1;
}
/*递归调用本身*/
void divideAlgorithm(int index,int *flagPrt)
{
     int i;
     if(*flagPrt==1)
     {
          return;
     }
     if(index==ARRAYLENGTH&&isSat())
     {
           for(i=0;i<ARRAYLENGTH;i++)
           {
                 //printf("%d ",array[i]);
                 arrayTemp[i]=array[i];
                
           }
           //printf("\n");
           *flagPrt=1;
           return;
     }
     else
     {
         if(index<ARRAYLENGTH)
         {
               array[index]=0;
               divideAlgorithm(index+1,flagPrt);

               array[index]=1;
               divideAlgorithm(index+1,flagPrt);
         }
     }   
}
void run(char *str)
{
      //当前时间
      clock_t startTime,endTime;
      //定义flag标志位 flag=1表示已成功找到;flag=0表示没有
      int flag=0,j;
      int *flagPrt=&flag;
      FILE *fp;
      startTime=clock();
      if((fp=fopen("刘润佳10212764\\10212764--divideAndConquer.txt","a+"))==NULL)
      { /*以文本只写方式打开文件*/
           printf("cannot open file");
           exit(0);
      }
      //初始化Array
      initialArray(array,ARRAYLENGTH);
      initalSentArray(str,sent,SENTENCES,VARIABLE);
      //printf("%s\n","#刘润佳 10212764");
      fprintf(fp,"%s\n","#刘润佳 10212764");
      str+=5;
      //printf("%s%s%s%d%d%d","#",str,"    ",-VARIABLE,-ARRAYLENGTH,-SENTENCES);
      fprintf(fp,"%s%s%s%d%d%d","#",str,"    ",-VARIABLE,-ARRAYLENGTH,-SENTENCES);
      divideAlgorithm(0,flagPrt);
      //结束时间
      endTime=clock();
      //printf("%s%f\n","运行时间是:",((float)(endTime-startTime))/1000);
      double timeOff = ((double)(endTime-startTime))/1000;     
      //printf("%f\n",-timeOff);             
      fprintf(fp,"%s%f\n","-",timeOff);
      for(j=0;j<ARRAYLENGTH&&*flagPrt;j++)
      {
             fprintf(fp,"%d   ",arrayTemp[j]);
                           
             if(j%50==0&&j!=0)
             {
                   //printf("\n");
                   fprintf(fp,"\n");
             }
                           
      }    
      //printf("\n");
      fprintf(fp,"\n");
      fclose(fp);
}
int main()
{
      char *str="test\\t1.txt";
      run(str);
      str="test\\t2.txt";
      run(str);
      str="test\\t3.txt";
      run(str);
      str="test\\t4.txt";
      run(str);
      str="test\\t5.txt";
      run(str);
      str="test\\t6.txt";
      run(str);
      str="test\\t7.txt";
      run(str);
      str="test\\t8.txt";
      run(str);
      str="test\\t9.txt";
      run(str);
      str="test\\t10.txt";
      run(str);
      system("pause");
      return 0;
}

转载于:https://www.cnblogs.com/growing/archive/2010/11/21/1883171.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值