/*/////////////////////////////////
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 |