Go to content

geek_stuff/today

자료구조 과제 #1

/*/////////////////////////////////
Data Structure Assignment #1


과제1:
Operand의 크기가 너무커서 integer type으로 처리하지 못하는 더하기 연산을 integer 덧셈처럼 처리하는 프로그램을 작성하시오.

채점에 사용될 양식
예)
input.txt

21123424543254546575767868
+4235465475678687979797

2335344365547657
-345463574687

25434665457655765879
+4547568798080980

3543454
-46576985679

..
..
..
EOF

output.txt
325243436576970808976

3655765876987908606080

654768780900897979799
..
..
..

답 생성시 음수는 숫자앞에 '-'기호를 붙이셔야 됩니다.
위의 방식으로 하겠습니다.

값 사이의 줄 공백은 input 파일에서는 처리하셔야 되고
처리가 안되어 있다면 '순서대로 2줄을 읽어들여' 처리하는 식으로 되어 있으면 됩니다.

output파일에서의 공백은 처리 안하셨어도 됩니다.
*/

#include <fstream.h> // includes iostream.h
#include <string.h>  // for strcmp()

#define IN_FILE "C:\\input.txt" // don't forget to use double '\\' instead of '\'
#define OUT_FILE "C:\\output.txt"
#define MAX_LEN 200 // up to 200 chars (w/ cr & sign, +1)
#define POSITIVE 0
#define NEGATIVE 1

void mysort(char *mychar) // clear out spaces;
{
int j=0;
char temp[MAX_LEN]=""; // clearing garbages out (will temporary store cleared *mychar values)
for (int i=0;i<=MAX_LEN+1;i++)
{
 if (mychar[i]!=' ') temp[j++]=mychar[i]; // if the character is not a blank, than save to the temp.
}
strcpy(mychar, temp); // overwrite strings with 'blank removed' ones.


int signcheck_rmv(char *mychar) // check sign and return 1 if it's negative, else 0.
{
int ret_key=0;
for (int i=0;i<=MAX_LEN+1;i++)
{
 switch(mychar[i])
 {
 case '-':
  ret_key=1;     // if it's negative turn the flag on.
 case '+':
  mychar[i]=' '; // and then change the sign symbol to a blank.
  break;
 }
}
mysort(mychar); // call sort function to remove spaces

return ret_key; // return 1 if it's negative, otherwise 0
}


void remove_zeros(char* output) // remove front zeros, ej) 001023 -> 1023
{
char temp[MAX_LEN]="";
strcpy(temp,output);

for (int i=0;(unsigned)i<strlen(temp);i++) {
 if(temp[i]>='1') break;
 else temp[i]=' ';
}
mysort(temp);

if (strcmp(temp,"")==0) strcpy(temp,"0"); // leave one '0', if output is null.
strcpy(output,temp);
}


inline int bigger(int a, int b){ if(a>b) return a; else return b; }  // return bigger integer, else return first input.


void reform(char *mychar, int len) //digit count and modify 11 as 0011 to fit for 2222
{
int j=len-strlen(mychar); //+1 is for case of increase of number over 10
if (strlen(mychar)==(unsigned)len) {} //skip if strlen(mychar) is equal to itself.
else {
 while(j--) {
  for (int i=len; i>=0; i--) //repeat as length of mychar.
  {
   if(i<=0) mychar[i]='0'; // put '0' to mychar[i] if [i] is 0.
   else mychar[i]=mychar[i-1]; //otherwise
  }
 }
}
}


void calculate_plus(char* a, char* b, char *output, int last) // calculate and saves value to *output
{
int c=0;
int inta, intb;

char temp[MAX_LEN]="";

// digit count and modify 11 as 0011 to fit for 2222
reform(a, last);
reform(b, last);
reform(temp, last);

for (int i=1;i<=last;i++)
{
 inta=a[last-i]-'0';
 intb=b[last-i]-'0'; // converts a character to an integer
 //cout<<"inta+intb:"<<inta+intb<<endl;

 temp[last-i]=(((inta+intb)%10)+c)+'0'; // perform plus calculation

 if((inta+intb)/10) // if a+b is over 10, then we need to
 {
  c=1;    // set flag to 1 which says the output is more than 10.
  if(i==last) // in case the output have more digit than input, like 999+999.
  {
   reform(temp,strlen(temp)+1); // increase one more digit
   temp[0]='1';                 // then put 1 in front.
  }
 }
 else c=0; // otherwise reset the flag
}

remove_zeros(temp);
strcpy(output,temp); // copy temp to output
}


void calculate_minus(char* a, char* b, char *output, int last) // calculate and saves value to *output
{
int inta=0, intb=0, c=0;
char temp[MAX_LEN]="";
char my_a[MAX_LEN]="";
char my_b[MAX_LEN]="";

strcpy(my_a,a);
strcpy(my_b,b);

// count digit and modify 11 as 0011 to fit for 2222
reform(temp, last);
reform(my_a, last);
reform(my_b, last);

for (int i=1;i<=last;i++)
{
 if((my_a[last-i]-'0')==0) inta=0;
 else inta=(my_a[last-i]-'0');
 if((my_b[last-i]-'0')==0) intb=0;
 else intb=(my_b[last-i]-'0'); // converts a character to an integer


 if(inta-intb-c>=0)
 {
  temp[last-i]=(((inta-intb)%10)-c)+'0'; // perform minus calculation
  c=0;
 }
 else //if(inta-intb-c<0)
 {
  temp[last-i]=(inta-intb-c+10)+'0';
  c=1;
 }
}
remove_zeros(temp);
strcpy(output, temp);
}


int calculate(char *a, char *b, char *output, int a_is_neg, int b_is_neg) //(unsigned)bigger number comes to a, return 1 when the answer is MINUS.
{
char temp[MAX_LEN]="";
int type_a=0, type_b=0, i;
int len_a=strlen(a);
int len_b=strlen(b);
int last=bigger(len_a,len_b);

int a_size=1, b_size=1;

if(len_a==len_b) // assume that we have same length, because we already reform(a)&(b)
{
 for (i=0;i<=last;i++) // compare one by one
 {
  if(a[i]>b[i]) a_size*=(i+1); // +1 to prevent result is 0,  when i==0;
  if(b[i]>a[i]) b_size*=(i+1);
 }
 //cout<<"a_size: "<<a_size<<endl<<"b_size: "<<b_size<<endl;
 if(a_size>b_size)
 {
  if(a_is_neg) {calculate_minus(a,b,output,last); return NEGATIVE;} // when a_is_big and a_is_neg, output must be NEGATIVE
  if(b_is_neg) {calculate_minus(a,b,output,last); return POSITIVE;}
  calculate_plus(a,b,output,last); return POSITIVE;
 }
 if(b_size>a_size) //switch between (a,b) is occuring here.
 {
  if(b_is_neg) {calculate_plus(b,a,output,last); return NEGATIVE;} // when b_is_big and b_is_neg, output must be NEGATIVE
  if(a_is_neg) {calculate_plus(b,a,output,last); return POSITIVE;}
  calculate_plus(a,b,output,last); return POSITIVE;
 }
 calculate_plus(a,b,output,last); return POSITIVE;
}


int LONG=1;  //define as variable because we have to change later..
int SHORT=0;
//negative=1
//positive=0

if (len_a>len_b) { type_a=LONG; type_b=SHORT; }
if (len_b>len_a) { type_b=LONG; type_a=SHORT; }
if (a_is_neg) type_a+=NEGATIVE; else type_a+=POSITIVE;
if (b_is_neg) type_b+=NEGATIVE; else type_a+=POSITIVE;

// long-  type_x=2,
// long+  type_x=1,
// short- type_x=1,
// short+ type_x=0.

// first determine two definite situation.
// long+a(1) - short-b(1) = 0 // minus_calc, return POSITIVE
// long+a(1) - short+b(0) = 1 // plus_calc, return POSITIVE
// long-a(2) - short-b(1) = 1 // plus_calc, return NEGATIVE
// long-a(2) - short+b(0) = 2 // minus_calc, return NEGATIVE
// short+a(0) - long-b(2) = -2 // switch, minus_calc, return NEGATIVE
// short+a(0) - long+b(1) = -1 // plus_calc, return POSITIVE
// short-a(1) - long-b(2) = -1 // plus_calc, return NEGATIVE
// short-a(1) - long+b(1) = 0 // switch, minus_calc, return NEGATIVE

// now arranging by output, we can see top 2 has distinctive output.

// long-a(2) - short+b(0) = 2 // minus_calc, return NEGATIVE
// short+a(0) - long-b(2) = -2 // switch, minus_calc, return NEGATIVE

// long+a(1) - short-b(1) = 0 // minus_calc, return POSITIVE
// short-a(1) - long+b(1) = 0 // switch, minus_calc, return NEGATIVE
// long+a(1) - short+b(0) = 1 // plus_calc, return POSITIVE
// long-a(2) - short-b(1) = 1 // plus_calc, return NEGATIVE
// short+a(0) - long+b(1) = -1 // plus_calc, return POSITIVE
// short-a(1) - long-b(2) = -1 // plus_calc, return NEGATIVE

// so we can write:
if ( (type_a-type_b) == 2 ) { calculate_minus(a,b,output,last); return NEGATIVE; }
else if ( (type_a-type_b) == -2 ) { calculate_minus(b,a,output,last); return NEGATIVE; }

// now we have 6 conditions left, so we change the calculation from a-b to a+b.
// then we'll have two distinctive output from them.

// long+a(1) + short-b(1) = 2 // minus_calc, return POSITIVE
// short-a(1) + long+b(1) = 0 // switch, minus_calc, return NEGATIVE

// long+a(1) + short+b(0) = 1 // plus_calc, return POSITIVE
// long-a(2) + short-b(1) = 3 // plus_calc, return NEGATIVE
// short+a(0) + long+b(1) = 1 // plus_calc, return POSITIVE
// short-a(1) + long-b(2) = 3 // plus_calc, return NEGATIVE

// so we can write:
else if ( (type_a+type_b) == 2 ) { calculate_minus(a,b,output,last); return POSITIVE; }
else if ( (type_a+type_b) == 0 ) { calculate_minus(b,a,output,last); return NEGATIVE; }

// now we have 4 conditions left, so we change the definition of long
// now change the def of long.
else{
 LONG=10;
 type_a=type_b=0; //reset type_a and type_b

 // recalculate then.
 if (len_a>len_b) { type_a=LONG; type_b=SHORT; }
 if (len_b>len_a) { type_b=LONG; type_a=SHORT; }
 if (a_is_neg) type_a+=NEGATIVE; else type_a+=POSITIVE;
 if (b_is_neg) type_b+=NEGATIVE; else type_a+=POSITIVE;

 // LONG=10
 // SHORT=0
 // NEGATIVE=1
 // POSITIVE=0
 
 // which makes
 // long-  type_x=11,
 // long+  type_x=10,
 // short- type_x=1,
 // short+ type_x=0.

 // we perform the plus calculations to determine next top two.
 // long+a(10) + short+b(0) = 10 // plus_calc, return POSITIVE
 // short+a(0) + long+b(10) = 10 // plus_calc, return POSITIVE
 
 // long-a(11) + short-b(1) = 12 // plus_calc, return NEGATIVE
 // short-a(1) + long-b(11) = 12 // plus_calc, return NEGATIVE

 // so we now can write:
 if ((type_a+type_b) == 10) { calculate_plus(a,b,output,last); return POSITIVE; }
 else { calculate_plus(a,b,output,last); return NEGATIVE; }
}

return POSITIVE; // return positive if the answer is 0 situation(a=b) like (111-111)=0
}


void main(void)
{
char a[MAX_LEN]="";
char b[MAX_LEN]="";
char output[MAX_LEN]="";  // clearing out garbages

// opening files...
ifstream input_file(IN_FILE); //open file to read
ofstream output_file(OUT_FILE); //open file to write
if(input_file.fail()) //input file check
 cerr << "Error opening "<<IN_FILE<<endl;
else if(output_file.fail()) //output file check
 cerr << "Error opening "<<OUT_FILE<<endl;
else
{
 while (! input_file.eof()) //loop starts to get lines, stops end of the file.
 {
  strcpy(output,""); // just in case if the line have odd number
  //read file by line
  input_file.getline(a, sizeof(a)); //get a line, when repeats get the next odd line
  input_file.getline(b, sizeof(b)); //get a next line, when repeats get the next even line
  if (strcmp(a,"EOF")==0 || strcmp(b,"EOF")==0) break; // break out loop when meets "EOF" string, no matter if there's more to read.
   // so, really doesn't matter either line number is on even, or odd.

  //calculation
  //remove the sign
  int is_a_neg=signcheck_rmv(a);
  int is_b_neg=signcheck_rmv(b);

  switch(calculate(a, b, output, is_a_neg, is_b_neg)) // check out whether output positive calculation or negative.
  {
  case NEGATIVE:
   reform(output,strlen(output)+1);
   output[0]='-';
  case POSITIVE:
   break;
  }

  //cout<<"a: "<<a<<endl<<"b: "<<b<<endl<<"o: "<<output<<endl;  // just for testing purpose.
  output_file<<output<<endl; // write a line to output file.
 }//end of eof checking loop
}//end of input file error checking

// closing files...
input_file.close();
output_file.close();
} //end of main(void)*/

'geek_stuff > today' 카테고리의 다른 글

1kko.com 블로그의 변천사  (0) 2006.05.21
자료구조 과제 #2  (0) 2006.05.10
심심해서 서버 하나를 뚫어봤다.  (0) 2006.05.08
Apple.com이 윈도우즈를 지원한다?!  (2) 2006.04.06
숫자 generator 프로그램  (0) 2006.03.27