Diskuze: Vybrání cifer z lichých pozic z dlouhého čísla
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Zobrazeno 5 zpráv z 5.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
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é.
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
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;
}
}
}
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.
Zobrazeno 5 zpráv z 5.