# Shkenca > Informatikë dhe Internet > Arti i programimit >  C#: Program për tastierë telefoni

## strange

Pershendetje te gjitheve,


Me duhet per ta ndreq nje program ne c# qe kur te shkrun numra, te dalin shkronja (si ne tastierat e telefonit) dhe anasjelltas, psh nese e shkruj "6338444" me mujt me konvertu ne shkronja qe eshte fjala " meti".  Di dikush si mund te beje kete? Mund te me ndihmoni ? 

Falimenderit.

----------


## Borix

Ok, me poshte po te paraqes nje draft te shpejte te nje kodi qe me erdhi ndermend. Normalisht, mund ta zgjerosh vete me tej per implementime te tjera, apo per ndarje ne funsione, etj...

Se pari, konceptoje cdo tast te tastjeres se celularit si nje objekt. Pra, tasti eshte nje objekt. Nje tast, ne celularin tim Nokia, ka nje numer (0-9) dhe mund te kete ose jo nje set prej 3-4 germash. Tasti 0 ka nje hapesire; tasti 1 nuk ka asnje germe; tastet 2,3,4,5,6, dhe 8 kane nga tre germa te alfabetit anglez, dhe tastet 7 dhe 9 kane nga kater germa te ketij alfabeti. Pra, anetaret (members) te klases Tast qe do te ndertosh jane nje vektor stringu qe do te ruaje germat e tastit perkates, nje numer qe do te ruaje shifren e paraqitur ne tast, si dhe shto nje variabel qe do te ruaje frekuencen e perseritjes se nje numri ne nje string te dhene (per shembull, ne stringun "6338444", per numrin 4 variabli do te ruaje nje vlere te barabarte me 3, frekuenca e numrit 4. (Maksimumi i ketij variabli eshte 4, sepse deri ne kater germa, maksimumi, mund te mbaje nje tast.)

Me poshte, eshte nje shembull klase te quajtur Tast:



```
using System;
using System.Collections.Generic;
using System.Text;

namespace cellkeytoLetters
{
    class Tast
    {
        private int _cnt;
        private int _numri; // numri i tastit
        private int _sa_here; // frekuenca e numrit qe percakton germen.
        private string[] _keypad; // germat e tastit

        public Tast()
        {
            this.Frekuenca = 0;
        }

        #region Atribute
        // ketu mund te shtosh atribute te ndryshme
        public int NumriTastit
        {
            get
            {
                return _numri;
            }
            set
            {
                if (value >= 0 && value <= 9)
                    _numri = value;
            }
        }

        public int Frekuenca
        {
            get
            {
                return _sa_here;
            }
            set
            {
                _sa_here = value;
            }
        }

        #endregion


       #region Metoda

        public void Shto(int NumriTastit, int NumriGermave, string germat)
        {
            _cnt = 0;
            this.NumriTastit  = NumriTastit;
            _keypad = new string[NumriGermave];

            for (_cnt = 0; _cnt < NumriGermave; ++_cnt)
            {
                _keypad[_cnt] = germat.Substring(_cnt,1);
            }
        }

        public string ShfaqGermen(int IndeksiGermes)
        {
            return _keypad[IndeksiGermes-1]; // zero-based, prandaj hiq 1
        }
        #endregion
    }
}
```


Dhe koncepti i klases, deklaro, tek programi kryesor, nje vektor objektesh te tipit Tast. Me poshte po te paraqes kodin e programit, i cili do te jete me i qarte:



```
using System;
using System.Collections.Generic;
using System.Text;

namespace cellkeytoLetters
{
    class Program
    {
        static void Main(string[] args)
        {
            Tast[] NokiaTast = new Tast[10]; // gjithsej 10 taste

            string strNum;
            int i, alfIDX=1;

            const string alfabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

            strNum = "6338444"; // rasti qe keni dhene ju

            // fillimisht, shto numrat ne vektorin NokiaTast:
            for (i = 0; i < 10; i++)
            {
                // rezervo memorie per cdo tast ne vektor:
                NokiaTast[i] = new Tast();
              
                if (i == 0) // tasti 0 ka nje hapesire
                    NokiaTast[i].Shto(0, 1, " ");
                else if (i == 1) // tasti 1 nuk ka asgje
                    NokiaTast[i].Shto(1, 0, ""); 
                else if (i>1 && i<7 || i==8) // tastet 2-6 dhe 8 kane nga 3 germa
                {
                    NokiaTast[i].Shto(3, 3, alfabet.Substring(alfIDX - 1, 3));
                    alfIDX += 3;
                }
                else if (i == 7 || i==9) // tastet 7 dhe 9 kane nga 4 germa
                {
                    NokiaTast[i].Shto(4, 4, alfabet.Substring(alfIDX - 1, 4));
                    alfIDX += 4;
                }
            }


            // tani, lexo numrat ne stringun strNum dhe nxirr germat:
            int saHere = 0, nr=0; // sa here shfaqet numri?
            i = 0;

            // fillo me germen e pare ne string:
            string currentChar = strNum.Substring(i, 1);

            while (i <= strNum.Length )
            {
                string ch="";

                try
                {
                    nr = int.Parse(currentChar);
                    ch = strNum.Substring(i, 1);
                }
                catch
                {
                    // shmang ndonje gabim ne lidhje me indeksin ne string
                }

                /* krahaso germen aktuale me germat ne vazhdim.
                 * per sa kohe qe germa aktuale eshte e barabarte
                 * me germat ne vazhdim, rrit vleren e variablit saHere,
                 * per te llogaritur frekuencen.
                 * Ne baze te vleres te saHere do te dallohet se per cilen
                 * germe te tastit perkates behet fjale...
                 * 
                 */
                if (ch == currentChar)
                {
                    ++saHere; // sa here perseritet germa aktuale
                    ++i; // rrit indeksin per germen tjeter ne string
                }
                else 
                {
                    // ruaj frekuencen e shfaqjes se numrit:
                    
                    NokiaTast[nr].Frekuenca = saHere;
                    Console.Write(NokiaTast[nr].ShfaqGermen(NokiaTast[nr].Frekuenca));
                    saHere = 0;
                    currentChar = ch; //fillo me karakterin tjeter te ndryshem
                }
                   
            }
            Console.ReadLine();
        }
    }
}
```

Pra, ideja eshte e tille: per secilin nga 10 tastet ne vektorin NokiaTast[] te tipit Tast, inicializo atributet. Per shembull, per tastin me numer 5 do te inicializosh atributin "NumriTastit" ne vleren "5" si dhe vektorin privat string "_keyPad[]" nepermjet funksionit publik Shto(...).

Pas inicializimit, studiohet stringu qe user-i jep si input, ne kete rast vlera "6338444". Algoritmi eshte i thjeshte: Merr vleren 6 dhe konvertoje ne integer duke perdorur metoden int.Parse() brenda nje blloku try...catch, per arsye shmangie gabimesh. Mbaje mend kete vlere dhe kontrollo se mos kete vlera te njejta ne vazhdim. Per sa kohe qe vlera aktuale eshte e barabarte me vleren ne vazhdim, rrit frekuencen. Pasi te mos jete me e barabarte (shih bllokun "else" tek loop-i "while"), afisho ne ekran germen perkatese, dhene frekuenca. Per shembull, ne rastin e vleres "3", frekuenca do te jete dy. Atehere, nga objekti NokiaTast[3], qe ka frekuence = 2, merr nga vektori _keypad[] vleren _keypad[2-1] = _keypad[1] = germa "E". Tek tasti 3, germa numer 2, ose germa me indeks 2-1 =1 eshte germa "E". Logjika aplikohet njelloj per germat e tjera.

Sigurisht, nje menyre me tradicionale do te ishte te perdorje nje strukture me dy atribute - numri i tastit dhe nje vektor germash per numrin perkates. Pastaj me te njejtin "while" loop si me lart mund te afishoje germat e nje stringu te dhene nga useri. gjithesesi, aq me teper ne C#, mos iu ndaj asnjehere te menduarit te orientuar me objekte, sepse kjo eshte dicka natyrore per qenien njerezore...

----------


## strange

Borix, te falimenderoj shume ty për mundimin qe ke bere e provova dhe funksionoi perveç dy gjerave të vogla, nese shkruaj te marrim shembull " Only" me numra qe i bien te shkruaj "66666555999" me qet një gabim qe se marr vesh dhe mendoj se gabimi qëndron se nuk e di te marri *O* përpara apo *N*, por nese do ta kishim ber me hapsir ne mes do ta kishte qit mirë, por kur e le ne mes te numrave një hapsir, me qet vetëm shkronjën e par tani nuk vazhdon pra e qet vetëm "666" një "0" dhe ndalet, me ndihmon dhe ni cik po nuk te erdhi mërzi se si ta bej qe te mund ta shkruaj" 666 66 555 999 " dhe at'here do funksionoi, te lutem nëse nuk te vjen merzi.

----------


## Borix

Duhet te vendosesh kufizime: pra, maksimumi i frekuences se numrit "6", le te themi, eshte 3. Atehere deklaro nje private member ne klasen Tast dhe nje public property GEt/Set per te lexuar/shkruar vleren e variablit ne loop-in e pare "for". Dhe tek while loop, kontrollo nese  variabli saHere eshte 3, ne rastin e tasteve 2,3,4,5,6, dhe 8, apo "4" ne rastin e tasteve 7 dhe 9. Nese po, atehere printo germen dhe kalo tek germa tjeter... Pra, keto jane modifikime qe ti i ben klases sipas nevojes...

----------


## strange

Borix, nëse nuk perton te ma shkruash se ndoshta bej ndonjë gabim ne shkrim se s'eshte pune; bej tre ore tu provu s'ka shanc ta bej vet. Kur shkruaj tani "6666" ma qet dy here "OO". S'me shkruan ti njiher nëse nuk te merziz ketë pjesën shtesë për te ndarë numrat?

Faleminderit shume shume. Te sjellt Zoti ndonje te mire  :buzeqeshje:

----------


## Borix

> flm shume shume nga ti te sjellt zoti ndonje te mire


Atehere, ...

Me poshte po te paraqes ndryshimet e duhura ne kod, si dhe nje rast special qe duhet te kesh parasysh.

Edhe nje here kodi i klases, me nje PUBLIC MEMBER te quajtur Maks, qe nenkupton kufirin e numrit total te germave qe mban nje objekt "Tast". Pra, per tastin numer 7, variabli Maks merr vleren 4, sepse mban deri ne 4 germa: PQRS. Pra, kodi i klases:



```
using System;
using System.Collections.Generic;
using System.Text;

namespace cellkeytoLetters
{
    class Tast
    {
        private int _cnt;
        private int _numri; // numri i tastit
        private int _sa_here; // frekuenca e numrit qe percakton germen.
        private string[] _keypad; // germat e tastit
        public byte Maks;

        public Tast()
        {
            this.Frekuenca = 0;
        }

        #region Atribute
        // ketu mund te shtosh atribute te ndryshme
        public int NumriTastit
        {
            get
            {
                return _numri;
            }
            set
            {
                if (value >= 0 && value <= 9)
                    _numri = value;
            }
        }

        public int Frekuenca
        {
            get
            {
                return _sa_here;
            }
            set
            {
                _sa_here = value;
            }
        }

        
        #endregion

        #region Metoda

        public void Shto(int NumriTastit, int NumriGermave, string germat)
        {
            _cnt = 0;
            this.NumriTastit  = NumriTastit;
            _keypad = new string[NumriGermave];

            for (_cnt = 0; _cnt < NumriGermave; ++_cnt)
            {
                _keypad[_cnt] = germat.Substring(_cnt,1);
            }
        }

        public string ShfaqGermen(int IndeksiGermes)
        {
            return _keypad[IndeksiGermes-1];
        }
        #endregion
    }
}
```

Vere se edhe variabli _cnt ruan (automatikisht) kufirin maksimal, megjithate nga ana konceptuale, eshte mire qe cdo atribut te jete i tille qe te kete nje kuptim te caktuar per rregullat e punes e te objektivave te tua ne lidhje me cdo lloj programi qe zhvillon.

Tani, vjen kodi i klases kryesore - Program.cs. Ketu, sic mund ta vesh re tek rreshtat te ngjyrosura ne te kuqe, kam shtuar nje kod ku te caktohet vlera e variablit Maks - per tastet 0 dhe 1 ajo eshte 1 dhe 0, perkatesisht. Per tastet 7 dhe 9, ajo eshte 4, ndersa per tastet e tjera ajo eshte 3.



```
using System;
using System.Collections.Generic;
using System.Text;

namespace cellkeytoLetters
{
    class Program
    {
        static void Main(string[] args)
        {
            Tast[] NokiaTast = new Tast[10]; // gjithsej 10 taste
            string strNum;
            int i, alfIDX=1;

            const string alfabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

            strNum = "66666555999"; //- rezultati: "ONLY"

            // fillimisht, shto numrat ne vektorin NokiaTast:
            for (i = 0; i < 10; i++)
            {
                // rezervo memorie per cdo tast ne vektor:
                NokiaTast[i] = new Tast();

                if (i == 0) // tasti 0 ka nje hapesire
                {
                    NokiaTast[i].Maks = 1;
                    NokiaTast[i].Shto(0, NokiaTast[i].Maks, " ");
                }
                else if (i == 1) // tasti 1 nuk ka asgje
                {
                    NokiaTast[i].Maks = 0;
                    NokiaTast[i].Shto(1, NokiaTast[i].Maks, "");
                }
                else if (i > 1 && i < 7 || i == 8) // tastet 2-6 dhe 8 kane nga 3 germa
                {
                    NokiaTast[i].Maks = 3;
                    NokiaTast[i].Shto(3, NokiaTast[i].Maks, alfabet.Substring(alfIDX - 1, 3));
                    alfIDX += 3;
                }
                else if (i == 7 || i == 9) // tastet 7 dhe 9 kane nga 4 germa
                {
                    NokiaTast[i].Maks = 4;
                    NokiaTast[i].Shto(4, NokiaTast[i].Maks, alfabet.Substring(alfIDX - 1, 4));
                    alfIDX += 4;
                }
            }


            // tani, lexo numrat ne stringun strNum dhe nxirr germat:
            int saHere = 0, nr=0; // sa here shfaqet numri?
            i = 0;

            // fillo me germen e pare ne string:
            string currentChar = strNum.Substring(i, 1);

            while (i <= strNum.Length)
            {
                string ch="";

                try
                {
                    nr = int.Parse(currentChar);
                    ch = strNum.Substring(i, 1);
                }
                catch
                {
                    // shmang ndonje gabim ne lidhje me indeksin ne string
                }

                /* krahaso germen aktuale me germat ne vazhdim.
                 * per sa kohe qe germa aktuale eshte e barabarte
                 * me germat ne vazhdim, rrit vleren e variablit saHere,
                 * per te llogaritur frekuencen.
                 * Ne baze te vleres te saHere do te dallohet se per cilen
                 * germe te tastit perkates behet fjale...
                 * 
                 */
                if (ch == currentChar && saHere < NokiaTast[nr].Maks)
                {
                    ++saHere; // sa here perseritet germa aktuale
                    ++i; // rrit indeksin per germen tjeter ne string
                }
                else 
                {
                    // ruaj frekuencen e shfaqjes se numrit:
                    
                    NokiaTast[nr].Frekuenca = saHere;
                    Console.Write(NokiaTast[nr].ShfaqGermen(NokiaTast[nr].Frekuenca));
                    saHere = 0;
                    currentChar = ch; //fillo me karakterin tjeter te ndryshem
                }
                   
            }
            Console.ReadLine();
        }
    }
}
```

Pra, tek for-loop, ti inicializon variablin public Maks ne kufirin perkates. Ndersa tek while-loop, qe eshte pjesa kryesore e programit, ti kontrollon se sa here eshte numeruar e njejta shifer. Ne rastin e stringut 66666555999, if-i kontrollon se sa here numerohet shifra "6", le te themi. Ne kete rast, kur shifra "6" eshte numeruar "3" here, atehere blloku "if" nuk ekzekutohet, ne favor te bllokut "else", i cili shfaq germen "O".


Tani, po te jap nje rast te ndryshem. Ekzekuto programin e mesiperm me kete string:



```
strNum = "99999999999999444999988";
```

REzultati do te jete i qarte: *ZZZXIZU*. Megjithate, nese une kerkoj stringun "*ZZYXWIZU*", atehere kjo perkthehet ne shifra si me poshte:



```
9999 9999 999 99 9 444 9999 88
```

Por, sic mund ta vesh re, ky kod eshte ekzaktesisht i njejte me vlere e mesiperme, por rezultat qe prodhon jane te ndryshme. Programi gjithnje do te prodhoje rezultatin e pare, sepse while-loop kontrollon deri ne Maks. Atehere, per te nxjerre rezultatin e duhur, mund te besh nje manipulim te tille: shto nje shifer "0" (zero) ne pikat "kritike" qe programi te printoje nje hapesire dhe te dalloje midis germave qe ti kerkon. Pra, 

9999*0*9999*0*999*0*99*0*9444999988 

do te afishoje ne ekran kete: *Z Z Y X WIZU*, ajo qe kerkuam me lart.

----------


## strange

Borix Faleminderit shume shume nga ti, s di cfare te te them tjetër veç te ruajt Zoti nga te këqijat, programi funksion për mrekulli.  :buzeqeshje: 

t'pershendes.

----------

