void rncAdd(RationalNumberCollection *c, RationalNumber rn) { // Wenn rn ungültig -> return if (!rnIsValid(rn)) { return; } // Länge der Collection ermitteln int len = rncTotalUniqueCount(*(&c)); // rn kürzen rn = rnShorten(rn); // Zeiger auf Collection RationalNumber (*ptr)[2] = c->rn; // Falls Bruch bereits vorhanden int i = rncSearch(*(&c), rn, 0, len-1); if (i >= 0) { // Erhöhe Counter des Bruchs ptr[i][1].numerator++; // Erhöhe totalCount der Collection c->totalCount++; // Erhöhe sum der Collection c->sum = rnShorten(rnAdd(c->sum,rn)); // Berechne average der Collection rncCalcAverage(*(&c)); return; } // Falls nocht nicht alle Elemente des Arrays belegt sind if (len < MAXSIZE) { // Trage den Bruch ein und erhöhe den Counter des Bruchs ptr[len][0] = rn; ptr[len][1].numerator++; // Erhöhe totalUniqueCount der Collection c->totalUniqueCount++; // Erhöhe totalCount der Collection c->totalCount++; // Erhöhe sum der Collection c->sum = rnShorten(rnAdd(c->sum,rn)); // Berechne average der Collection rncCalcAverage(*(&c)); } // Collection sortieren wenn Länge der Collection > 0 if (len > 0) { rncSort(*(&c), len+1); } // Berechne median der Collection rncCalcMedian(*(&c)); }
/* adds a new rational number to the collection or raises the count by one */ void rncAdd(RationalNumberCollection* c, RationalNumber r){ if(!rnIsValid(r)) { return; } RationalNumber rnOne = { 1, 1 }; RationalNumber rnZero = { 0, 1 }; if(c->totalUniqueCount == 0){ c->rnList[0] = r; c->rnList[1]= rnOne; rncAdded(c, r, true); }else{ int index = rncExists(c, r); if(index != -1){ if (rnEqual(r,rnZero) && rncCount(c,r) == 0) { rncAddSorted(c,r); rncAdded(c, r, true); } else { c->rnList[index+1] = rnAdd(c->rnList[index+1],rnOne); rncAdded(c, r, false); } } else { if (c->totalUniqueCount == 1000) { return; } //c->rnList[(c->totalUniqueCount)*2] = r; //c->rnList[(c->totalUniqueCount)*2+1] = rnOne; rncAddSorted(c,r); rncAdded(c, r, true); } return; } }
RationalNumberCollection *rncAdd(RationalNumberCollection* c, RationalNumber n) { printf("\n %i/%i will be added to storage.\n",n.numerator,n.denominator); int pos = rncFindPosition(c,n); // wenn es die RationalNumber schon im Array gibt if(pos != -1) { c->collection[pos].count++; RationalNumber summand = c->collection[pos].rn; c->rnSum = rnAdd(c->rnSum, summand); c->totalCount++; } else{ // schaffe Platz wenn der nfi belegt sein sollte. if(!(c->nfi < c->size)) { RationalNumberCollection *cNew = rncUpdateSize(c, true); c = rncDelete(c); c = cNew; } RationalNumber summand = n; c->rnSum = rnAdd(c->rnSum, summand); // und die perfekte Postition dem nfi entspricht if(rncFindIndex(c,n) == c->nfi) { c->collection[c->nfi].rn.numerator = n.numerator; c->collection[c->nfi].rn.denominator = n.denominator; c->collection[c->nfi].count++; c->nfi++; c->totalCount++; c->totalUniqueCount++; } else { int tempIndex = c->nfi; while(rncFindIndex(c,n) < tempIndex) { CollectionElement tempInhalt = c->collection[tempIndex - 1]; c->collection[tempIndex] = tempInhalt; tempIndex--; } int stelle = rncFindIndex(c,n); c->collection[stelle].rn = n; c->collection[stelle].count = 1; c->nfi++; c->totalCount++; c->totalUniqueCount++; } } print(c); return c; }
/* calculates the new values for the members of the given collection, after a rational number was added */ void rncAdded(RationalNumberCollection* c, RationalNumber r, bool isNew){ if(isNew){ c->totalUniqueCount++; } c->totalCount++; c->sum = rnAdd(c->sum, r); RationalNumber rnDivisor = { c->totalCount, 1 }; c->average=rnDivide(c->sum, rnDivisor); rncCalcMedian(c); return; }
} END_TEST /***** Test Add Function with triple digit numbers, exercising full suite *****/ START_TEST(test_add_function_with_complex_numbers_143_plus_352_equals_495) { RomanNumber rn1 = newRomanNumber("CXLIII"); RomanNumber rn2 = newRomanNumber("CCCLII"); RomanNumber sum = rnAdd(rn1, rn2); ck_assert_str_eq("CDXCV", to_string(sum)); ck_assert_int_eq(495, to_a(sum)); } END_TEST
} END_TEST /*** Test Add Function, using two digit numbers that require simplification ***/ START_TEST(test_add_function_with_moderately_complex_numbers_15_plus_17_equals_32) { RomanNumber rn1 = newRomanNumber("XV"); RomanNumber rn2 = newRomanNumber("XVII"); RomanNumber sum = rnAdd(rn1, rn2); ck_assert_str_eq("XXXII", to_string(sum)); ck_assert_int_eq(32, to_a(sum)); } END_TEST
} END_TEST /**************** Test Add Function, using larger digits, 5+2=7 ***************/ START_TEST(test_add_function_with_simple_math_5_plus_2_equals_7) { RomanNumber rn1 = newRomanNumber("V"); RomanNumber rn2 = newRomanNumber("II"); RomanNumber sum = rnAdd(rn1, rn2); ck_assert_str_eq("VII", to_string(sum)); ck_assert_int_eq(7, to_a(sum)); } END_TEST
void rncCalcMedian(RationalNumberCollection *c) { // Länge der Collection bestimmen int len = rncTotalUniqueCount(*(&c)); // Wenn Collection leer if (len == 0) { RationalNumber result = { 0, 1 }; c->median = result; } // Zeiger auf Collection RationalNumber (*ptr)[2] = c->rn; // Wenn Länge der Collection == 1 if (len == 1) { c->median = ptr[0][0]; } // Wenn Länge der Collection == 2 if (len == 2) { RationalNumber r = { 2, 1 }; c->median = rnShorten(rnDivide(rnAdd(ptr[0][0], ptr[1][0]), r)); } // Wenn Länge der Collection gerade if (len%2 == 0) { RationalNumber r = { 2, 1 }; int lowerMedian = (len / 2) - 1; int upperMedian = len / 2; c->median = rnShorten(rnDivide(rnAdd(ptr[lowerMedian][0], ptr[upperMedian][0]), r)); } // Wenn Länge der Collection ungerade else { int median = len / 2; c->median = ptr[median][0]; } }
int main() { printf("Performing unit tests for RationalNumber..."); fflush(stdout); /* Part 1 - RationalNumber data type */ RationalNumber n1 = { 3, 4 }, n2 = { 6, 4 }, n3 = { 3, 2 }, n4 = { -9, -6 }, n5 = { 9, -6 }, n6 = { 9, 4 }, n0 = { 0, 4 }, nn = { 4, 0 }; assert( rnIsValid(n0) ); assert( !rnIsValid(nn) ); assert( rnEqual( n2, n3) ); assert( rnEqual( rnAdd(n1,n1), n2) ); assert( rnEqual( n2,n4) ); assert( !rnEqual( n4,n5) ); assert( rnLessThan( n5,n3) ); RationalNumber t1 = rnAdd(n1,n2); RationalNumber t2 = rnDivide(n3,n3); RationalNumber t3 = rnDivide(n2,n2); RationalNumber t4 = rnDivide(n6,n0); assert( rnEqual(t1, n6) ); assert( rnEqual(t2, t3) ); assert( !rnIsValid(t4) ); printf(" successful!\n"); return 0; }
} END_TEST /******************************************************************************* * Use above API to add two roman numbers * ******************************************************************************/ /******************** Test Add Function, start simple 1+1=2 *******************/ START_TEST(create_function_to_add_two_numbers) { RomanNumber rn1 = newRomanNumber("I"); RomanNumber rn2 = newRomanNumber("I"); RomanNumber sum = rnAdd(rn1, rn2); ck_assert_str_eq("II", to_string(sum)); ck_assert_int_eq(2, to_a(sum)); } END_TEST
/* calculates the median for the given collection */ void rncCalcMedian(RationalNumberCollection* c) { if (c->totalCount == 0) { RationalNumber rnZero = { 0,1 }; c->median = rnZero; return; } else if (c->totalCount == 1) { c->median = c->rnList[0]; return; } else if (c->totalCount % 2 == 0) { int medianDeepness = c->totalCount / 2; for (int i = 0; i < c->totalUniqueCount*2; i = i+2) { int count = c->rnList[i+1].numerator; while(count > 0) { medianDeepness--; count--; if(medianDeepness == 0) { RationalNumber rn1 = c->rnList[i]; RationalNumber rn2 = c->rnList[i+2]; RationalNumber rnDivisor = { 2,1 }; if (count != 0) { rn2 = c->rnList[i]; } c->median = rnDivide(rnAdd(rn1,rn2),rnDivisor); return; } } } return; } else { int medianDeepness = c->totalCount / 2 + 1; for (int i = 0; i < c->totalUniqueCount*2; i = i+2) { medianDeepness = medianDeepness - c->rnList[i+1].numerator; if (medianDeepness <= 0) { c->median = c->rnList[i]; return; } } return; } }
void rncCalcAverage(RationalNumberCollection *c) { // Zeiger auf Collection RationalNumber (*ptr)[2] = c->rn; // Alle Brüche in der Collection zählen und sie summieren int i = 0; RationalNumber count = { 0, 1 }; RationalNumber result = { 0, 1 }; while(ptr[i][1].numerator > 0) { result = rnAdd(result, rnMultiply(ptr[i][0], ptr[i][1])); count.numerator += ptr[i][1].numerator; i++; } // Wenn keine Brüche gespeichert if (count.numerator == 0) { count.numerator = 1; } // Gekürzte RationalNumber zurückgeben c->average = rnShorten(rnDivide(result, count)); }