在C ++中转换字符串中特定字符的简单方法?

时间:2008-10-21 05:09:11

标签: c++ string character

如果我有字符串.....ZZ..ZZ......Z.1.Z.23Z.4.Z55

是否有一种简单的方法可以将当前位置右侧字符串中的所有Z个字符移位?

一些额外的测试字符串是:

  • .Z
  • Z.
  • ZZ.
  • .ZZ
  • Z
  • ZZ
  • ZZZ

我认为这个问题的一些较高的投票答案(包括目前接受的答案)不适用于这些测试。

3 个答案:

答案 0 :(得分:5)

只需遍历文本并交换字符:

int main ()
{
    char text[] = "...Z.Z.Z...", temp;
    int text_len = strlen (text), i;
    for (i = text_len - 1; i >= 0; i--)
    {
        if (text[i] == 'Z')
        {
                temp = text[i+1];
                text[i+1] = text[i];
                text[i] = temp;
        }
    }
    printf ("%s\n", text);
    return 0;
}

产地:

[~]$ gcc zshift.c && ./a.out
....Z.Z.Z..

上述代码中有关可能出现1个错误的错误的评论中有很多讨论。但是,简单的测试/单步测试足以表明情况并非如此。

zshift "Z." -> ".Z"
zshift ".Z" -> "."
zshift "Z" -> ""

我认为当从字符串末尾移开时“掉落”尾随Zs的行为是明智的。毕竟,如果你移位一个整数的位,那么最终超出整数范围的位就会被删除。

如果需要另一种行为 - 例如,仅在字符串内移位 - 对算法的更改很小:

temp = text[i+1];
if (temp == 0) continue;
text[i+1] = text[i];
text[i] = temp;

答案 1 :(得分:2)

以此处发布的代码为基础。函数获取str和strlen,覆盖str。也适用于随后的Z.继续前进以提高速度,后续Z.

void move_z_right (char* str, int strlen) {
    for (unsigned int i = 0; i < strlen - 1; ++i)
    {
        if (str[i] == 'Z')
        {
            unsigned int j = i+1;
            while (str[j] == 'Z' && j < strlen - 1) ++j;
            if (j == strlen) break; // we are at the end, done
            char tmp = str[j];
            str[j] = str[i];
            str[i] = tmp;
            i = j; // continue after new Z next run
        }
    }
}

请注意,John Millikin的解决方案更易于阅读和更正。

答案 2 :(得分:0)

轻微修复上一个答案(向右移动并假设'。'表示“可以移动到这里”):

  char text[] = "...Z.Z.Z...";

  for (int i = strlen(text) - 2); i > 0; --i) {
    if (text[i] == 'Z' && text[i + 1] == '.') {
      text[i] = '.';
      text[i + 1] = 'Z';
    }
  }