Manipulação de strings do tipo String de substituição na expressão matemática

1

Imagine algo como

exp(49/200)+(x-49/200)

Eu quero passar como argumento da função "roundn" qualquer operação que não seja uma adição ou uma subtração Então minha expressão se tornou

roundn(exp(roundn(49/200,n)),n)+(x - roundn(49/200,n)

Bem, a expressão que quero manipular é esta:

exp(49/200)+exp(49/200)*(x-49/200)+1/2*exp(49/200)*(x-49/200)^2+1/6*exp(49/200)*(x-       49/200)^3+1/24*exp(49/200)*(x-49/200)^4+1/120*exp(49/200)*(x-49/200)^5+1/720*exp(49/200)*(x-49/200)^6+1/5040*exp(49/200)*(x-49/200)^7+1/40320*exp(49/200)*(x-49/200)^8+1/362880*exp(49/200)*(x-49/200)^9+1/3628800*exp(49/200)*(x-49/200)^10+1/39916800*exp(49/200)*(x-49/200)^11

Eu estou procurando um método (que inclua qualquer programa) que não seja baseado em programação de linguagem, tanto em lote ou somithing assim ...

    
por Peterstone 22.11.2010 / 20:48

2 respostas

2

Tente isto:

ro='roundn('    # roundn open
rc=',n)'        # roundn close
fun='exp\('
expression='exp(49/200)+(x-49/200)'
echo "$expression" |
perl -pe "s/$fun[^)]*\K\)/)$rc/g; s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g; s/$fun[^)]*/$ro\$&/g"

que deve dar a você:

roundn(exp(roundn(49/200,n)),n)+(x-roundn(49/200,n))

Sua expressão mais longa deve resultar em:

roundn(exp(roundn(49/200,n)),n)+roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))+roundn(1/2,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^2+roundn(1/6,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^3+roundn(1/24,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^4+roundn(1/120,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^5+roundn(1/720,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^6+roundn(1/5040,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^7+roundn(1/40320,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^8+roundn(1/362880,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^9+roundn(1/3628800,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^10+roundn(1/39916800,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n) ^11

Explicação

  • /exp\([^)]*\K\)/)$rc/g - fechar exp (), adicionar roundn close
    • para strings que começam com "exp (" e terminam com ")"
    • \K faz a "exp (" uma correspondência de largura zero, então somente o paren de fechamento é substituído
  • s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g - strings de dígitos com mult e div, surround com roundn open e roundn close
    • strings de dígitos que não começam com "^", mas podem conter "/" ou "*"
    • deve ter dois ou mais caracteres no total - provavelmente há uma maneira melhor de fazer isso
    • carat tem look-behind negativo (largura zero), por isso não é incluído quando a substituição é feita
  • s/exp\([^)]*/$ro\$&/g - abrir exp (), adicionar roundn open
    • antes de "exp (" seguido de zero ou mais caracteres que não são ")", adicione roundn open
  • $ro , $rc e $fun são variáveis do shell
    • colocar o script Perl entre aspas duplas permite que essas variáveis sejam expandidas
  • $& contém toda a correspondência, exceto as porções de largura zero
    • escapar provavelmente não é necessário, mas eu fiz isso apenas no caso - para evitar confundir o shell

Não seria muito difícil fazer isso funcionar se houver mais de uma função. No entanto, ele provavelmente irá desmoronar completamente se eles estiverem aninhados.

Editar:

Aqui está uma versão do script Perl:

$ro = "roundn(";
$rc = ",n)";
$fun = "exp\(";
while (<>) {
    s/$fun[^)]*\K\)/)$rc/g;
    s/(?<!\^)[0-9\/*]+[0-9]/$ro$&$rc/g;
    s/$fun[^)]*/$ro$&/g;
    print
}

Execute assim:

perl script.pl < data.txt
    
por 23.11.2010 / 07:13
0

Bem, estou tentando executar seu código ... Eu faço um pequeno programa (practicalcase1.pl) com o primeiro parágrafo do código que você escreveu:

ro='roundn('    # roundn open
rc=',n)'        # roundn close
fun='exp\('
expression='exp(49/200)+(x-49/200)'
echo "$expression" |
perl -pe "s/$fun[^)]*\K\)/)$rc/g; s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g; s/$fun[^)]*/$ro\$&/g"

Mas eu recebo algumas mensagens no cmd das janelas:

Semicolon seems to be missing at practicalcase1.pl line 1
Semicolon seems to be missing at practicalcase1.pl line 2
Semicolon seems to be missing at practicalcase1.pl line 3
Semicolon seems to be missing at practicalcase1.pl line 4
String found where operator expected at practicalcase1.pl line 5, near "echo "$expression""
(Do you need to predeclare echo?)
String found where operator expected at practicalcase1.pl line 6, near "pe "s/$fun[^)]*\K\)/)$rc/g; s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g""
(Do you need to predeclare pe?)
Can´t modify constant item in scalar assigment at practicalcase1.pl line 2, near "rc"
syntax error at practicalcase1.pl line 2, near "rc"
Execution of practicalcase1.pl aborted due to compilation errors.

O que eu poderia fazer com os erros do tipo "ponto-e-vírgula parece ..."? O que é preciso eu tenho a ver com o erro "String encontrado onde o operador ..."? E quanto a "Não é possível modificar o item constante no escalar ..."? Que tal "erro de sintaxe em practicalcase1.pl line2 ..."

Muito obrigado!

    
por 23.11.2010 / 18:14