/* 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;
}
Esempio n. 2
0
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;
}