Introdução ao conceito de indicador de passagem

Nesta seção será apresentado o conceito de indicador de passagem, bastante útil em algoritmos que precisem detectar a ocorrência de um evento, não importando quantos vezes ele ocorre. Um exemplo simples e direto seria detectar a ocorrência de (ao menos) um valor negativo em uma sequência. Outro exemplo indireto seria descobrir se um número natural é primo (indireto pois precisaremos dividir por naturais menores que o valor dado e, ao detectar um divisor, a resposta é negativa).

1. Ideias que se repetem

Em matemática é comum a existência de ideias que são usadas para resolver variados problemas, como a soma telescópica, na qual rearranjamos os termos de modo a ocorrer uma sequência de eliminações. Por exemplo, para obter o somatório de 1/(i*(i+1)), para i variando de 1 até n:

somai=1n 1/(i (i+1)) = somai=1n (1/i - 1/(i+1)) = somai=1n = (1-1/2) + (1/2 - 1/3) + ... + (1/n - 1/(n+1)) = 1 - 1/(n+1).

Em desenvolvimento de software (programas computacionais) esse princípio do "reaproveitamento" de ideias é ainda mais importante, pois muitas vezes reaproveitamos uma "ideia pronta", já implementada em um procedimento ou uma função (método). Um exemplo que provavelmente você já utilizou é a ideia de contador: sempre que executar determinada instrução, acrescentar 1 ao contador (e.g. em algoritmo para imprimir os n primeiros naturais).

2. Ideia de indicador de passagem

A ideia de indicador de passagem é utilizar uma variável que será usada para registrar se determinado evento ocorreu. Para implementar essa ideia, temos três momentos:

  1. Essa variável inicialmente recebe uma marca, por exemplo, valor 0.
  2. Dentro do laço, em cada passo, verifica-se a ocorrência do evento, se ele ocorrer então sinalize a ocorrência do evento (por exemplo, atribuindo o valor 1).
  3. Ao final do laço, basta examinar o conteúdo da variável sinalizadora (se ela estiver com valor 1, o evento ocorreu, caso contrário, não ocorreu).

Por exemplo, alguém está interessado em controlar seu extrato bancário e para isso deseja um programa que recebe os valores digitados e verifica se algum deles é negativo. Nesse caso pode-se empregar a ideia de indicador de passagem, o que é ilustrado no código seguinte (usando a linguagem Portugol):

 // O indicador de passagem recebera o nome sugestivo 'existeNegativo'
 existeNegativo = 0; // 0 => "ate' aqui" nenhum negativo - ou, "em principio, nao existem negativos"
 repita N vezes
   leia(x);
   se (x < 0)
   entao existeNegativo = 1; // existe negativo! ("nunca mais" elimine o 1 dessa variavel indicadora)
 // terminado o laco a resposta e' dada olhando se ocorreu o evento (ao menos uma vez)
 se (existeNegativo == 1)
 entao imprima("Existe(m) negativo(s)");
 senao imprima("NAO existe sequer um valor negativo na sequencia digitada!");
Cód. 1. Exemplo de indicador de passagem para verificar ocorrência de algum valor negativo.

Portanto, sempre que perceber que deve ser identificado a ocorrência de um evento, pode-se utilizar o modelo acima.

3. Cuidado com um erro comum ao tentar usar indicadores

Um erro bastante comum para os iniciantes na arte de programar é, a cada passo, alterar o valor da variável indicadora. Por exemplo, poder-se-ia "estragar" o código acima se for acrescentado um comando senao dentro do laço, do seguinte modo

 // Contra-exemplo NAO implemente desse modo!
 existeNegativo = 0; // 0 => "ate' aqui" nenhum negativo - ou, "em principio, nao existem negativos"
 repita N vezes
   leia(x);
   se (x < 0)
   entao existeNegativo = 1; // existe negativo! ("nunca mais" elimine o 1 dessa variavel indicadora)
   senao existeNegativo = 0; // NAO use uma linha dessa (ela "desfaz" o indicador)!!!!
 // terminado o laco a resposta SERIA dada olhando se ocorreu o evento
 se (existeNegativo == 1)
 entao imprima("Existe(m) negativo(s)");
 senao imprima("NAO existe sequer um valor negativo na sequencia digitada!");
Cód. 2. Contra-exemplo: errando na implementação de indicador de passagem para verificar ocorrência de algum valor negativo.

Para você ter certeza de ter entendido o conceito é bom simular o código acima, por exemplo, usando os seguintes dados como entrada: N=4 e a sequência de 4 dados como sendo 2, -1, -3, 4. Será usado i para indicar o número de dados digitados (auxiliar, faria parte do código se for usado um comando for do C ou Python).

 i |  x | existeNegativo
 1 |  2 |              0
 2 | -1 |              1
 3 | -3 |              1
 4 |  2 |              0

Note que ao final da simulação, existeNegativo está com o valor 0, que indicaria a não existência de negativos na sequência, mas existem 2 negativos! Logo, solução errada!

Na verdade, na implementação errônea acima, a resposta será definida exclusivamente pela última iteração do laço. Por que?
A razão é que, a cada passo a variável existeNegativo receberá um valor (esse é o erro), pois se a condição for verdadeira executa-se a atribuição existeNegativo = 1 e se for falsa executa-se a atribuição existeNegativo = 0.
Portanto, não importa quais sejam os N-1 primeiros valores digitados, o único usado para definir o valor final de existeNegativo seria o último! Erro!

4. Códigos em C e em Python para o exemplo acima de indicador de passagem

Abaixo está indicado em C e em Python o código para digitar N valores (inteiros) e imprimir se algum negativo foi ou não registrado (digitado).

C            Python
  int n, i;
  scanf("%d", &n);                     n = int(input());
  existeNegativo = 0;                  existeNegativo = 0;
  for (i=0; i< n; i++)                  for i in range(n) :
    if (x < 0 )                           if (x < 0 ) :
      existeNegativo = 1;                   existeNegativo = 1;
  if (existeNegativo == 1)              if (existeNegativo == 1) :
    printf("Existe(m) negativo(s)\n");    print("Existe(m) negativo(s)");
  else printf("NAO existe!\n");         else : print("NAO existe!");

5. Outros exemplos de uso do conceito de indicador de passagem

Existe uma quantidade arbitrária de exemplos em que o conceito de indicador de passagem é útil. Abaixo listo apenas alguns exemplos simples:

Alterações :
2022/04/02: cores
2021/06/21: 2 correções léxicas (rearranjamos, raiz)
2021/06/07: 4 correções léxicas
2021/06/06: revisão geral (com pequenos acertos e novas frases), numeração de seções/subseções
2020/08/15: novo formato, pequenas revisões
2020/08/12: novo formato, pequenas revisões
2019/05/08: primeira versão