게시판 즐겨찾기
편집
드래그 앤 드롭으로
즐겨찾기 아이콘 위치 수정이 가능합니다.
이 소스는 뭐가 잘못된 건가요?
게시물ID : jisik_74368짧은주소 복사하기
작성자 : 으잉Ω
추천 : 0
조회수 : 741회
댓글수 : 2개
등록시간 : 2010/04/01 21:34:15
C 로 카르노맵 짠건데 어떻게 고쳐야되죠...?
고수님들 도와줘요~ 

 

 

 #include <stdio.h>
    int ncterm(register, char *, register);
    int pairing(int, int);
 int count(int, register);
 int primes(int, int);
 int originprime(register, register);
 int fepi();
 int reduction(int);
  
 int nvars;  
 int nterms = 1;  
 int nwords;  
 int minterm[256];
 int noterm[256]; 
 int impchart[256][48]; 
 int impcnt[256]; 
 int impext[256]; 
 int essprm[48]; 
 int imps = 0;  
 int priterm[48]; 
 int pricare[48]; 
 int pptr; 
 char func = 'f';
 char vname[12]; 
 char *fgets();

 struct list {
  int term;
  int oneterm; 
  int twoterm; 
  int nocare;
  int match;
  } 
 plist[9196];

 

 /*********************************main*********************************/

void main(){

  int i, j;
   
  char in[120];
  char outline[120];
  char tterm[16];
  char vdig;

  register k=0, l=0, m=0;
  int flag = 0;
  char *gptr;

  register n, o;

  fprintf(stdout,"Input a logical expression, in sum of products form,\n");
  fprintf(stdout,"a,b,c,d..., a',b',c',d'\n");
  fprintf(stdout,"ex)ab'd+ac\n");


  gptr = fgets(in,120,stdin);

  nvars = 0;

  if ((gptr==NULL) || (in[0]=='\n')) {
   nvars =0;
   fprintf(stderr,"no input expression\n\n");
   main();
 }

  while (in[k] != '\n') {
   if ( in[k++] == '=' ) flag = k;
  }
  k = flag;

  while ( in[k] != '\n' ) {
   if ( in[k] == '+' ) {
    outline[l++] = in[k];
   } 
   else if ( in[k] == '\'' ) {
    outline[l] = outline[l-1];
    outline[l-1] = in[k];
    j++;
   } 
   else if (((in[k]>='a')&&(in[k]<='z')) || ((in[k]>='A')&&(in[k]<='Z'))) {
    outline[l++] = in[k];
    flag = 0;
    for ( m=0; m<nvars; m++ ) {
     if ( vname[m] == in[k] ) 
      flag = 1;
    }
    if ( flag == 0 ) {
     vname[nvars++] = in[k];
    }
   }
   k++;
  }
  outline[l++] = '+';


  for ( k=0; k<nvars; k++ ) {
   nterms *= 2;
  }
  nwords = ((nterms+(16-1))/16);
  k = 0;
  while ( k < nwords ) {
   for ( m=0; m<48; m++ ) 
    impchart[k][m] = 0;
   noterm[k] = 0;
   minterm[k++] = 0;
  }
  if ( nvars == 0 ) {
   fprintf(stderr," input is wrong\n");
   main();
  }
  m = 0;
  while ( m < l ) {
   tterm[nvars] = '1'; 
   for ( k=0; k<nvars; k++ ) 
    tterm[k] = 'X';
   while ( outline[m] != '+' ) {
    if ( outline[m] == '\'' ) {
     vdig = '0';
     m++;
    } 
    else vdig = '1';

    for ( k=0; k<nvars; k++ ) {
     if ( outline[m] == vname[k] ) {
      tterm[k] = vdig;
     }
    }
    m++;
   }
   ncterm(0,tterm,0);
   m++;
   
  }


  if ( (nvars > 0 ) && (nvars <= 12) ) {
   
   for ( o=0; o<nwords; o++ ) { //quine
    impcnt[o] = 0;
    impext[o] = 0;
   }
   for ( o=0; o<48; o++ ) {
    essprm[o] = 0;
   }
   for ( n=0; n<nterms; n++ ) {
    if ((((minterm[n/16]|noterm[n/16])>>n)&1) == 1 ) {
     plist[pptr].nocare = 0;
     plist[pptr].match = 0;
     plist[pptr].oneterm = 1;
     plist[pptr].twoterm = 0;
     plist[pptr++].term = n;
    
     if ( pptr >= 4096 ) {
      fprintf(stderr,"Too many minterms ( > %d )\n",4096);
      fprintf(stderr,"Process aborted\n");
      n = nterms;
      pptr = 0; 
     }
    }
   }
   pairing(0,pptr);
   i = fepi();
   reduction(i);
   }

  getchar();
}

 

 


 /*********************************ncterm*********************************/

int ncterm(register i,char *entry, register trm)


 {
  int num;
  char iterm;
  register j;

 if ( i >= nvars ) {
  sscanf(entry,"%d",&num);
  minterm[trm/16] |= num<<(trm);
  noterm[trm/16] &= ~(1<<(trm));
 } 
 else {
  sscanf(entry,"%1s",&iterm);
  if ( (iterm == '1') || (iterm == '0') ) 
  {
   trm = (trm<<1)|(iterm-'0');
   ncterm(i+1,entry+1,trm);
  } 
  else {
   trm = trm<<1;
   ncterm(i+1,entry+1,trm);
   trm |= 1;
   ncterm(i+1,entry+1,trm);
  }
 }
 return 0;
 }

 


 /*********************************pairing*********************************/

int pairing(int first, int last)

 int first, last
 {
  int match = 0; 
  int submatch = 0;
  int diff, diffx = 0;
  int fterm, dterm; 
  register next;  
  int jstart, second; 
  int i, j2;
  register j, k;

  jstart = first;
  second = first;
  next = last; 
  j = jstart;
  j2 = jstart;
  while ( jstart< last-1 ) {
   while ( j2 < (last-1) ) {
    for ( k=second+1; k<last; k++ ) {
     if ((plist[j].nocare == plist[k].nocare ) && 
      (count(nvars,plist[j].term) == 
      (count(nvars,plist[k].term)-1))  && 
      (count(nvars,diff=(plist[k].term^plist[j].term))==1) ) {
      
      if ((diffx==0)||((((plist[j].term-fterm)%dterm) == 0) && (diff==diffx))){
       match = 1;
       submatch = 1;
       if ( diffx == 0 ) {
        dterm = plist[k].term-plist[j].term;
        fterm = plist[j].term;
       }
       plist[j].match = 1;
       plist[k].match = 1;
       plist[next].match = 0;
       plist[next].nocare = plist[j].nocare|diff;
       plist[next].term = plist[j].term;
       plist[next].oneterm = j;
       plist[next++].twoterm = k;      
       second = k;
       diffx = diff;
       j = ++k;
      }
     }
    }
    if ( submatch == 1 ) {
     second += 2;
     j = second;     
     submatch = 0;
    } 
    else {
     j = ++j;
     j2 = j;
     second = j;
    }
   }    
   if ( match == 1 ) {
    pairing(last,next);
    j2 = plist[last].oneterm;
    j = j2;
    second = plist[last].twoterm;
    next = last;
    match = 0;
    diffx = 0;
   } 
   else {
    jstart++;
    second = jstart;
    j = jstart;
   }
  }
  primes(first,last);
  return 0;
 }

 

 /*********************************primes*********************************/

int primes(int first,int last)

 int first, last;
 {
  register i, j;
  int flag;
  int rep;
  int match;
  for ( j=first; j<last; j++ ) {
   if ( plist[j].match == 0 ) {
    flag = 0;
    for ( i=0; i<imps; i++ ) {
     if (count(nvars,plist[j].nocare) <= count(nvars,pricare[i]) ){
      if (((plist[j].nocare|pricare[i]) == (pricare[i])) &&
       (((~pricare[i])&priterm[i])==((~pricare[i])&plist[j].term))&&
       ((plist[j].term|priterm[i]|pricare[i]) ==
       (priterm[i]|pricare[i]))) {
       
       flag = 1;
      }
     } 
     else if (count(nvars,plist[j].nocare)>count(nvars,pricare[i])) {
      if (((pricare[i]|plist[j].nocare)==(plist[j].nocare)) &&
       (((~plist[j].nocare)&plist[j].term) ==
       ((~plist[j].nocare)&priterm[i])) &&
       ((priterm[i]|plist[j].term|plist[j].nocare) ==
       (plist[j].term|plist[j].nocare))) {
       
       flag = 2;
       rep = i;
      }
     }
    }

    if (flag == 0) {
     originprime(j,imps);
     priterm[imps] = plist[j].term;
     pricare[imps] = plist[j].nocare;
     imps++;
     if ( imps >= 48 ) {
      fprintf(stderr,"Warning, overflow of prime implicant chart\n");
      imps--; 
     }
    } 
    else if (flag == 2) {
     originprime(j,rep);
     priterm[rep] = plist[j].term;
     pricare[rep] = plist[j].nocare;
    }
   }
  }
  return 0;
 }

 

 /*********************************count*********************************/

int count(len,term)

 int len;
 register term;  
 {
  register i;
  register count = 0;
  for ( i=0; i< len; i++ ) count+=(term>>i)&1;
  return(count);
}


 /*********************************originprime*********************************/

int originprime(j,imp)

 register j; 
 register imp; 
 {
  if ( j < pptr ) {
   impchart[plist[j].term/16][imp] |= (1<<(plist[j].term));
  } 
  else {
   originprime(plist[j].oneterm,imp);
   originprime(plist[j].twoterm,imp);
  }
  return 0;
 }


 /*********************************fepi*********************************/

int fepi()

 {
  register i, j, k;
  int uncov;
  int temp;
  char echar;
  
  for ( i=0; i<nwords; i++ ) {
   for ( j=0; j<imps; j++ ) {
    impcnt[i] |= impchart[i][j];
   }
  }
  for ( i=0; i<nterms; i++ ) {
   temp = 0;
   for ( j=0; j<imps; j++ ) {
    temp += (((impchart[i/16][j]>>i))&1);
   }
   if ( temp >= 2 ) impext[i/16] |= (1<<(i));
  }
  for ( i=0; i<nwords; i++ ) {
   impcnt[i] &= ~noterm[i];
   impext[i] &= ~noterm[i];
   for ( j=0; j<16; j++ ) {
    if ( (((impcnt[i]>>j)&1) == 1) && (((impext[i]>>j)&1)==0) ) {
     k = 0;
     while ( ((impchart[i][k]>>j)&1) == 0 ) 
      k++;
     essprm[k] = 1;
    }
   }
  }
  fprintf(stdout,"\nPrime implicants & essential prime implicant ");
  for ( i=0; i<imps; i++ ) {
   if ( essprm[i] == 1 ) {
    echar = ' ';
    for ( j=0; j<nwords; j++ ) {
     impcnt[j] &= ~impchart[j][i];
    }
   } 
   else echar = ' ';
   fprintf(stdout,"\n%c ",echar);
   for ( j=0; j<nvars; j++ ) {
    if (((pricare[i]>>(nvars-1-j))&1) == 0) {    
     fprintf(stdout,"%c",vname[j]);
     if (((priterm[i]>>(nvars-1-j))&1) == 0) {
      fprintf(stdout,"'");
     }
    }
   }
   fprintf(stdout,"\t)) ");
   for ( j=0; j<nterms; j++ ) {
    if ( ((impchart[j/16][i]>>j)&1) == 1 ) 
     fprintf(stdout,"%d,",j);
   }
  }
  uncov = 0;
  for ( i=0; i<nwords; i++ ) {  
   uncov += count(16,impcnt[i]);
  }
  return(uncov);
 }

 

 /*********************************reduction*********************************/

int reduction(uncov)

 int uncov;
 {
  register i,j;
  int nonemps;  
  int terms, lits;
  int nons[48];
  int termlist[256];
  int fail; 
  long limit, li;  
  char oper;  

  struct current {
   int terms;
   int lits;
   int list[48];
  } 
  curbest;
  
  if ( uncov == 0 ) {
   fprintf(stdout,"\n    ->minimal expression is unique\n\n");
  } 
  else {
   fprintf(stdout,"\n    ->no unique minimal expression\n\n");
   j = 0;
   for ( i=0; i<imps; i++ )
    if (essprm[i] == 0) nons[j++] = i;
    nonemps = j;
    if ( nonemps > 32 ) {
     fprintf(stderr,"Warning! Only 32 prime implicants");
     fprintf(stderr,"considered for coverage\n of all terms ");
     fprintf(stderr,"Make %d implicants!!\n", nonemps-(32));
     nonemps = 32;
    }
    if ( nonemps > 16 ) {
     fprintf(stdout,"Warning! Large number of cyclical prime implicants\n");
     fprintf(stdout,"Computation will take awhile\n");
    }
    limit = 1;
    for ( i=0; i<nonemps; i++ ) limit *= 2; 
    curbest.terms = 32000;
    curbest.lits = 32000;
    curbest.list[0] = -1;
    for ( li=1L; li<limit; li++ ) {
     terms = count(2*16,li);
     if ( terms <= curbest.terms ) {
      lits = 0;
      for ( i=0; i<nwords; i++ )
       termlist[i] = impcnt[i];
      for ( i=0; i<nonemps; i++ ) {
       if (((li>>i)&1L) == 1L) {
        for ( j=0; j<nterms; j++ ) {
         if (((impchart[j/16][nons[i]]>>j)&1)==1) {
          termlist[j/16] &= ~(1<<(j));
         }
        }
       }
       lits += (nvars - count(nvars,pricare[nons[i]]));
      }
      fail = 0;
      for ( i=0; i<nwords; i++ ) {
       if ( termlist[i]!=0 ) fail = 1;     
      }     
      if ((fail==0) && ((terms<curbest.terms) || (lits<curbest.lits))) {
       curbest.terms = terms;
       curbest.lits = lits;
       j = 0;
       for ( i=0; i<nonemps; i++ ) {
        if (((li>>i)&1L)==1L) { 
         curbest.list[j++] = nons[i];
        }
       }
       curbest.list[j] = -1;
      }
     }
    }
    j = 0;
    while ( curbest.list[j] >= 0 ) {
     essprm[curbest.list[j]] = 1;
     j++;
    }
  }
  fprintf(stdout,"\nminimal expression:\n\n     %c(",func);
  for ( i=0; i<nvars; i++ ) {
   fprintf(stdout,"%c",vname[i]);
   if ( i < nvars - 1 ) fprintf(stdout,",");
  }
  fprintf(stdout,")");
  oper = '=';
  for ( i=0; i<imps; i++ ) {
   if ( essprm[i] == 1 ) {
    fprintf(stdout," %c ",oper);
    for ( j=0; j<nvars; j++ ) {
     if (((pricare[i]>>(nvars-1-j))&1) == 0) {
      fprintf(stdout,"%c",vname[j]);
      if (((priterm[i]>>(nvars-1-j))&1) == 0) {
       fprintf(stdout,"'");
      }
     }
    }
    oper = '+';
   }
  }
  fprintf(stdout,"\n\n");
  return 0;
 }
전체 추천리스트 보기
새로운 댓글이 없습니다.
새로운 댓글 확인하기
글쓰기
◀뒤로가기
PC버전
맨위로▲
공지 운영 자료창고 청소년보호