Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Vybrání cifer z lichých pozic z dlouhého čísla

Aktivity
Avatar
Dominik Vokůrka:31.10.2021 11:56

Zdravím, v C# se snažím z dlouhého čísla, které zadám do konzole vytáhnout pouze cifry na lichých pozicích tak aby se mi uložily jako hodnoty proměnné a já s nimi pak mohl dál pracovat. Bohužel mě ale nenapadá jak. Budu moc vděčný každému kdo se mě pokusí nasměrovat na správnou cestu. Děkuji

Zkusil jsem: Nenapadá mě jak vybrat pouze liché pozice.

Chci docílit: Snažím se vytvořit validátor platebních karet a tak potřebuji vybrat z čísla platební karty cifry na lichých pozicích abych je mohl ověřit.
Více informací o tom jak se ověřují platební karty jsou zde: https://www.usetreno.cz/…ditni-karty/

 
Odpovědět
31.10.2021 11:56
Avatar
Alesh
Tvůrce
Avatar
Odpovídá na Dominik Vokůrka
Alesh:31.10.2021 12:17

Ty zadáš něco jako: "1248" a program má do proměnné uložit "14" (tj. textový řetězec vytvořený z 1. a 3 číslice), chápu to správně?
Toto je snadné. Stačí ten vstup projít for cyklem s krokem 2 a znak na té pozici přilepit do té nové proměnné.

 
Nahoru Odpovědět
31.10.2021 12:17
Avatar
Jan Kerhart
Člen
Avatar
Jan Kerhart:31.10.2021 15:36

Vzhledem k tomu, že pro ověření budeš muset pracovat se všemi čísly, nejen lichými, tak bych si nejprve celý String naparsoval na pole čísel (resp. při použití LINQ objekt IEnumerable). To lze úplně nejlépe udělat asi takto:

var numbers = input.Select(x => (int)char.GetNumericValue(x));

Potom už jen vynásobíš všechna lichá čísla 2, nejjednodušší je:

numbers = numbers.Select((x, i) => (i % 2 == 0) ? (x * 2) : x);

No a nakonec vše jen sečteš, jen pozor, že čísla větší než 9 je nutné nejprve ciferovat, tj. v tomto případě asi nejlépe odečíst od nich 9 (10 - 1):

int sum = numbers.Sum(x => (x >= 10) ? (x - 9) : x);

No a zjistit platnost přes modulo 10 by jsi asi už zvládl :)

return sum % 10 == 0

(pokud to nemáš v metodě, tak místo return použij if, Console.WriteLine nebo cokoliv jiného potřebuješ.)

Ještě by bylo vhodné hned po bodu č. 1 zkontrolovat, že v čísle byla pouze čísla, ne nějaké jiné znaky. Každý jiný znak bude v poli reprezentován hodnotou -1, tj. můžeš je třeba jen vyházet (čímž mimo jiné umožníš zápis s mezerami po 4 číslicích):

numbers = numbers.Where(x => x >= 0);

nebo vypsat nějaké chybové hlášení, vyhodit výjimku apod.

Pokud ti toto zápisy přes LINQ nejsou příjemné, tak vše to lze samozřejmě zapsat i jen pomocí cyklů.

Pozn: Kód jsem nezkoušel, ale měl by fungovat :)

 
Nahoru Odpovědět
31.10.2021 15:36
Avatar
HONZ4
Člen
Avatar
Odpovídá na Dominik Vokůrka
HONZ4:31.10.2021 16:19

Já bych to udělal takto, ošetřila by se tím možnost, že uživatel zadá třeba mezeru nebo pomlčku

using System;
using System.Text;

namespace TestConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            ulong pn = ParseNumber(Console.ReadLine());
            Console.WriteLine(pn);
        }

        static ulong ParseNumber(string str)
        {
            ulong value = 0;

            if (!string.IsNullOrEmpty(str))
            {
                int counter = 0;

                var bu = new StringBuilder(str.Length);

                foreach (var c in str)
                {
                    if (char.IsDigit(c))
                    {
                        if ((counter & 0x00000001) == 0) bu.Append(c);
                        counter++;
                    }
                }

                ulong.TryParse(bu.ToString(), out value);
            }

            return value;
        }
    }
}
 
Nahoru Odpovědět
31.10.2021 16:19
Avatar
HONZ4
Člen
Avatar
Odpovídá na Dominik Vokůrka
HONZ4:31.10.2021 19:22

Omlouvám se, nečetl jsem pozorně otázku, ani jsem se nedíval na ten uvedený odkaz.
Takže tady je oprava bez LINQ

using System;

namespace TestConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            bool valid = IsValidCardID(Console.ReadLine());
            Console.WriteLine((valid) ? "ANO" : "NE");
        }

        static bool IsValidCardID(string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                int counter = 0, sum = 0;
                int v, w;

                foreach (var c in str)
                {
                    if (char.IsDigit(c))
                    {
                        v = (int)char.GetNumericValue(c);

                        if ((counter & 0x00000001) == 0)
                        {
                            w = v * 2;
                            if (w > 9) w -= 9;
                            sum += w;
                        }
                        else sum += v;
                        counter++;
                    }
                }

                //Console.WriteLine(sum);
                return ((sum % 10 == 0) && sum > 0);
            }

            return false;
        }
    }
}

Příspěvek Jana Kerharta řeší problém nejspíš správně, já jen LINQ neovládám.

 
Nahoru Odpovědět
31.10.2021 19:22
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 5 zpráv z 5.