Převod na čísla zadané textem v ASP.NET MVC
Zadání
Vytvořte webovou aplikaci v ASP.NET MVC, která vypočítá modus (nejčastěji se vyskytující prvek) z čísel zadaných ve formulářovém poli. Čísla jsou zadaná slovy a jsou vždy do 100, oddělená jsou čárkou.
Pokud je modů více, např. pro vstup:
sto, padesát šest, dvacet, sto, padesát šest
budou vypsány všechny, zde tedy 100, 56.
Mé řešení nebere ohled na diakritiku a funguje pro rozsah čísel 0-199 . Soutěžní verze ještě neměla ošetřené chybné převody řetězců "tricet dvacet", "jedenáct jedenáct" a pod. (hodnoty se sečetly)
Mé řešení
Nejdříve jsem si musel projít 3 tutoriály na MVC 1 2 3 . Po základním návrhu struktury MVC jsem se pustil do kódování ve třídě ModusModel.
Pro převod slovně zadaných čísel mě jako první napadlo využití přípon a kořenů slov číslic. Tím jsem docílil "pouhých" 25 řetězců pro porovnávání, které jsem uložil do slovníku.
dicFirstNumber.Add("nula", 0); dicFirstNumber.Add("jedna", 1); dicFirstNumber.Add("jede", 1); dicFirstNumber.Add("dva", 2); dicFirstNumber.Add("dve", 2); dicFirstNumber.Add("tri", 3); dicFirstNumber.Add("ctyri", 4); dicFirstNumber.Add("ctr", 4); dicFirstNumber.Add("pade", 5); dicFirstNumber.Add("pet", 5); dicFirstNumber.Add("pat", 5); dicFirstNumber.Add("sest", 6); dicFirstNumber.Add("sede", 6); dicFirstNumber.Add("sedum", 7); dicFirstNumber.Add("sedm", 7); dicFirstNumber.Add("osum", 8); dicFirstNumber.Add("osm", 8); dicFirstNumber.Add("devate", 9); dicFirstNumber.Add("devade", 9); dicFirstNumber.Add("devet", 9); dicFirstNumber.Add("deset", 10); dicSecondNumber.Add("cet", 10); dicSecondNumber.Add("nact", 1); dicSecondNumber.Add("sat", 10); dicThirdNumber.Add("sto", 100);
O to složitější pak bylo ošetřit, aby chybně zadaná čísla byla odhalena.
Postup
Vstupní řetězec se rozdělí na řetězce oddělené čárkou. Jedno číslo se pak podle mezer rozdělí na jednotlivé části (např. "dvacet jedna" na "dvacet","jedna"). Text se postupně testuje, zda obsahuje řetězce ze slovníků, a to od nejvyšších hodnot po nejmenší. Po zjištění hodnoty celého čísla se tyto hodnoty testují ve funkci CheckResults, jestli jsou korektní. Pokud je nalezena chyba, vypíše se, na které pozici se nachází.
private bool CheckResults(int[] results) { if (results.Length == 1) return true; //pokud se jedna o pouze jedno cislo, tak se nemusi nic dal resit if (results[0] != results.Max() || results[results.Length - 1] != results.Min()) //osetreni, ze cisla jsou serazena zleva doprava podle velikosti { return false; } if (results.Contains(10))//pokud obsahuje cislo 10 { if (results.Length == 3 || results[0] != 100) // cislo 10 muze byt pouze v kombinaci cisla 100 { return false; } } if (results.Length == 3)// aby proslo sto devadesat devet - kontroluji se hodnoty... neprojde tricet, dvacet, deset { if (results[0] == 100 && results[1] < 100 && results[1] > 19 && results[2] < 10) { return true; } else return false; } if (results.Length == 2) { if ((results[0] == 100 && results[1] < 100) || (results[0] > 19 && results[1] < 10)) { return true; } else return false; } return true; }
Samotný výpočet hodnoty modus:
private void CountModus() { StringBuilder sb = new StringBuilder(); int max = dicResult.Values.Max(); dicResult.Where(v => v.Value == max).Select(v => v.Key).ToList().ForEach(v => sb.Append(v + ", ")); sb.Remove(sb.Length - 2, 2); OutputString = sb.ToString(); }
Galerie

Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 127x (5.99 MB)
Aplikace je včetně zdrojových kódů v jazyce C#