/* Parameters : * prevWord: the word before, the one for which we need to look up bigrams. * prevWordLength: its length. * codes: what user typed, in the same format as for UnigramDictionary::getSuggestions. * codesSize: the size of the codes array. * bigramChars: an array for output, at the same format as outwords for getSuggestions. * bigramFreq: an array to output frequencies. * maxWordLength: the maximum size of a word. * maxBigrams: the maximum number of bigrams fitting in the bigramChars array. * This method returns the number of bigrams this word has, for backward compatibility. * Note: this is not the number of bigrams output in the array, which is the number of * bigrams this word has WHOSE first letter also matches the letter the user typed. * TODO: this may not be a sensible thing to do. It makes sense when the bigrams are * used to match the first letter of the second word, but once the user has typed more * and the bigrams are used to boost unigram result scores, it makes little sense to * reduce their scope to the ones that match the first letter. */ int BigramDictionary::getBigrams(const int32_t *prevWord, int prevWordLength, int *codes, int codesSize, unsigned short *bigramChars, int *bigramFreq, int maxWordLength, int maxBigrams) { // TODO: remove unused arguments, and refrain from storing stuff in members of this class // TODO: have "in" arguments before "out" ones, and make out args explicit in the name mBigramFreq = bigramFreq; mBigramChars = bigramChars; mInputCodes = codes; mMaxBigrams = maxBigrams; const uint8_t* const root = DICT; int pos = getBigramListPositionForWord(prevWord, prevWordLength); // getBigramListPositionForWord returns 0 if this word isn't in the dictionary or has no bigrams if (0 == pos) return 0; int bigramFlags; int bigramCount = 0; do { bigramFlags = BinaryFormat::getFlagsAndForwardPointer(root, &pos); uint16_t bigramBuffer[MAX_WORD_LENGTH]; int unigramFreq = 0; const int bigramPos = BinaryFormat::getAttributeAddressAndForwardPointer(root, bigramFlags, &pos); const int length = BinaryFormat::getWordAtAddress(root, bigramPos, MAX_WORD_LENGTH, bigramBuffer, &unigramFreq); // codesSize == 0 means we are trying to find bigram predictions. if (codesSize < 1 || checkFirstCharacter(bigramBuffer)) { const int bigramFreq = UnigramDictionary::MASK_ATTRIBUTE_FREQUENCY & bigramFlags; // Due to space constraints, the frequency for bigrams is approximate - the lower the // unigram frequency, the worse the precision. The theoritical maximum error in // resulting frequency is 8 - although in the practice it's never bigger than 3 or 4 // in very bad cases. This means that sometimes, we'll see some bigrams interverted // here, but it can't get too bad. const int frequency = BinaryFormat::computeFrequencyForBigram(unigramFreq, bigramFreq); if (addWordBigram(bigramBuffer, length, frequency)) { ++bigramCount; } } } while (UnigramDictionary::FLAG_ATTRIBUTE_HAS_NEXT & bigramFlags); return bigramCount; }
int main() { char exitOperator = 'x'; char cancelOperator = 'c'; char addOperator = '+'; char subtractOperator = '-'; char multiplyOperator = '*'; char divideOperator = '/'; char squareOperator = 'r'; char powerOperator = '^'; char factorialOperator = '!'; char simplifyOperator = 's'; int numerator1, denominator1, numerator2, denominator2, resultNumerator, resultDenominator, exponent; double number1, number2, powerResult; char operator1 = '0', operator2, menuCharacter, character; loadOperatorsFromFile(exitOperator, cancelOperator, addOperator, subtractOperator, multiplyOperator, divideOperator, squareOperator, powerOperator, factorialOperator, simplifyOperator); bool exitMenu = false; do { menuCharacter = printMenu(); switch (menuCharacter) { case '1': printOperators(exitOperator, cancelOperator, addOperator, subtractOperator, multiplyOperator, divideOperator, squareOperator, powerOperator, factorialOperator); cout << "Write an inline expresion:" << endl; do { cin.sync(); checkFirstCharacter(character, number1); checkOperator(character, operator1, exitOperator); do { checkOperation(operator1, addOperator, number2, number1, subtractOperator, multiplyOperator, divideOperator, squareOperator, factorialOperator, powerOperator, exponent, powerResult, exitOperator, operator2, cancelOperator); if (operator2 == addOperator || operator2 == subtractOperator || operator2 == divideOperator || operator2 == multiplyOperator || operator2 == powerOperator || operator2 == factorialOperator || operator2 == squareOperator) { cin.get(operator1); } } while (operator1 != '\n' && operator1 != exitOperator); } while (operator2 != exitOperator); break; case '2': configureOperators(character, exitOperator, cancelOperator, addOperator, subtractOperator, multiplyOperator, divideOperator, squareOperator, powerOperator, factorialOperator); break; case '3': cout << endl << "Fractions mode" << endl << endl; printOperators(exitOperator, cancelOperator, addOperator, subtractOperator, multiplyOperator, divideOperator, squareOperator, powerOperator, factorialOperator); do { cout << "Write an inline fraction expresion:" << endl; cin.sync(); character = cin.peek(); if (isdigit(character)) { readFraction(numerator1, denominator1); if (numerator1 != 0 && denominator1 != 0) { cin.get(operator1); } else { operator1 = cancelOperator; } } else { cin.get(operator1); } do { //TODO extract checkSimplifyOperation(operator1, simplifyOperator, numerator1, denominator1); if (operator1 == addOperator) { readFraction(numerator2, denominator2); addFractions(numerator1, denominator1, numerator2, denominator2, resultNumerator, resultDenominator); printFraction(resultNumerator, resultDenominator); numerator1 = resultNumerator; denominator1 = resultDenominator; } if (operator1 == subtractOperator) { readFraction(numerator2, denominator2); subtractFractions(numerator1, denominator1, numerator2, denominator2, resultNumerator, resultDenominator); printFraction(resultNumerator, resultDenominator); numerator1 = resultNumerator; denominator1 = resultDenominator; } if (operator1 == multiplyOperator) { readFraction(numerator2, denominator2); multiplyFractions(numerator1, denominator1, numerator2, denominator2, resultNumerator, resultDenominator); printFraction(resultNumerator, resultDenominator); numerator1 = resultNumerator; denominator1 = resultDenominator; } if (operator1 == divideOperator) { readFraction(numerator2, denominator2); divideFractions(numerator1, denominator1, numerator2, denominator2, resultNumerator, resultDenominator); printFraction(resultNumerator, resultDenominator); numerator1 = resultNumerator; denominator1 = resultDenominator; } if (operator1 == powerOperator) { cin >> exponent; powerOfFractions(numerator1, denominator1, exponent, resultNumerator, resultDenominator); numerator1 = resultNumerator; denominator1 = resultDenominator; printFraction(numerator1, denominator1); } if (operator1 != cancelOperator) { cin.get(operator1); operator2 = cin.peek(); if (operator2 == cancelOperator) { numerator1 = 0; cout << numerator1 << endl; operator1 = exitOperator; } if (operator2 == simplifyOperator || operator2 == addOperator || operator2 == subtractOperator || operator2 == divideOperator || operator2 == multiplyOperator || operator2 == powerOperator) { cin.get(operator1); } } } while (operator1 != '\n' && operator1 != exitOperator); } while (operator2 != exitOperator); break; case '4': saveConfigurationToFile(exitOperator, cancelOperator, addOperator, subtractOperator, multiplyOperator, divideOperator, squareOperator, powerOperator, factorialOperator, simplifyOperator); exitMenu = true; break; } } while (!exitMenu); return 0; }