如何以循环方式下移字母字符?

时间:2019-08-26 00:26:00

标签: c

我想找到比我早7个字符的字母字符,所以我写了这个函数,所以效果很好:

char find7_before(char letter){
    switch (letter){
        case 'g':
          return 'z';
          break;
        case 'f':
          return 'y';
          break;
        case 'e':
          return 'x';
          break;
        case 'd':
          return 'w';
          break;
        case 'c':
          return 'v';
          break;
        case 'b':
          return 'u';
          break;
        case 'a':
          return 't';
          break;
        default:
        return (char)(((int)letter) - 7);
    }
}

但是我想我可以在没有所有这些情况的情况下以更聪明的方式做到这一点,但我只是想不通! (我想出了如何以循环方式找到7个字母)任何帮助,想法或提示? 谢谢:)

3 个答案:

答案 0 :(得分:1)

减去'a'(现在是0-25),再减去7,再加上mod26。然后再次添加'a',这样就回到了char。

答案 1 :(得分:1)

假设ASCII具有连续的['a' , 'z'] ...

只需“ mod 26”。

letter = ((letter - 'a' - 7) mod 26) + 'a';

但是C没有 Euclidean mod 运算符。
参见What's the difference between “mod” and “remainder”?

因此,创建一个 Euclidean mod 函数-保存以供以后使用。

int modulo_Euclidean(int a, int b) {
  int m = a % b;
  if (m < 0) {
    // m += (b < 0) ? -b : b; // avoid this form: it is UB when b == INT_MIN
    m = (b < 0) ? m - b : m + b;
  }
  return m;
}



letter = modulo_Euclidean(letter - 'a' - 7, 26) + 'a';

或者,代码可以利用'a'的值为97,而不会减去太多,以致letter - ('a'%26) - 7变为负数。

letter = (letter - ('a'%26) - 7)%26 + 'a';

pedantic代码不会假设连续的['a' , 'z'] 并且执行更复杂的代码。

答案 2 :(得分:1)

我认为,最清晰,最简单的方法是使用if语句:

char find7_before(char letter) {
    char value = letter - 7;
    if (value < 'a') {
        value += 26;
    }
    return value;
}

这里的先决条件是字母介于'a''z'之间(包括首字母)。

该技术也可以概括为:

char findn_before(char letter, int n) {
    char value = letter - n;
    if (value < 'a') {
        value += 26;
    }
    return value;
}

letter上的前提条件与之前相同; n必须在0到26之间(包括0和26)。