```c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#define MAX_WORD_LENGTH 100
#define MAX_DICTIONARY_SIZE 10000
#define VOWELS "aeiou"
typedef struct {
char word[MAX_WORD_LENGTH];
int frequency;
} Word;
typedef struct {
char word[MAX_WORD_LENGTH];
int index;
} DictionaryEntry;
Word words[MAX_DICTIONARY_SIZE];
DictionaryEntry dictionary[MAX_DICTIONARY_SIZE];
int dictionarySize = 0;
void addWord(char *word) {
int found = 0;
for (int i = 0; i < dictionarySize; i++) {
if (strcmp(dictionary[i].word, word) == 0) {
dictionary[i].frequency++;
found = 1;
break;
}
}
if (!found) {
strcpy(words[dictionarySize].word, word);
words[dictionarySize].frequency = 1;
dictionary[dictionarySize].index = dictionarySize;
dictionarySize++;
}
}
double logProbability(char *context, char *word) {
int contextLength = strlen(context);
int wordLength = strlen(word);
int totalWordsInContext = contextLength + wordLength;
int totalVowelsInContext = countVowels(context);
int totalVowelsInWord = countVowels(word);
int totalConsonantsInWord = totalWordsInContext - totalVowelsInWord;
int totalConsonantsInContext = totalWordsInContext - totalVowelsInContext;
int totalLettersInWord = totalConsonantsInWord + totalVowelsInWord;
int totalLettersInContext = totalConsonantsInContext + totalVowelsInContext;
int wordIndex = findWordIndex(word);
int contextIndex = findWordIndex(context);
double probability = exp((-1.0 * log(words[wordIndex].frequency)) * (totalLettersInWord));
double contextFrequency = exp((-1.0 * log(words[contextIndex].frequency)) * (totalLettersInContext));
double wordFrequency = exp((-1.0 * log(words[wordIndex].frequency)) * (totalLettersInWord));
double coOccurrenceFrequency = (contextFrequency * wordFrequency) / (totalLettersInContext * totalLettersInWord);
return probability * coOccurrenceFrequency;
}
int findWordIndex(char *word) {
int index = binarySearch(&dictionary[0], dictionarySize, word);
if (index >= 0) {
return dictionary[index].index;
} else {
return index;
}
}
int binarySearch(DictionaryEntry *array, int size, char *value) {
int low = 0;
int high = size - 1;
int mid;
int comparisonResult;
while (low <= high) {
mid = (low + high) >> 1;
comparisonResult = strcmp(array[mid].word, value);
if (comparisonResult == 0) {
return array[mid].index;
} else if (comparisonResult < 0) {
low = mid + 1;
} else if (comparisonResult > 0) {
high = mid - 1;
} else if (mid > high && mid < low) { // This is to handle the case when there are duplicate values in the array. We need to make sure we don't miss any of them. For example, consider the array [a, a, b] and the search value 'a'. The first 'a' will be found at index position zero, but the second 'a' will not be found because it falls between the two indices of the previous 'a'. So we need to adjust our search range accordingly. In this case, we adjust the high pointer to mid + 1 and continue searching. If we didn't do this, we would miss the second 'a'. Similarly, if we had an array like [b, a, a] and searched for 'a', we would also miss the first 'a' because it falls between the two indices of the second 'a'. Therefore, we adjust the low pointer to mid + 1 as well. This ensures that we always have a valid index to return even when there are duplicate values in the array. Note that this adjustment only needs to be made when mid > high and mid < low. Otherwise, we can simply return mid which would give us the correct result. However, by making this adjustment, we ensure that we don't miss any of the duplicate values. This is why we use the || condition in the if statement inside the while loop. It checks both conditions separately so that we can make the appropriate adjustment based on which condition is true. This way, we can ensure that we always have a valid index to return even when there are duplicate values in the array.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#define MAX_WORD_LENGTH 100
#define MAX_DICTIONARY_SIZE 10000
#define VOWELS "aeiou"
typedef struct {
char word[MAX_WORD_LENGTH];
int frequency;
} Word;
typedef struct {
char word[MAX_WORD_LENGTH];
int index;
} DictionaryEntry;
Word words[MAX_DICTIONARY_SIZE];
DictionaryEntry dictionary[MAX_DICTIONARY_SIZE];
int dictionarySize = 0;
void addWord(char *word) {
int found = 0;
for (int i = 0; i < dictionarySize; i++) {
if (strcmp(dictionary[i].word, word) == 0) {
dictionary[i].frequency++;
found = 1;
break;
}
}
if (!found) {
strcpy(words[dictionarySize].word, word);
words[dictionarySize].frequency = 1;
dictionary[dictionarySize].index = dictionarySize;
dictionarySize++;
}
}
double logProbability(char *context, char *word) {
int contextLength = strlen(context);
int wordLength = strlen(word);
int totalWordsInContext = contextLength + wordLength;
int totalVowelsInContext = countVowels(context);
int totalVowelsInWord = countVowels(word);
int totalConsonantsInWord = totalWordsInContext - totalVowelsInWord;
int totalConsonantsInContext = totalWordsInContext - totalVowelsInContext;
int totalLettersInWord = totalConsonantsInWord + totalVowelsInWord;
int totalLettersInContext = totalConsonantsInContext + totalVowelsInContext;
int wordIndex = findWordIndex(word);
int contextIndex = findWordIndex(context);
double probability = exp((-1.0 * log(words[wordIndex].frequency)) * (totalLettersInWord));
double contextFrequency = exp((-1.0 * log(words[contextIndex].frequency)) * (totalLettersInContext));
double wordFrequency = exp((-1.0 * log(words[wordIndex].frequency)) * (totalLettersInWord));
double coOccurrenceFrequency = (contextFrequency * wordFrequency) / (totalLettersInContext * totalLettersInWord);
return probability * coOccurrenceFrequency;
}
int findWordIndex(char *word) {
int index = binarySearch(&dictionary[0], dictionarySize, word);
if (index >= 0) {
return dictionary[index].index;
} else {
return index;
}
}
int binarySearch(DictionaryEntry *array, int size, char *value) {
int low = 0;
int high = size - 1;
int mid;
int comparisonResult;
while (low <= high) {
mid = (low + high) >> 1;
comparisonResult = strcmp(array[mid].word, value);
if (comparisonResult == 0) {
return array[mid].index;
} else if (comparisonResult < 0) {
low = mid + 1;
} else if (comparisonResult > 0) {
high = mid - 1;
} else if (mid > high && mid < low) { // This is to handle the case when there are duplicate values in the array. We need to make sure we don't miss any of them. For example, consider the array [a, a, b] and the search value 'a'. The first 'a' will be found at index position zero, but the second 'a' will not be found because it falls between the two indices of the previous 'a'. So we need to adjust our search range accordingly. In this case, we adjust the high pointer to mid + 1 and continue searching. If we didn't do this, we would miss the second 'a'. Similarly, if we had an array like [b, a, a] and searched for 'a', we would also miss the first 'a' because it falls between the two indices of the second 'a'. Therefore, we adjust the low pointer to mid + 1 as well. This ensures that we always have a valid index to return even when there are duplicate values in the array. Note that this adjustment only needs to be made when mid > high and mid < low. Otherwise, we can simply return mid which would give us the correct result. However, by making this adjustment, we ensure that we don't miss any of the duplicate values. This is why we use the || condition in the if statement inside the while loop. It checks both conditions separately so that we can make the appropriate adjustment based on which condition is true. This way, we can ensure that we always have a valid index to return even when there are duplicate values in the array.
上一篇:kol什么意思,能不能通俗地解释
下一篇:怎么样获得白血病?