uma máquina de estados recebe entradas que podem ou não transformar seu estado em um conjunto finito de outros estados. Como isso é diferente de qualquer outro programa de computador?
Algumas respostas aqui enfatizam que em nosso universo (provavelmente) finito tudo é finito, todos os programas de computador são executados em tempo finito; portanto, tecnicamente, tudo é uma máquina de estado finito. Isso é "tecnicamente correto (o melhor tipo de correção)", mas também está completamente errado.
A essência é a seguinte: - Alguns programas de computador exigem mais memória de trabalho quando obtêm entradas maiores e mais complexas. Alguns não.
Se você perceber isso, obterá uma visão teórico-informativa que poderá permitir que você escreva programas mais eficientes e elegantes quando encontrar o tipo de problema especificado. Também permitirá que você reconheça o tipo de problema em que isso pode se aplicar.
Aqui estão dois exemplos de brinquedos:
Problema 1: Um programa recebe uma lista de caracteres na entrada padrão. Após o processamento de todos os caracteres, o programa deve imprimir se o número de caracteres "x" na entrada foi ímpar ou par .
Problema 2: Um programa recebe uma lista de caracteres na entrada padrão. Após o processamento de todos os caracteres, o programa deve imprimir se o número de caracteres "x" na entrada foi menor , igual ou maior que o número de caracteres "y".
Você pode parar de ler agora, resolver os problemas em sua linguagem de programação favorita (ou apenas um pseudocódigo) e retornar mais tarde.
...
O importante que você deve ter notado é o seguinte: Para implementar a solução do problema 1 corretamente, você precisa apenas de um pouco de memória. Você não precisa calcular quantos "x" já processou - apenas se o número de "x" processados até agora foi ímpar ou par. Quando você encontrar outro "x", vire o bit. No final do programa, observe a parte e imprima a resposta.
Sua entrada contém uma dúzia de caracteres? Milhares de personagens? Personagens Googolplex (hipoteticamente falando, é claro)? Não importa; um pouco de memória de trabalho ainda será suficiente.
Você não pode fazer a mesma coisa com o problema 2. Ao ler os caracteres, lembre-se da diferença entre o número de "x" 's e "y" já processados; caso contrário, você não poderá imprimir a resposta correta de maneira confiável. Você pode perceber que você realmente não precisa se lembrar de ambos os números de "x" 's e 'y'' s - apenas a sua diferença, até agora; um valor inteiro que você aumentará quando encontrar outro "x" e diminuirá quando encontrar outro "y" - mas ainda assim, se você decidir usar, por exemplo, 32 bits de memória para manter esse valor, poderá receber uma entrada ( bilhões de caracteres) que você não pode processar corretamente com a quantidade limitada de memória.
É isso o que queremos dizer com dizer que o problema 1 pode ser resolvido por uma "máquina de estado" e o problema 2 não. Uma quantidade limitada de memória é suficiente para uma entrada de qualquer tamanho.
(Obviamente, você também pode escrever uma solução ineficiente para o problema 1, onde tentaria contar todos os "x" 's e, em seguida, também obteria um problema de falta de memória. Mas a diferença é que um existe uma solução eficiente para o problema 1 , enquanto uma solução igualmente eficiente para o problema 2 não existe .)
Por que isso é importante na vida real?
Primeiro, diferentemente desses dois exemplos de brinquedos, o dilema pode não estar literalmente entre um bit e um valor inteiro, mas entre uma estrutura de dados grande e outra ainda maior. Às vezes, a estrutura de dados "ainda maior" não se encaixa na memória do computador ou reduz a velocidade do programa, mesmo para entradas realistas.
Segundo, a solução que usa a máquina de estado provavelmente será muito mais rápida. Também será dimensionado linearmente com o comprimento da entrada; isto é, o processamento de entrada 10 vezes mais exigirá 10 vezes mais tempo (em oposição a, por exemplo, 100 vezes mais tempo). Essa é uma propriedade desejada quando você precisa processar muitos dados.
Terceiro, o uso limitado e ilimitado de memória afeta a segurança . Se você escreve um programa que requer apenas memória limitada, não precisa se preocupar com o excesso de memória e como eles podem ser abusados para comprometer a segurança de todo o sistema.
Quarto, isso faz parte do que deveria ser um currículo padrão de ciência da computação em qualquer escola decente: línguas formais , automatos , complexidade computacional etc. Para entender o panorama geral por trás do design do computador, em vez de apenas "uhh, juntei alguns códigos da internet, espero realmente que funcione, mas não sei ao certo".
Para tirar proveito dessa teoria, você realmente não precisa de nenhuma máquina especial, de qualquer estrutura ou biblioteca ... você só precisa entender "oh, essa parte do problema pode realmente ser resolvida usando uma quantidade finita de memória" e escrever seu programa (na sua linguagem de programação favorita) de acordo. Mas, em algumas situações, é melhor usar uma biblioteca existente, para que você não precise reinventar a roda.