permute.cpp
来自「一个google的OCR源码」· C++ 代码 · 共 1,706 行 · 第 1/3 页
CPP
1,706 行
free_choice(this_choice); if (display_ratings) print_word_choice("permute_characters", best_choice);}/********************************************************************** * permute_compound_word * * Return the top choice for each character as the choice for the word. **********************************************************************/A_CHOICE *permute_compound_words(CHOICES_LIST character_choices, float rating_limit) { A_CHOICE *first_choice; A_CHOICE *best_choice = NULL; char word[UNICHAR_LEN * MAX_WERD_LENGTH + 1]; char unichar_lengths[MAX_WERD_LENGTH + 1]; float rating = 0; float certainty = 10000; char char_choice; int x; int first_index = 0; char *ptr; word[0] = '\0'; unichar_lengths[0] = 0; if (array_count (character_choices) > MAX_WERD_LENGTH) { return (new_choice (NULL, NULL, MAX_FLOAT32, -MAX_FLOAT32, -1, NO_PERM)); } array_loop(character_choices, x) { first_choice = (A_CHOICE *) first_node ((CHOICES) array_value (character_choices, x)); ptr = class_string (first_choice); char_choice = ptr != NULL ? *ptr : '\0'; if (x > first_index && (char_choice == '-' || char_choice == '/')) { if (compound_debug) cprintf ("Hyphenated word found\n"); permute_subword (character_choices, rating_limit, first_index, x - 1, word, unichar_lengths, &rating, &certainty); if (rating > rating_limit) break; first_index = x + 1; strcat(word, class_string (first_choice)); char length[] = {strlen(class_string (first_choice)), 0}; strcat(unichar_lengths + x, length); rating += class_probability (first_choice); certainty = min (class_certainty (first_choice), certainty); } } if (first_index > 0 && first_index < x && rating <= rating_limit) { permute_subword (character_choices, rating_limit, first_index, x - 1, word, unichar_lengths, &rating, &certainty); best_choice = new_choice (word, unichar_lengths, rating, certainty, -1, COMPOUND_PERM); } return (best_choice);}/********************************************************************** * permute_subword * * Permute a part of a compound word this subword is bounded by hyphens * and the start and end of the word. Call the standard word permute * function on a set of choices covering only part of the original * word. When it is done reclaim the memory that was used in the * excercise. **********************************************************************/void permute_subword(CHOICES_LIST character_choices, float rating_limit, int start, int end, char *word, char unichar_lengths[], float *rating, float *certainty) { int x; A_CHOICE *best_choice = NULL; A_CHOICE raw_choice; CHOICES_LIST subchoices; CHOICES choices; char this_char; char *ptr; DisableChoiceAccum(); raw_choice.string = NULL; raw_choice.lengths = NULL; raw_choice.rating = MAX_INT16; raw_choice.certainty = -MAX_INT16; subchoices = new_choice_list (); for (x = start; x <= end; x++) { choices = (CHOICES) array_value (character_choices, x); ptr = best_string (choices); this_char = ptr != NULL ? *ptr : '\0'; if (this_char != '-' && this_char != '/') { subchoices = array_push (subchoices, choices); } else { const char* str = best_string(choices); strcat(word, str); char length[] = {strlen(str), 0}; strcat(unichar_lengths + x, length); } } if (array_count (subchoices)) { if (compound_debug) dawg_debug = TRUE; best_choice = permute_all (subchoices, rating_limit, &raw_choice); if (compound_debug) dawg_debug = FALSE; if (best_choice && class_string (best_choice)) { strcat (word, class_string (best_choice)); strcat (unichar_lengths, class_lengths (best_choice)); *rating += class_probability (best_choice); *certainty = min (class_certainty (best_choice), *certainty); } else { *rating = MAX_FLOAT32; } } else { *rating = MAX_FLOAT32; } free_choice_list(subchoices); if (best_choice) free_choice(best_choice); if (compound_debug && *rating < MAX_FLOAT32) { cprintf ("Subword permuted = %s, %5.2f, %5.2f\n\n", word, *rating, *certainty); } if (raw_choice.string) strfree(raw_choice.string); if (raw_choice.lengths) strfree(raw_choice.lengths); EnableChoiceAccum();}/********************************************************************** * permute_top_choice * * Return the top choice for each character as the choice for the word. * In addition a choice is created for the best lower and upper case * non-words. In each character position the best lower (or upper) case * character is substituted for the best overall character. **********************************************************************/A_CHOICE *permute_top_choice(CHOICES_LIST character_choices, float rating_limit, A_CHOICE *raw_choice, BOOL8 *any_alpha) { CHOICES char_list; A_CHOICE *first_choice; A_CHOICE *best_choice; A_CHOICE *other_choice; const char *ptr; const char *first_char; //first choice const char *second_char; //second choice const char *third_char; //third choice char prev_char[UNICHAR_LEN + 1]; //prev in word const char *next_char = ""; //next in word const char *next_next_char = ""; //after next next in word char word[UNICHAR_LEN * MAX_PERM_LENGTH + 1]; char capital_word[UNICHAR_LEN * MAX_PERM_LENGTH + 1]; char lower_word[UNICHAR_LEN * MAX_PERM_LENGTH + 1]; char word_lengths[MAX_PERM_LENGTH + 1]; char capital_word_lengths[MAX_PERM_LENGTH + 1]; char lower_word_lengths[MAX_PERM_LENGTH + 1]; int x; int x_word = 0; int x_capital_word = 0; int x_lower_word = 0; BOOL8 char_alpha; float rating = 0; float upper_rating = 0; float lower_rating = 0; float first_rating = 0; float certainty = 10000; float upper_certainty = 10000; float lower_certainty = 10000; float certainties[MAX_PERM_LENGTH + 1]; float lower_certainties[MAX_PERM_LENGTH + 1]; float upper_certainties[MAX_PERM_LENGTH + 1]; register CHOICES this_char; register const char* ch; register inT8 lower_done; register inT8 upper_done; prev_char[0] = '\0'; if (any_alpha != NULL) *any_alpha = FALSE; if (array_count (character_choices) > MAX_PERM_LENGTH) { return (NULL); } array_loop(character_choices, x) { if (x + 1 < array_count (character_choices)) { char_list = (CHOICES) array_value (character_choices, x + 1); first_choice = (A_CHOICE *) first_node (char_list); ptr = class_string (first_choice); next_char = (ptr != NULL && *ptr != '\0') ? ptr : " "; } else next_char = ""; if (x + 2 < array_count (character_choices)) { char_list = (CHOICES) array_value (character_choices, x + 2); first_choice = (A_CHOICE *) first_node (char_list); ptr = class_string (first_choice); next_next_char = (ptr != NULL && *ptr != '\0') ? ptr : " "; } else next_next_char = ""; char_list = (CHOICES) array_value (character_choices, x); first_choice = (A_CHOICE *) first_node (char_list); ptr = class_string (first_choice); if (ptr != NULL && *ptr != '\0') { strcpy(word + x_word, ptr); word_lengths[x] = strlen(ptr); strcpy(capital_word + x_capital_word, ptr); capital_word_lengths[x] = strlen(ptr); strcpy(lower_word + x_lower_word, ptr); lower_word_lengths[x] = strlen(ptr); } else { word[x_word] = ' '; word_lengths[x] = 1; capital_word[x_capital_word] = ' '; capital_word_lengths[x] = 1; lower_word[x_lower_word] = ' '; lower_word_lengths[x] = 1; } first_char = (ptr != NULL && *ptr != '\0') ? ptr : " "; first_rating = class_probability (first_choice); upper_rating += class_probability (first_choice); lower_rating += class_probability (first_choice); lower_certainty = min (class_certainty (first_choice), lower_certainty); upper_certainty = min (class_certainty (first_choice), upper_certainty); certainties[x] = class_certainty (first_choice); lower_certainties[x] = class_certainty (first_choice); upper_certainties[x] = class_certainty (first_choice); lower_done = FALSE; upper_done = FALSE; char_alpha = FALSE; second_char = ""; third_char = ""; iterate_list(this_char, char_list) { ptr = best_string (this_char); ch = ptr != NULL ? ptr : ""; if (strcmp(ch, "l") == 0 && rest (this_char) != NULL && best_probability (rest (this_char)) == first_rating) { ptr = best_string (rest (this_char)); if (ptr != NULL && (strcmp(ptr, "1") == 0 || strcmp(ptr, "I") == 0)) { second_char = ptr; this_char = rest (this_char); if (rest (this_char) != NULL && best_probability (rest (this_char)) == first_rating) { ptr = best_string (rest (this_char)); if (ptr != NULL && (strcmp(ptr, "1") == 0 || strcmp(ptr, "I") == 0)) { third_char = ptr; this_char = rest (this_char); } } ch = choose_il1 (first_char, second_char, third_char, prev_char, next_char, next_next_char); if (strcmp(ch, "l") != 0 && word_lengths[x] == 1 && word[x_word] == 'l') { word[x_word] = *ch; lower_word[x_lower_word] = *ch; capital_word[x_capital_word] = *ch; } } } if (ch != NULL && *ch != '\0') { /* Find lower case */ if (!lower_done && (unicharset.get_islower(ch) || (unicharset.get_isupper(ch) && x == 0))) { strcpy(lower_word + x_lower_word, ch); lower_word_lengths[x] = strlen(ch); lower_rating += best_probability (this_char); lower_rating -= class_probability (first_choice); lower_certainty = min (best_certainty (this_char), lower_certainty); lower_certainties[x] = best_certainty (this_char); lower_done = TRUE; } /* Find upper case */ if (!upper_done && unicharset.get_isupper(ch)) { strcpy(capital_word + x_capital_word, ch); capital_word_lengths[x] = strlen(ch); upper_rating += best_probability (this_char); upper_rating -= class_probability (first_choice); upper_certainty = min (best_certainty (this_char), upper_certainty); upper_certainties[x] = best_certainty (this_char); upper_done = TRUE; } if (!char_alpha && unicharset.get_isalpha(ch)) char_alpha = TRUE; if (lower_done && upper_done) break; } } if (char_alpha && any_alpha != NULL) *any_alpha = TRUE; if (first_choice == NULL) { cprintf ("Permuter giving up due to null choices list"); word[x_word + 1] = '$'; word[x_word + 2] = '\0'; word_lengths[x + 1] = 1; word_lengths[x + 2] = 0; cprintf (" word=%s\n", word); return (NULL); } rating += class_probability (first_choice); if (rating > rating_limit) return (NULL); certainty = min (class_certainty (first_choice), certainty); strncpy(prev_char, word + x_word, word_lengths[x]); prev_char[word_lengths[x]] = '\0'; x_word += word_lengths[x]; x_capital_word += capital_word_lengths[x]; x_lower_word += lower_word_lengths[x]; } word[x_word] = '\0'; word_lengths[x] = 0; capital_word[x_capital_word] = '\0'; capital_word_lengths[x] = 0; lower_word[x_lower_word] = '\0'; lower_word_lengths[x] = 0; if (rating < class_probability (raw_choice)) { if (class_string (raw_choice)) strfree (class_string (raw_choice)); if (class_lengths (raw_choice)) strfree (class_lengths (raw_choice)); class_probability (raw_choice) = rating; class_certainty (raw_choice) = certainty; class_string (raw_choice) = strsave (word); class_lengths (raw_choice) = strsave (word_lengths); class_permuter (raw_choice) = TOP_CHOICE_PERM; LogNewRawChoice (raw_choice, 1.0, certainties); } if (ngram_permuter_activated) return NULL; best_choice = new_choice (word, word_lengths, rating, certainty, -1, TOP_CHOICE_PERM); adjust_non_word(best_choice, certainties); other_choice = new_choice (lower_word, lower_word_lengths, lower_rating, lower_certainty, -1, LOWER_CASE_PERM); adjust_non_word(other_choice, lower_certainties); if (class_probability (best_choice) > class_probability (other_choice)) { clone_choice(best_choice, other_choice); } free_choice(other_choice); other_choice = new_choice (capital_word, capital_word_lengths, upper_rating, upper_certainty, -1, UPPER_CASE_PERM); adjust_non_word(other_choice, upper_certainties); if (class_probability (best_choice) > class_probability (other_choice)) { clone_choice(best_choice, other_choice); } free_choice(other_choice); return (best_choice);}/********************************************************************** * choose_il1 * * Choose between the candidate il1 chars. **********************************************************************/const char* choose_il1(const char *first_char, //first choice const char *second_char, //second choice const char *third_char, //third choice const char *prev_char, //prev in word const char *next_char, //next in word const char *next_next_char) { //after next next in word inT32 type1; //1/I/l type of first choice inT32 type2; //1/I/l type of second choice inT32 type3; //1/I/l type of third choice int first_char_length = strlen(first_char); int prev_char_length = strlen(prev_char); int next_char_length = strlen(next_char); int next_next_char_length = strlen(next_next_char); if (*first_char == 'l' && *second_char != '\0') { if (*second_char == 'I' && (((prev_char_length != 0 && unicharset.get_isupper (prev_char, prev_char_length)) && (next_char_length == 0 || !unicharset.get_islower (next_char, next_char_length)) && (next_char_length == 0 || !unicharset.get_isdigit (next_char, next_char_length))) || ((next_char_length != 0 && unicharset.get_isupper (next_char, next_char_length)) && (prev_char_length == 0 || !unicharset.get_islower (prev_char, prev_char_length)) && (prev_char_length == 0 || !unicharset.get_isdigit (prev_char, prev_char_length))))) first_char = second_char; //override else if (*second_char == '1' || *third_char == '1') { if ((next_char_length != 0 && unicharset.get_isdigit (next_char, next_char_length)) || (prev_char_length != 0 && unicharset.get_isdigit (prev_char, prev_char_length)) || (*next_char == 'l' && (next_next_char_length != 0 && unicharset.get_isdigit (next_next_char, next_next_char_length)))) { first_char = "1"; first_char_length = 1; } else if ((prev_char_length == 0 || !unicharset.get_islower (prev_char, prev_char_length)) && ((next_char_length == 0 || !unicharset.get_islower (next_char, next_char_length)) || (*next_char == 's' && *next_next_char == 't'))) { if (((*prev_char != '\'' && *prev_char != '`') || *next_char != '\0') && ((*next_char != '\'' && *next_char != '`') || *prev_char != '\0')) { first_char = "1"; first_char_length = 1; } } } if (*first_char == 'l' && *next_char != '\0' && (prev_char_length == 0 || !unicharset.get_isalpha (prev_char, prev_char_length))) { type1 = 2; if (*second_char == '1') type2 = 0; else if (*second_char == 'I') type2 = 1; else if (*second_char == 'l') type2 = 2; else type2 = type1; if (*third_char == '1') type3 = 0; else if (*third_char == 'I') type3 = 1; else if (*third_char == 'l') type3 = 2; else type3 = type1;#if 0 if (bigram_counts[*next_char][type2] > bigram_counts[*next_char][type1]) { first_char = second_char; type1 = type2; } if (bigram_counts[*next_char][type3] > bigram_counts[*next_char][type1]) { first_char = third_char; }#endif } } return first_char;}/********************************************************************** * permute_words * * Permute all the characters together using the dawg to prune all * but the valid words. **********************************************************************/A_CHOICE *permute_words(CHOICES_LIST char_choices, float rating_limit) { A_CHOICE *best_choice; best_choice = new_choice (NULL, NULL, rating_limit, -MAX_FLOAT32, -1, NO_PERM); if (hyphen_base_size() + array_count (char_choices) > MAX_WERD_LENGTH) { class_probability (best_choice) = MAX_FLOAT32; } else { dawg_permute_and_select ("system words:", word_dawg, SYSTEM_DAWG_PERM, char_choices, best_choice, TRUE); dawg_permute_and_select ("document_words", document_words, DOC_DAWG_PERM, char_choices, best_choice, FALSE); dawg_permute_and_select ("user words", user_words, USER_DAWG_PERM, char_choices, best_choice, FALSE); } return (best_choice);}/********************************************************************** * valid_word * * Check all the DAWGs to see if this word is in any of them. **********************************************************************/int valid_word(const char *string) { int result = NO_PERM; if (word_in_dawg (word_dawg, string)) result = SYSTEM_DAWG_PERM; else { if (word_in_dawg (document_words, string)) result = DOC_DAWG_PERM; else if (word_in_dawg (user_words, string)) result = USER_DAWG_PERM; } return (result);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?