Interpretacja wyrażeń zapisanych słownie.

Odpowiedz Nowy wątek
2019-07-17 07:05
0

Hej! Jestem tu nowy i mam mały problem.
Chce napisać funkcje która gdy użytkownik poda jakieś wyrażenie (np. dwieście siedemdziesiąt trzy razy trzy podzielić przez dwa) wyświetli mu działanie jakie powininen wykonać (np. 273*3/2) oraz podać wynik (409.5).

Jak na razie nie moge sobie poradzić z zamianą słów na liczby.

Oto kod który udało mi się wytworzyć, i który działa tylko po części.

$q = $input;
$q = zrob_cyferki($q);
echo $q;
function zrob_cyferki($q) {
  /*Podstawowe*/
  $q = str_replace('jeden','+1',$q);
  $q = str_replace('dwa','+2',$q);
  $q = str_replace('trzy','+3',$q);
  $q = str_replace('cztery','+4',$q);
  $q = str_replace('piec','+5',$q);
  $q = str_replace('szesc','+6',$q);
  $q = str_replace('siedem','+7',$q);
  $q = str_replace('osiem','+8',$q);
  $q = str_replace('dziewiec','+9',$q);
  $q = str_replace('dziesiec','+10',$q);
  $q = str_replace('jedenascie','+11',$q);
  $q = str_replace('dwanascie','+12',$q);
  $q = str_replace('trzynascie','+13',$q);
  $q = str_replace('czternascie','+14',$q);
  $q = str_replace('pietnascie','+15',$q);
  $q = str_replace('szesnascie','+16',$q);
  $q = str_replace('siedemnascie','+17',$q);
  $q = str_replace('osiemnascie','+18',$q);
  $q = str_replace('dziewietnascie','+19',$q);
  $q = str_replace('sto','+100',$q);
  $q = str_replace('dwiescie','+200',$q);
  $q = str_replace('tysiac','+1000',$q);
  $q = str_replace('milion','+1000000',$q);//i tu nie działa już :(
  $q = str_replace('miliard','+1000000000',$q);//tak samo...
  /*No i reszta*/
  $q = str_replace('dzies','*(10^1)',$q);
  $q = str_replace('scie','*(10^2)',$q);
  $q = str_replace('sta','*(10^2)',$q);
  $q = str_replace('set','*(10^2)',$q);
  $q = str_replace('tys','*(10^3)',$q);
  $q = str_replace('milion','*(10^6)',$q);//i tu nie działa już :(
  $q = str_replace('miliar','*(10^9)',$q);
  /*Zamiana znaków*/
  $q = str_replace('dod','+',$q);
  $q = str_replace('plu','+',$q);
  $q = str_replace('min','-',$q);
  $q = str_replace('ode','-',$q);
  $q = str_replace('otw','(',$q);
  $q = str_replace('zam',')',$q);
  $q = str_replace('pot','^',$q);
  $q = str_replace('razy','*',$q);
  $q = str_replace('mno','*',$q);
  $q = str_replace('podz','/',$q);
  $q = str_replace('prze','/',$q);
  $alfabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' '];
  foreach ($alfabet as $literka) {
    $q = str_replace($literka,'',$q);
  }
  return $q;
}
edytowany 3x, ostatnio: MrCyjaneK CyjaneK, 2019-07-17 07:10

Pozostało 580 znaków

2019-07-17 07:31
2

To jest ogólnie nieprzemyślane. Patrz np:

czterdzieści
Z resztą już z dwadzieścia zrobi ci jakieś +2*(10^2)cia
Poza tym np dwa miliony, pięć milionów.

Przemyśl ponownie założenia i wtedy pisz kod.


edytowany 2x, ostatnio: Freja Draco, 2019-07-17 07:32

Pozostało 580 znaków

2019-07-17 07:34
0
Freja Draco napisał(a):

To jest ogólnie nieprzemyślane. Patrz np:

czterdzieści
Z resztą już z dwadzieścia zrobi ci jakieś +2*(10^2)cia
Poza tym np dwa miliony, pięć milionów.

Przemyśl ponownie założenia i wtedy pisz kod.

co do 'cia' to na końcu wszystkie litery usuwa, a nad kodem myśle cały czas :/

Pozostało 580 znaków

2019-07-17 07:38
1
MrCyjaneK CyjaneK napisał(a):
Freja Draco napisał(a):

To jest ogólnie nieprzemyślane. Patrz np:

czterdzieści
Z resztą już z dwadzieścia zrobi ci jakieś +2*(10^2)cia
Poza tym np dwa miliony, pięć milionów.

Przemyśl ponownie założenia i wtedy pisz kod.

co do 'cia' to na końcu wszystkie litery usuwa, a nad kodem myśle cały czas :/

A... to po to ten alfabet na końcu.
Użyj raczej wyrażeń regularnych i https://www.php.net/manual/en/function.preg-replace.php


Pozostało 580 znaków

2019-07-17 07:41
0

Okej

edytowany 1x, ostatnio: MrCyjaneK CyjaneK, 2019-07-17 07:42

Pozostało 580 znaków

2019-07-17 07:49
0

Wyjąwszy powyższe zastrzeżenia, nie wiem, co ci tam nie działa przy 1 000 i 1 000 000.
U mnie wychodzi:

$q = "milion tysiac";
-> +1000000 +1000


Pozostało 580 znaków

2019-07-20 14:53
0

Ten problem wbrew pozorom nie jest taki prosty - zwłaszcza w języku polskim, ale zakładając, że przyjmiemy uproszczoną wersję, gdzie użytkownik może używać tylko ograniczonej liczby słów, da się to w miarę prosto ogarnąć.
Pierwszy błąd jaki robisz to próba ogarnięcia wszystkiego za pomocą 1 funkcji, gdzie problemy masz dwa - wykrycie działań i transformacja słów na liczby. Napiszę CI algorytm jak powinieneś do tego podejść (zakładam, że jesteś początkujący, więc użyjemy prostych metod).

  1. Na wejściu masz string typu "liczba działanie liczba działanie liczba działanie ...". Widzę tu prostą tablicę, gdzie parzyste indeksy (0,2,4) są liczbami, a nieparzyste (1,3...) nazwami działań. Zróbmy z tego 2 tablice - w jednej będą liczby, w drugiej działania. Działania są łatwe do wyłapania w stringu, bo to stałe, więc potraktujmy je jako rozdzielniki - czyli używając np. prostych funkcji typu str_search / str_pos wyłuskaj z tego 2 tablice wyszukując nazwy działań.
  2. Zajmijmy się tablicą z działaniami - przekształcenie nazw działań na odpowiadające im operatory jest banalne - wystarczy zrobić iterację po tablicy i stworzyć tablicę kolejnych działań - przykładowy rezultat ['+", '-', '+'] - jeden problem mamy rozwiązany.
  3. Większym problemem będą liczby, jeśli wykonałeś krok pierwszy to masz na wejściu tablicę w stylu ['jeden', 'pięć', cztery tysiące dwieście osiem']. Wypisując sobie przykładowe liczby na kartce zobaczysz, że składanie liczb rządzi się pewnymi prawami. Liczby do tysiąca są dość proste do przekształcenia ze słów na zapis liczbowy, potem zaczynają się schody, ale widać zależności typu jeśli jest tysiąc to nie ma przed tym liczby, ale jak są "tysiące/tysięcy" to musisz spodziewać się liczby. Nigdy tego nie robiłem ale na szybko napisałbym funkcję rozpoznającą liczby 0-999, podzielił string za pomocą stringów "tysięcy/milionów/miliardów' i przed tymi słowami wykorzystał ponownie funkcję rozpoznającą liczby 0-999 -> czyli przykładowo:
    (sto pięć) (tysięcy) (dwieście cztery) - mam w stringu słowo tysięcy, wiec spodziewam się liczby z zakresu (1-999) przed tym słowem i liczby (1-999) lub niczego za stringiem. Używając teraz funkcji do rozpoznawania liczb 0-999 + trochę zabawy powinieneś wyłuskać z takiego zapisu liczbę.
    Tak więc kończysz z tablicą typu [1,2,555,93433].
  4. Składamy dwie tablicę w jedną całość na przemian liczba - działanie - liczba - działanie - liczba i uzyskujemy wynik.

Myślę, że mniej więcej takim algorytmem nawet z użyciem podstawowych funkcji operujących na stringach powinno Ci się udać osiągnąć efekt. Nie sprawdzałem czy na 100% się sprawdzi, tylko tak na szybko naszkicowałem jak można ten problem ugryźć - pewnie przy implementacji parę kwestii wyskoczy. Jeśli piszesz to w celach edukacyjnych to wyjdź od jakiejś uproszczonej wersji typu tylko liczby do tysiąca, a dopiero potem postaraj się rozwinąć.

Najważniejsza lekcja do wyciągnięcia - złożone problemy rozkładaj na proste problemy.
Druga rada - zaprzyjaźnij się z tablicami.
Trzecia rada (niestety może być za trudna na tym etapie) - spróbuj zainstalować debugger, bo przy tego typu działaniach będziesz miał sporo sytuacji brzegowych i bez debuggera więcej czasu spędzisz na wyszukiwaniu błędów niż programowaniu.

Powodzenia.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0