Tyl*_*aff 8 c++ performance switch-statement
我正在为我班上的"字典"工作.我有一个调用的int数组NumOfWordsInFile[],NumOfWordsInFile[0]对应于A.txt中有多少个单词,NumOfWordsInFile[25]对应于Z.txt
就像现在一样,我有一个巨大的开关,用于26种不同的字母条件.我有一个叫做的函数AddWord(string word).AddWord获取传递给它的单词的第一个字母,并将其插入相应的.txt文件中.现在这是问题所在.每次在A.txt中添加一个单词时,我必须增加NumOfWordsInFile[0]1.我能想到的唯一方法是使用这些巨大的开关.我还有一个deleteWord函数,NumOfWordsInFile[]如果删除该单词,则相反递减.现在我不想要两个26箱开关,但问题是我不知道怎么做.现在我可以为删除功能做同样的事情,但我真的不希望有更多的代码行来完成.有一个更好的方法吗?
AddWord功能中的开关示例:
case 'w':
if (numOfWordsInFile[22] < maxWordsPerFile) {
fout.open(fileName.data(), ios::app);
fout << word << " " << endl;
numOfWordsInFile[22]++;
if (totalWordsInDict < maxWordsInDict) {
totalWordsInDict++;
}
return(Dictionary::success);
} else {
return(Dictionary::failure);
}
case 'x':
if (numOfWordsInFile[23] < maxWordsPerFile) {
fout.open(fileName.data(),ios::app);
fout << word << " " << endl;
numOfWordsInFile[23]++;
if (totalWordsInDict < maxWordsInDict) {
totalWordsInDict++;
}
return(Dictionary::success);
} else {
return(Dictionary::failure);
}
Run Code Online (Sandbox Code Playgroud)
删除功能.
bool Dictionary::DeleteAWord(string word)
{
ofstream fout;
ifstream fin;
string x;
string fileName="#.txt";
int count=0;
vector <string> words;
bool deleted=false;
fileName[0]=toupper(word[0]);
fin.open(fileName.data()); //makes the file depending on the first letter of the argument "word"
while (fin >> x)
{
words.push_back(x);
count++;//number of elements in vector
}
if (SearchForWord(x))
{
for ( ;count > 0; count--)
{
if (words[count-1] == word)
{
// cout << "Found word " << word << " during search, now deleting" << endl;
words.erase(words.begin()+(count-1));
deleted = true;
/*
This clearly doesn't work and is what I need help with, I know why it
doesn't work but I don't know how to make it better than having another
huge switch.
*/
numOfWordsInFile[toupper(word[0])]--;
/*
*/
totalWordsInDict--;
fin.close();
}
}
if (deleted)
{
fout.open(fileName.data());
for (int i = 0; i < words.size(); i++)
fout << words[i] << endl;
return(Dictionary::success);
}
return(Dictionary::failure);
}
return(Dictionary::failure);
}
Run Code Online (Sandbox Code Playgroud)
只是快速看一下,看起来你正在使用字母表中字母的位置来做事情.
您可以使用以下语句替换所有switch语句:
int letter = (int)(ActualLetter - 'a');
if(numOfWordsInFile[letter]<maxWordsPerFile){
fout.open(fileName.data(),ios::app);
fout<<word<<" "<<endl;
numOfWordsInFile[letter]++;
if(totalWordsInDict<maxWordsInDict){
totalWordsInDict++;
}
return(Dictionary::success);
}else{
return(Dictionary::failure);
}
Run Code Online (Sandbox Code Playgroud)
ActualLetter就像是'a',例如.
在相关的说明中,将来如果您实际上有大型switch语句,请考虑将代码封装在函数中:
switch (letter)
{
case 'a':
LetterA();
break;
case 'b':
LetterB();
break;
...
}
Run Code Online (Sandbox Code Playgroud)
或者甚至更好,您可以使用多态来根据特定的派生类将C++调度到您想要的方法:
class BaseLetter
{
...
public:
virtual void DoStuff() = 0;
};
class LetterA : public BaseLetter
{
public:
void DoStuff();
};
class LetterB : public BaseLetter
{
public:
void DoStuff();
};
void Foo(BaseLetter *letter)
{
// Use dynamic dispatch to figure out what to do
letter->DoStuff();
}
Run Code Online (Sandbox Code Playgroud)
请注意,动态调度确实会产生(轻微)性能损失,而上述实际使用它是一个非常糟糕的地方.解决方案I,RedX和其他人发布的解决方案更适合您的具体示例.
struct FileInfo {
int NumWords;
std::string Filename;
};
std::map<char, FileInfo> TheFiles;
FileInfo & FI = TheFiles[letter];
// Work with FI.NumWords and FI.Filename
Run Code Online (Sandbox Code Playgroud)
或者:
std::vector<FileInfo> TheFiles;
FileInfo & FI = TheFiles[std::tolower(Letter) - 'a'];
Run Code Online (Sandbox Code Playgroud)
字符基本上是数字。“a”是 97,“b”是 98,依此类推。最简单的方法是简单地将 every 替换为numOfWordsInFile[n],并且numOfWordsInFile[current_char - 'a']每种情况重复的整个代码可能驻留在一个函数中,如下所示:
int AddWord(char current_char) {
if(numOfWordsInFile[current_char - 'a']<maxWordsPerFile){
fout.open(fileName.data(),ios::app);
fout<<word<<" "<<endl;
numOfWordsInFile[current_char - 'a']++;
if(totalWordsInDict<maxWordsInDict){
totalWordsInDict++;
}
return(Dictionary::success);
}else{
return(Dictionary::failure);
}
}
Run Code Online (Sandbox Code Playgroud)
对于更通用的解决方案,请阅读哈希映射和函数指针(例如,当您可能想要为每个字符分配不同的函数时)。
| 归档时间: |
|
| 查看次数: |
2080 次 |
| 最近记录: |