巧妙地减少if-elseif语句的方法

时间:2018-01-15 23:56:37

标签: c++ string if-statement control-flow

我开发了一个代码来将SpinBox限制为字母而不是整数。一切都运行正常,但如果有任何聪明的方法,我想减少if-elseif语句。这是代码

const list1 = [ 
  { tail: 'A', head: 'B', distance: '5' },
  { tail: 'B', head: 'C', distance: '4' },
  { tail: 'C', head: 'D', distance: '8' },
  { tail: 'D', head: 'C', distance: '8' },
  { tail: 'D', head: 'E', distance: '6' },
  { tail: 'A', head: 'D', distance: '5' },
  { tail: 'C', head: 'E', distance: '2' },
  { tail: 'E', head: 'B', distance: '3' },
  { tail: 'A', head: 'E', distance: '7' } 
]

const list2 = [ { tail: 'A', head: 'B' }, { tail: 'B', head: 'C' } ]

// result should be [{ tail: 'A', head: 'B', distance: '5' },
// { tail: 'B', head: 'C', distance: '4' }] from list1

6 个答案:

答案 0 :(得分:7)

怎么样:

 if (text.size()>0 && std::isalpha(text[0]))
     return std::toupper(text[0])-'A'; 
 else return -1;    // or throw an exception 

这是online demo

工作原理:首先检查字符串是否为空,第一个字符是否为(with isalpha())。如果它有效,因为你在小写和大写之间没有区别,我们转换char toupper()。由于您的返回值按字母顺序排列,我们只需要减去第一个字母。

答案 1 :(得分:4)

根据ASCII表,每个字母都有一个整数值。如果你仔细观察,你会发现这些字母很方便地放在表格中:a到z都是直接相互跟随的,A到Z也是如此。

您可以先确定小写或大写,然后返回text[0] - 'a'text[0] - 'b'

答案 2 :(得分:2)

您可以使用字符串的find成员函数并稍微更改函数签名来消除df <- data.frame(B=c(1,0,0), C=c(3,4,9), D=c(1,1,0)) #A function to calculate stations whether there is a communication or process component or both df <- df %>% mutate(combined.score = ifelse("B" %in% names(.) & "C" %in% names(.) & "D" %in% names(.), B + C + D, ifelse("B" %in% names(.) & "C" %in% names(.), B + C, B))) %>% mutate(combined.score.correct = B + C + D) 函数中的多个if语句:

valueFromText

答案 3 :(得分:1)

使用静态成员(std::map - look up table)&amp;编写一个小类或结构。一些充当包装器的静态方法肯定适用于您的情况。代码的使用相当干净,易读,易于使用,应该是可移植的并且可以重复使用。

注意: - 如果按顺序定义系统的字符代码,这将起作用;否则,您需要一些其他机制来initialize静态地图。

<强> AlphaSpinBox.h

#ifndef ALPHA_SPIN_BOX_H
#define ALPHA_SPIN_BOX_H

#include <string>
#include <cctype>
#include <map>

struct AlphaSpinBox {    
    // static table
    static std::map<unsigned, std::string> table_;    
    // Must be called first
    static void initializeMap();    
    // helper function
    static std::string toUpper( const std::string& str );    
    // get string from value
    static std::string textFromValue( const unsigned& val );        
    // get value from string
    static unsigned valueFromText( const std::string& text );

    // other member's, functions etc. that you may have for this class
};

#endif // !ALPHA_SPIN_BOX_H

<强> AlphaSpinBox.cpp

#include "AlphaSpinBox.h"

// define static member
std::map<unsigned, std::string> AlphaSpinBox::table_;

void AlphaSpinBox::initializeMap() {
    // Could do some checks here to see if this function has not been called
    // then display a message to the user that this function needs to be called first;
    // and to check if it has already been called once before; warning the user
    // that this method should only initialize the map once per application run.
    static char c = 'A';
    static std::string str;
    for ( unsigned n = 0; n < 26; n++ ) {
        str.assign( &c );
        table_.insert( std::make_pair( n, str ) );
        c++;
    }
}

std::string AlphaSpinBox::toUpper( const std::string& str ) {
    std::string result = str;
    std::transform( str.begin(), str.end(), result.begin(), ::toupper );
    return result;
}

std::string AlphaSpinBox::textFromValue( const unsigned& val ) {
    // you could check to see if val is within range before returning...
    return table_[val];
}

unsigned AlphaSpinBox::valueFromText( const std::string& text ) {
    std::string upper = toUpper( text );
    for ( auto pair : table_ ) {
        if ( upper == pair.second ) {
            return pair.first;
        }
    }
    return -1;
}

<强>的main.cpp

#include <string>
#include <iostream>
#include "AlphaSpinBox.h"

int main() {

    // Must Be Called First
    AlphaSpinBox::initializeMap();

    // Remember that the map first entry's key starts at 0 and not 1
    std::cout << "The number 8 has letter: " 
              << AlphaSpinBox::textFromValue( 8 ) 
              << std::endl;

    std::cout << "The letter Q has value: " 
              << AlphaSpinBox::valueFromText( std::string( "Q" ) ) 
              << std::endl;

    // check case for lower cases being converted to upper case
    std::cout << "The letter j has value: " 
              << AlphaSpinBox::valueFromText( std::string( "j" ) ) 
              << std::endl;

    std::cout << "\nPress any key and enter to quit." << std::endl;
    char q;
    std::cin >> q;
    return 0;
}

答案 4 :(得分:1)

下面,也许,更容易理解的一个:

int AlphaToNumeric(string &value)
{
    return (value.front() >= 'A' && value.front() <= 'Z') ? value.front() - 'A' : (value.front() >= 'a' && value.front() <= 'z') ? value.front() - 'a' : -1;
}

或者:

int AlphaToNumeric(string &value)
{
    return (value.front() >= 65 && value.front() <= 90) ? value.front() - 65 : (value.front() >= 97 && value.front() <= 122) ? value.front() - 97 : -1;
}

答案 5 :(得分:1)

不确定此限定符是否“聪明”,但假设您只想查看text的第一个字符,则可以直接执行

#include <string>
#include <cctype>

int AlphaSpinBox::valueFromText(const std::string &text) 
{
     std::string str("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
     int retval = -2;
     if (text.size() > 0)
     {
         char c = std::toupper(text[0]);
         std::size_t index = str.find(c);
         retval = (index != std::string::npos) ? int(index) : -1;
     }
     return retval;
}

与原始问题中的代码不同,这将编译(因为它尝试转换字符串中的第一个字符,而不是整个字符串)。但是,它也会执行更多检查,因此如果给定长度为零的字符串,则返回-2,如果字符串中的第一个字符不是字母,则返回-1

如果你假设一个字符集,其中(大写)字母顺序出现,这可以更简单。对于所有标准化字符集,这种假设并不严格,但对于现代系统来说,这种假设往往是正确的。

#include <string>
#include <cctype>

int AlphaSpinBox::valueFromText(const std::string &text) 
{
     int retval = -2;
     if (text.size() > 0)
     {
         int c = std::toupper(text[0]);
         retval = std::isupper(c) ? c - 'A' : -1;
     }
     return retval;
}

使用其中一个版本或另一个版本的选择取决于代码永远不会移植到具有字符集的系统的置信度,其中字符集是非连续的。