这是一个非常具有挑战性的问题,因为我不确定如何正确提问。
我编写了一个程序,每次加载时都会读取相同的文本数据。文本数据是字典中的单词列表,程序解决字谜类型的谜题(如 Jumble、Boggle、Scrabble 等)。此文本数据永远不会改变。目前我用来读取一个文本文件,该文件必须与所构建的 .exe 位于同一文件夹中。这假设用户不会只是进入并擦除、编辑或以其他方式破坏文本文件或用户真正可能做的事情。不仅如此,锁定文件并读取它是非常缓慢的操作。
该程序所做的大部分工作是将 .txt 文件转换为抽象数据类型 (ADT),它将单词分类为“签名”,然后构建一组具有相同签名的单词。这些集合存储在一个结构(此处称为 map)中,该结构是一个键:值类型的数据结构,其中键是签名。无论如何,该信息与问题无关,足以说明在加载时我需要在内存中构建我的 ADT。我正在寻找比文本文件更复杂的方法。
由于我是编程新手,因此可能有更好的方法。我只是不知道如何问这个问题,因为我不知道那里有什么可用的。
我了解数据库,但话又说回来,这似乎依赖于外部文件。我看过一些关于将数据存储在 .h 文件中的帖子,但他们总是想构建一个字符数组 (char[i]),这需要将这些数据转换为我的 ADT,而当程序正在加载。(为什么要将它转换为 char 数组只是为了将其读回 ADT?)
/*
* Project: myJumble
* Created by CS106 C++ Assignment Wizard 0.1
*
* Name: Brad Beall
* Section: Life
* This code will solve the jumble puzzles in the newspaper.
*/
#include <fstream>
#include <iostream>
#include "simpio.h"
#include "map.h"
#include "set.h"
#include "genlib.h"
//This function swaps two characters.
void Swap(char &ch1, char &ch2)
{
char tmp = ch1;
ch1 = ch2;
ch2 = tmp;
}
//This function sorts all the chars in a word in alphabetical order
string SortWord(string inWord)
{
inWord = ConvertToLowerCase(inWord);
//these two for loops will sort the string alphabetically
// - idea is starting from the front, find the 'smallest' character in the string.
// (where a is 'smaller' than b)
// then move that smallest character to the front of the string
// now move to the next character and again look for the smallest character.
// Example: for "peach", first move the 'a' to the front to form "apech", then move 'c' to form "acpeh"...
for (int i = 0; i < inWord.length(); i++) {
int minIndex = i;
for (int j = i+1; j < inWord.length(); j++)
{
if (inWord[j] < inWord[minIndex])
{
// looking for the 'smallest' character
minIndex = j;
}
}
Swap(inWord[i], inWord[minIndex]);
}
return inWord;
}
void BuildDictionary(Map<Set<string> > &kDict, ifstream &in)
{
string nextWord = "";
while(true)
{
//read in the next word from the dictionary
in >> nextWord;
if (in.fail()) break;
//sort letters alphabetically using SortWord, use that as the key
// and then add that key:value pair to the set.
kDict[SortWord(nextWord)].add(nextWord);
}
}
//this function prints a set
void PrintSet(Set<string> &inputSet)
{
Set<string>::Iterator it = inputSet.iterator();
while (it.hasNext())
{
cout << it.next() << endl;
}
}
int main ()
{
////debug the function: string SortWord(string inWord)
//cout << "Enter a word to sort" << endl;
//string tempString = GetLine();
//tempString = SortWord(tempString);
//cout << tempString;
//building the dictionary may take some time.
cout << "Loading the dictionary. This may take some time." << endl;
//read in the text file with all dictionary words
ifstream in;
in.open("enable1.txt");
//call the member function that will create our data structure
//this will be a MAP:
// - key: the alphabetized letters from a word, or the word's "signature"
// - value: a Vector of words with the matching signature
Map<Set<string> > keyedDictionary;
BuildDictionary(keyedDictionary, in);
while(true)
{
//prompt user for a word to solve
cout << "Enter a jumbled word to solve." << endl;
cout << "Type '0' to exit." << endl << endl;
string solveWord = GetLine();
if(solveWord == "0"){
break;
}
//sort the word into a signature key
solveWord = SortWord(solveWord);
//call the PrintSet(Set) member function to print the set of solutions for this signature key
PrintSet(keyedDictionary[solveWord]);
}
return 0;
}