【问题标题】:How can I compact this code? Too many if statements如何压缩此代码? if 语句过多
【发布时间】:2021-09-15 23:00:19
【问题描述】:

有什么方法可以压缩我的这段代码吗?这是基于 ASCII 值的,我正在尝试为它创建一个表。我可以创建一个可能更简单的地图,但我不知道我的教授是否出于某种原因允许这样做。

如果我确实做了一张地图,我只会创建一个包含所有标准 ascii 值的地图,而不是拥有所有这些语句。但是为了这种方法,我考虑过实现 && 和!和 ||但不知道从哪里开始。

void mark_cells(int row, int _table[][MAX_COLUMNS], const char columns[], int state) {
    if (columns == ALFA) {
        // A-Z
        for (int i = 65; i <= 90; ++i) {
            _table[row][i] = state;
        }
        // a-z
        for (int i = 97; i <= 122; ++i) {
            _table[row][i] = state;
        }
    }
    else if (columns == DIGITS) {
        // 0 - 9
        for (int i = 48; i <= 57; ++i) {
            _table[row][i] = state;
        }
    }
    else if (columns == OPERATORS) {
        // <, =, >
        for (int i = 60; i <= 62; ++i) {
            _table[row][i] = state;
        }
        // (,),*,+
        for (int i = 40; i <= 43; ++i) {
            _table[row][i] = state;
        }
        // {,|,}
        for (int i = 123; i <= 125; ++i) {
            _table[row][i] = state;
        }
        // !
        _table[row][33] = state;
        // %
        _table[row][37] = state;
        // &
        _table[row][38] = state;
        // -
        _table[row][45] = state;
    }
    else if (columns == SPACES) {
        _table[row][32] = state;
    }
    else if (columns == PUNC) {
        // ;
        _table[row][58] = state;
        // :
        _table[row][59] = state;
        // ?
        _table[row][63] = state;
        // '
        _table[row][39] = state;
        // .
        _table[row][46] = state;
        // ~
        _table[row][126] = state;
        // !
        _table[row][33] = state;
        // `
        _table[row][96] = state;
        // ,
        _table[row][44] = state;
        // -
        _table[row][45] = state;
    }
    
}

此代码标记行和列并将其设置为给定状态:
这是我的常量

#ifndef CONSTANTS_H
#define CONSTANTS_H

const int MAX_COLUMNS = 256;
const int MAX_ROWS = 100;
const int MAX_BUFFER = 200;

const char ALFA[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char DIGITS[] = "0123456789";
const char OPERATORS[] = "><=!+-%&|()*";
const char SPACES[] = {' ', '\t', '\n', '\0'};
const char PUNC[] = "?.,:;'`~!";

【问题讨论】:

  • 不是一个好的switch 候选人,但std::(unordered_)map&lt;std::string, std::function&lt;(prototype)&gt; 可能是一个不错的选择。取决于用例。注意比较 char 数组和 == 是行不通的,除非你故意比较指针。如果要比较字符串值,则需要strcmp 或迁移到std::string
  • 我看不到重叠,所以我认为您已经建议的地图将是重写它的最佳方式。
  • 正如@user4581301 指出的那样,让“列”成为 char[] 是有问题的。如果您可以将其设为enum,您的地图解决方案会更好。
  • 旁注:for (int i = 65; i &lt;= 90; ++i) 使用for (int i = 'A'; i &lt;= 'Z'; ++i) 可能更容易阅读
  • 我不清楚这个函数在做什么。我认为可能正确的做法是重新设计调用此函数的代码。

标签: c++ data-structures


【解决方案1】:

首先,我不知道这应该如何工作:

if (columns == ALFA)

如果columnschar[] 类型。那是指针比较还是字符串比较?如果是后者,它不会做你认为它会做的事情(可靠地)。

如果是字符串比较,请将column 更改为const std::string&amp; 类型。那么这些与定义的文字的比较会更好。

对于初学者,有一个辅助函数来执行不断重复的循环。

void setStateOnRange(int table[][MAX_COLUMNS], int row, int start, int end, int state) {
        for (int i = start; i <= end; ++i) {
            table[row][i] = state;
        }
}

那么你的函数写起来就容易多了:

void mark_cells(int row, int _table[][MAX_COLUMNS], const string& columns, int state) {
    if (columns == ALFA) {
        // A-Z
        setStateOnRange(_table, row, 'A','Z');
        setStateOnRange(_table, row, a','z');
    }
    else if (columns == DIGITS) {
        // 0 - 9
        setStateOnRange(_table, row, '0','9');
    }
    ...

另一个想法是创建一个静态表,将每个 ascii 值映射到您期望的列范围。我会让你相应地初始化表格。实现变得非常短。

void mark_cells(int row, int _table[][MAX_COLUMNS], const string& columns, int state) {

    static string columnmap[128] = {
           /* 0..31*/ NONE, NONE, NONE, ... <32 NONES in a row>,
           /* 32-47*/ SPACE, PUNC, PUNC, PUNC....
           /*48-57*/  DIGIT, DIGIT, DIGIT.... 
                      PUNC, PUNC, PUNC...
           /*65-90*/  ALFA, ALFA, etc....
           ...};

     for (int i = 0; i < 128; i++) {
         if (columnmap[i] == columns) {
             table[row][i] = state;
         }
     }
 }

【讨论】:

    【解决方案2】:

    我会先将每组字符变成一个字符串。例如:

    const char* allAlpha = "QWERTYUIOPASDFGHJKLZXCVBNM"
                           "qwertyuiopasdfghjklzxcvbnm";
    const char* allDigits = "1234567890";
    const char* allOperators = "<=>,*+!%&-";
    ...
    

    其他人也是如此。然后你的逻辑会选择一个:

    const char* selected = nullptr;
    if (columns == ALFA)
        selected = allAlpha;
    else if (columns == DIGITS)
        selected = allDigits;
    else if (columns == OPERATORS)
        selected = allOperators;
    ...
    

    最后,如果你选择了一些东西,你可以通过它来标记所有这些状态:

    if (selected)
    {
        for (const char* p = selected; *p != '\0'; ++p)
            _table[row][(unsigned char)*p] = state;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-04-26
      • 2022-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 2019-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多