/* Input 2 numbers and get the product. This version does not handle decimal or negative numbers or any wrong input. Error handling is minimal. */ using namespace std; #include <iostream> const int PARTLENGTH = 8; class Number { public: long part; Number * next; Number() { part = 0; next = NULL; } }; //Function Declarations string multiply(string, string); // Multiply 2 numbers int numparts(string); // Find out how many sections the string has Number * makeEmptyLinkedList(int); // Create a linked list with so many nodes void fillLinkedList(Number *, string); // Inserts the relevant values into the linked list void movenext(Number * &); // Updates the pointer to the next record void mult(Number *, Number *, long); // Multiply the linked list with a value and return it in another list void adjust(Number *); // Adjust the arithmetic overflow of a number void mult10(Number *); // Multiply 10 to the linked list void add(Number *, Number *); // Add 2 linked lists together void appendNumberToBuffer(Number *, string &); // Recurse through linked list and append to buffer string removeLeadingZeros(string); // Remove leading zeros from a string long tenpower(int); // Function for getting 10 ^ value passed //End function declarations int main(int argc, char *argv[]) { //First 2 command-line arguments constitute the numbers string strFirst = removeLeadingZeros(string(argv[1])); string strSecond = removeLeadingZeros(string(argv[2])); cout << "The product is " << multiply(strFirst, strSecond) << endl; return 0; } string multiply(string strFirst, string strSecond) { int nodes_1 = numparts(strFirst); Number * nFirst = makeEmptyLinkedList(nodes_1); fillLinkedList(nFirst, strFirst); Number * nInter = makeEmptyLinkedList(nodes_1 + 1); Number * nTotal = makeEmptyLinkedList(nodes_1 + numparts(strSecond) + 2); int iter = strSecond.length(); for (int i = 0; i < iter; i++) { mult(nFirst, nInter, strSecond[i] - '0'); adjust(nInter); mult10(nTotal); adjust(nTotal); add(nTotal, nInter); //This call also resets nInter to zero adjust(nTotal); } string strBuffer = ""; appendNumberToBuffer(nTotal, strBuffer); return removeLeadingZeros(strBuffer); } Number * makeEmptyLinkedList(int numlinks) { if (!numlinks) return 0; Number * nHead, * nTemp, * nOld; for (int i = 0; i < numlinks; i++) { nOld = nTemp; nTemp = new Number; if (!i) nHead = nTemp; else nOld->next = nTemp; } return nHead; } void fillLinkedList(Number * nHead, string strDigits) { char * sDup = strdup(strDigits.c_str()); strrev(sDup); for (int i = 0; nHead; i++, movenext(nHead)) { nHead->part = 0; for (int j = 0; j < PARTLENGTH; j++) { char chrLetterToAdd = sDup[(i * PARTLENGTH) + j]; if (chrLetterToAdd == '\0') break; int intDigitToAdd = chrLetterToAdd - '0'; nHead->part += intDigitToAdd * tenpower(j); } } } void movenext(Number * & nPointer) { nPointer = nPointer->next; } int numparts(string strValue) { int length = strValue.length(); int total = length / PARTLENGTH; return (length % PARTLENGTH) ? total + 1 : total; } void adjust(Number * nList) { int remain = 0; while (nList) { nList->part += remain; long divider = tenpower(PARTLENGTH); remain = nList->part / divider; nList->part %= divider; movenext(nList); } } void add(Number *nTotal, Number *nInter) { while (nInter) { nTotal->part += nInter->part; nInter->part = 0; movenext(nTotal); movenext(nInter); } } void mult10(Number * nList) { while (nList) { nList->part *= 10; movenext(nList); } } void mult(Number * nOperand, Number * nResult, long number) { while (nOperand) { nResult->part = nOperand->part * number; movenext(nOperand); movenext(nResult); } } long tenpower(int intExponent) { return (long) pow(10.0, (double) intExponent); } string removeLeadingZeros(string strValue) { int intNonZeroPos = strValue.find_first_of(string("123456789")); if (intNonZeroPos == string::npos) return string("0"); else { int intLength = strValue.length(); return strValue.substr(intNonZeroPos, intLength - intNonZeroPos); } } void appendNumberToBuffer(Number * nHead, string & strBuffer) { if (nHead->next) appendNumberToBuffer(nHead->next, strBuffer); char strPrintfFormat[10], strPartValue[10]; sprintf(strPrintfFormat, "%%0%dld\0", PARTLENGTH); sprintf(strPartValue, strPrintfFormat, nHead->part); strBuffer += strPartValue; }
Copyright © 1999-2008 Krishna Kumar, All Rights Reserved.