Maison > développement back-end > C++ > Comment puis-je implémenter efficacement une instruction Switch avec des arguments non entiers en C/C ?

Comment puis-je implémenter efficacement une instruction Switch avec des arguments non entiers en C/C ?

DDD
Libérer: 2024-11-28 07:25:14
original
1009 Les gens l'ont consulté

How Can I Efficiently Implement a Switch Statement with Non-Integer Arguments in C/C  ?

Arguments non entiers dans les instructions Switch C/C

L'instruction switch dans C/C est un puissant mécanisme de flux de contrôle qui permet un branchement efficace basé sur des valeurs entières . Cependant, il est souvent souhaitable d'activer des valeurs non entières, telles que des chaînes ou des énumérations. Cela présente un défi car les instructions switch n'acceptent que les arguments entiers.

Approches traditionnelles

Une approche traditionnelle pour gérer les arguments switch non entiers consiste à utiliser une séquence d'instructions if :

if( str == "foo" )      ...
else if( str == "bar" ) ...
else                    ...
Copier après la connexion

Cependant, cette approche est inefficace car elle nécessite une complexité temporelle linéaire (O(n)) pour n cas. Une solution plus efficace consiste à représenter les valeurs non entières sous forme d'entiers, soit à l'aide de cartes, soit de ifs imbriqués. Cependant, ces approches peuvent être complexes et sujettes aux erreurs.

Recherche binaire avec des macros

À l'aide de macros, il est possible d'implémenter une recherche binaire déroulée au moment de la compilation, permettant une analyse rapide et syntaxique. -approche conviviale :

#define NEWMATCH
#define MATCH("asd")
  some c++ code
#define MATCH("bqr")
  ... the buffer for the match is in _buf
#define MATCH("zzz")
  ...  user.YOURSTUFF 
#define ENDMATCH(xy_match)
Copier après la connexion

Cette macro générera une fonction qui prend une chaîne en entrée et renvoie un booléen, implémentant une recherche binaire à travers le spécifié cas.

C 11 lambdas et listes d'initialiseurs

En C 11, les lambdas et les listes d'initialiseurs offrent une approche plus élégante et concise :

template<typename KeyType, typename FunPtrType>
void switchStatement(const KeyType& value, std::initializer_list<std::pair<const KeyType, FunPtrType>> sws) {
    std::lower_bound(sws.begin(), sws.end(), value, [&](const auto& a, const auto& b) { return a.first < b.first; });
    if (r != sws.end() && !cmp(val, *r)) { r->second(); } // else: not found
}
Copier après la connexion
int main() {
    switchStatement<const char*, void(*())>("ger", {
        { "asdf", []{ printf("0\n"); } },
        { "bde", []{ printf("1\n"); } },
        { "ger", []{ printf("2\n"); } },
    });
    return 0;
}
Copier après la connexion

Temps de compilation Trie

En C moderne, les techniques de métaprogrammation C 11 peuvent être utilisées pour créer un trie au moment de la compilation, une structure de données avancée qui peut gérer efficacement les branches de cas non triées :

#include <smile/cttrie/cttrie.h>

using namespace smile::cttrie;

// Define cases as string literals
trie<true, void()> s = {"foo", "bar"};

int main() {
  // Switch on a string
  s.switch_on("foo", []() { std::cout << "foo" << std::endl; });
  return 0;
}
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal