Od 15. do 21.4. slevy 20 až 80% v sekci C/C++. Když ne teď, tak kdy?
Vyšlehej si extra vědomosti! Až 100% bodů na prémiový obsah zdarma! Více zde

Diskuze: Převod pozice ve string na int

Aktivity (4)
Avatar
Michal Ch
Člen
Avatar
Michal Ch:18. února 16:20

Zdravím, pokouším se napsat program, který po zadání libovolného řetězce (kombinace písmen a čísel) vyhodnotí procentuální zastoupení čísel a čísla sečte.

Postupoval jsem dle hledání souhlásek a samohlásek v lekci 9. Procentuální zastoupení čísel funguje, ale nemůžu přijít na to jak převést string na požadované pozici na int, abych ho mohl sečíst a dosáhnout tak požadovaného součtu číslic.

Věřím že to nebude nic složitého, nicméně jako začátečník jsem si s tím dlouho lámal hlavu a nenašel jsem řešení. Budu rád za každou radu/připomínku nebo pomoc :-). Díky.

Takhle vypadá zatím můj kód:

{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Zadej libovolnou kombinaci čísel a písmen");
            string a = Console.ReadLine();
            a = a.ToLower();

            int pocetcisel = 0;
            int pocetpismen = 0;
            int soucet = 0;

            string cisla = "0123456789";
            string pismena = "aábcčdďeéěfghiíjklmnňoópqrřsštťuůúvwxyýzž";

            foreach (char b in a)
            {
                if (cisla.Contains(b))
                {
                    //int x = Convert.ToInt32(a[b]);
                    //soucet = soucet + x;
                    pocetcisel++;
                }
                if (pismena.Contains(b))
                    pocetpismen++;

            }

            Console.WriteLine();
            Console.Write("Číslice zabírají: " + (float)pocetcisel * 100 / a.Length + "% ze zadaného řetezce");
            Console.ReadLine();
 
Odpovědět 18. února 16:20
Avatar
Odpovídá na Michal Ch
Michael Škrášek:18. února 17:38

Chyba:

//Convert.ToInt32(a[b]);
Convert.ToInt32(b)

Kód by mohl vypadat nějak takhle:

int letters = 0, digits = 0, total = 0;
foreach (char ch in a)
{
    if (char.IsDigit(ch))
    {
        digits++;
        total += Convert.ToInt32(ch);
    }
    else if (char.IsLetter(ch))
        letters++;
}

Console.WriteLine($"Číslice zabírají: {(float)digits * 100 / a.Length}% ze zadaného řetezce");
Console.WriteLine($"Písmena zabírají: {(float)letters * 100 / a.Length}% ze zadaného řetezce");
Console.WriteLine($"Součet číslic: {total}");
Nahoru Odpovědět 18. února 17:38
I choose a lazy person to do a hard job. Because that person will find an easy way to do it ... Bill Gates
Avatar
Odpovídá na Michael Škrášek
Tomáš Novotný:18. února 20:21

ahoj
spíše něco k zamyšlení....
a řeší se číslo nebo číslice? z mého pohledu je v tom docela rozdíl... třeba ve stringu 'ahoj 123 +-/' je celkem znaků 12, alfabetických 4, numerických (číslicových) 3, speciálních 3, mezer 2, slov 1, čísel 1, skupin spec. znaků 1
potom % zastoupení číslic je 3/12 a jejich součet 6
ale % zastoupení čísel je 1 z ? toto nedává úplně smysl, jedině v případě, že by se ostatní části považovaly třeba za slova/skupiny ... tj.. 1/3 ze všech skupin ..1x slovo ahoj, 1x číslo 123, 1x skupina znaků +-/
nevím jak je C# řešeno, ale z jiného jazyku mám třeba zkušenost s tím, že je potřeba u funkcí, které počítají znaky dbát i na kódování...
tj. pokud by vstup byl třeba v utf-8, ale funkce by si myslela, že string je v kódování 1250 tak v případě českých znaků dojde ke špatným výsledkům...

Nahoru Odpovědět 18. února 20:21
∞ ... the exact amount of possibilities how to deal with the situation ... so by calm, your solution is one of many
Avatar
Jan Mareš
Člen
Avatar
Jan Mareš:19. února 5:15

Ahoj jsem také začátečník. Ale zkusil by jsem to převést Parsováním.
Př:

int soucet = int.Parse (cisla);

Něco podobného se použilo ve 4té lekci. Základní konstrukce c# net.

 
Nahoru Odpovědět  +1 19. února 5:15
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Michal Ch
DarkCoder:19. února 14:16

Konverzi číslice reprezentované jako znak na jeho číselnou hodnotu provedeš pomocí výrazu (C notace):

c - '0' nebo c - 48 (první způsob je lepší).

kde c představuje znak v rozsahu ASCII 48 až 57 (0 = 48, ..., 9 = 57). Výsledek výrazu je číselná hodnota konvertovaného znaků, kterým je číslo.

Nahoru Odpovědět 19. února 14:16
"„Učíš-li se proto, aby sis zapamatoval, zapomeneš. Učíš-li se proto, abys porozuměl, zapamatuješ si."
Avatar
Michal Ch
Člen
Avatar
Odpovídá na Michael Škrášek
Michal Ch:19. února 17:07

@Michael Skrášek: bohužel tvůj kód mi nefunguje. Při napsání: a2 mi jako odpověď součtu vyleze číslo 50, obdobně při vstupu více čísel. Je tam jakési prolínání s číslem 50...

@Tomáš Novotný: také jsem na to myslel, nicméně je to myšleno jako jedna číslice tzn od 0 do 9.

@Jan Mareš: takto mi to také bohužel nejde, převede mi to pouze celý řetězec na jedno číslo s písmenky

@DarkCoder: bohužel nevím jak to myslíš, můžeš prosím napsat příklad přímo v nějakém krátkém kódu ? :-)

 
Nahoru Odpovědět 19. února 17:07
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Michal Ch
DarkCoder:19. února 17:38

Konverze číslice 2 z char na int.
(Kód psán v C)

char buff[] = "Test123";
int val = buff[5] - '0';

Proměnná val nyní obsahuje hodnotu 2.

Nahoru Odpovědět 19. února 17:38
"„Učíš-li se proto, aby sis zapamatoval, zapomeneš. Učíš-li se proto, abys porozuměl, zapamatuješ si."
Avatar
Odpovídá na Michal Ch
Michael Škrášek:19. února 17:45

Jo, menší chybka:

//Convert.ToInt32(ch);
int.Parse(ch.ToString());
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět 19. února 17:45
I choose a lazy person to do a hard job. Because that person will find an easy way to do it ... Bill Gates
Avatar
Michal Ch
Člen
Avatar
Odpovídá na DarkCoder
Michal Ch:19. února 17:47

Když to tak napíšu, tak mi píše, že index je mimo hranice pole. Proměnná a je typu string a je to pro mě ten vstupní řetězec.

foreach (char b in a)
           {
               if (cisla.Contains(b))
               {
                   int pom = a[b] - '0';
                   soucet = pom + soucet;
                   pocetcisel++;
               }
               if (pismena.Contains(b))
                   pocetpismen++;
 
Nahoru Odpovědět 19. února 17:47
Avatar
Michal Ch
Člen
Avatar
Odpovídá na Michael Škrášek
Michal Ch:19. února 17:50

Děkuji, v této podobě kód již funguje jak má:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Zadej libovolnou kombinaci čísel a písmen");
            string a = Console.ReadLine();
            a = a.ToLower();

            int pocetcisel = 0;
            int pocetpismen = 0;
            int soucet = 0;

            string cisla = "0123456789";
            string pismena = "aábcčdďeéěfghiíjklmnňoópqrřsštťuůúvwxyýzž ";

            foreach (char b in a)
            {
                if (cisla.Contains(b))
                {
                    soucet += int.Parse(b.ToString());
                    pocetcisel++;
                }
                if (pismena.Contains(b))
                    pocetpismen++;

            }

            Console.WriteLine();
            Console.Write("Číslice zabírají: " + (float)pocetcisel * 100 / a.Length + "% ze zadaného řetezce");
            Console.WriteLine();
            Console.Write("Součet číslic je: " + soucet);
            Console.ReadLine();
 
Nahoru Odpovědět 19. února 17:50
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Michal Ch
DarkCoder:19. února 20:11

Meze máš ošetřené podmínkou cyklu, přístup k hodnotám na daném indexu se provádí nepřímo pomocí ukazatele. Zde je pak ukázka a důkaz toho, že výraz c - '0' platí. Kód opět v jazyce C.

// Zde načtení řetězce str

ndigits = 0;
sum = 0;
while (*pstr) {
        if ((*pstr >= '0') && (*pstr <= '9')) {
                ndigits++;
                sum += (*pstr - '0');
        }
        pstr++;
}

kde pstr je ukazatel na vstupní řetězec str, ndigits představuje počet číslic v řetězci str a sum součet číslic v řetezci str. Rozdíl ukazatelů představuje délku řetězce a tedy procentuální zastoupení číslic v řetězci je pak dáno vztahem:

(ndigits / (float)(pstr - str)) * 100

Přetypování jednoho z operandů je nutné z důvodu zamezení celočíselného dělení.

Nahoru Odpovědět 19. února 20:11
"„Učíš-li se proto, aby sis zapamatoval, zapomeneš. Učíš-li se proto, abys porozuměl, zapamatuješ si."
Avatar
Odpovídá na Michal Ch
Michael Škrášek:19. února 20:38

Tenhle kód by samozřejmě měl fungovat ... jen menší chybka:

//int pom = a[b] - '0';
int pom = b - '0';
Nahoru Odpovědět 19. února 20:38
I choose a lazy person to do a hard job. Because that person will find an easy way to do it ... Bill Gates
Avatar
Michal Ch
Člen
Avatar
Michal Ch:19. února 20:54

Děkuji všem :-)

 
Nahoru Odpovědět 19. února 20:54
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 13 zpráv z 13.