Pergunta

Se eu tiver a .....ZZ..ZZ..... corda ou .Z.1.Z.23Z.4.Z55,

Existe uma maneira fácil de transferir todos os Zcharacters na seqüência de um certo espaço da posição atual?

Algumas cadeias de teste adicionais são:

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

Eu acho que algumas das maiores votou respostas a esta pergunta (incluindo o aceito atualmente) não funcionam nesses testes.

Foi útil?

Solução

Apenas percorrer os caracteres de texto e de swap:

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;
}

Produz:

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

Há muita discussão nos comentários sobre um possível erro de off-by-1 no código acima. No entanto, testes simples / percorrendo é o suficiente para mostrar que este não é o caso.

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

Eu acho que o comportamento de "deixar cair" arrastando Zs ao deslocar para fora da extremidade da corda é sensato. Afinal, se você mudar os bits de um inteiro, pedaços que acabam fora dos limites do inteiro são descartados.

Se um outro comportamento é desejado - por exemplo, mudando apenas dentro da string - a mudança para o algoritmo é mínima:

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

Outras dicas

Com base postado anteriormente código aqui. Função obtém str e strlen, substitui str. Funciona também com Z. posterior Indo para a frente para a melhoria velocidade com Z posterior.

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
        }
    }
}

Note que a solução da John Millikin é mais agradável de ler e também correta.

Leve correção para a resposta anterior (mudança para a direita e assumir meios 'pode mudar para cá' ''):

  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';
    }
  }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top