c++ - 如何避免长 switch 语句? C++

标签 c++ performance switch-statement

我正在为我的类(class)编写一本“词典”。我有一个名为 NumOfWordsInFile[] 的 int 数组,其中 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);
    }

删除函数。

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);
}

最佳答案

快速看一下,您似乎是在使用字母在字母表中的位置来做事。

您可以将所有 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);
}

例如,ActualLetter 类似于“a”。

相关说明,将来如果您确实有大型 switch 语句,请考虑将代码封装在函数中:

switch (letter)
{
    case 'a':
      LetterA();
      break;

    case 'b':
      LetterB();
      break;

    ...
}

或者更好的是,您可以使用多态性让 C++ 根据特定的派生类分派(dispatch)到您想要的方法:

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();
}

请注意,动态调度确实有(轻微的)性能影响,上面是实际使用它的一个非常糟糕的地方。我、RedX 和其他人发布的解决方案更适合您的具体示例。

关于c++ - 如何避免长 switch 语句? C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5533159/

相关文章:

c++ - GCC 7,-Wimplicit-fallthrough 警告,以及清除它们的便携方式?

.net - SCT到期后续订WCF客户端吗?

sql-server - 使用函数和 View 的 SQL Server 查询速度较慢

c++ - 发送 void 类型定义的函数指针作为要调用的参数

c++ - C++ 动态分配内存中的动态内存分配

Javascript - 添加到 String.prototype 的函数在 V8 中性能不佳?

带有字符串变量的 Javascript 开关不起作用

java - 需要常量表达式? (Java 开关语句)

c++ - 完美转发/移动构造不适用于 std::apply 中的元组

c++ - 不同类访问的数据的单一拷贝