• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Mnożenie stringa

Object Storage Arubacloud
0 głosów
2,113 wizyt
pytanie zadane 25 kwietnia 2018 w C i C++ przez Marcin Reguła Początkujący (450 p.)
zamknięte 26 kwietnia 2018 przez Marcin Reguła

Witam.

Ostatnio w jednym z zadań przyszło mi mnożyć pojedyńcze liczby z ciągu cyfr, i nie potrafię sobie z tym poradzić przy takim zapisie wartości na wyjściu są kosmiczne. Mogę liczyć na podpowiedź jak to zapisać?

#include <iostream>
using namespace std;

int main()
{  string pesel;
   cin>>pesel;
   int dlugosc=pesel.length();
   int c=pesel[0]*3;
   cout<<c;
   return 0;
}

 

komentarz zamknięcia: Rozwiązanie problemu
1
komentarz 25 kwietnia 2018 przez Beginer Pasjonat (22,110 p.)
Linia 7 (długość stringa) jest tutaj zbędna.

(Poza tym liczba znaków w PESEL jest zawsze stała i znana - wynosi 11)
komentarz 25 kwietnia 2018 przez Marcin Reguła Początkujący (450 p.)
Używając tablicy int każda cyfra musiała hy być po enterze a tego bym nie chciał tak za bardzo.
komentarz 26 kwietnia 2018 przez Beginer Pasjonat (22,110 p.)
Tutaj nie używasz żadnej tablicy. Z tego co widzę wczytujesz jako string cały PESEL w postaci 11 cyfr, i mnożysz pierwszą cyfrę PESEL przez 3.
komentarz 26 kwietnia 2018 przez Marcin Reguła Początkujący (450 p.)
Dokładnie, a wynik jest oderwany od matematyki jaką znamy (np.1*3=96) , a chciałbym żeby był poprawny.

2 odpowiedzi

+1 głos
odpowiedź 25 kwietnia 2018 przez niezalogowany
wybrane 26 kwietnia 2018 przez Marcin Reguła
 
Najlepsza

Każdy znak w stringu jest zapisany w postaci kodu ASCII np znak '0' to 48. Wiec musisz tyle odjąć, aby z kodu ASCII otrzymać odpowiadającą cyfrę dla intów. Na szczęście nie trzeba ich wszystkich pamiętać:

int main() {
	std::cout << int('a') << "\n";
	std::cout << int('0') << "\n";
	std::cout << int('9') << "\n";
	std::cout << int('0' - 48) << "\n";
	std::cout << int('9' - 48) << "\n";
	std::cout << int('9' - '0') << "\n";
	std::cout << int('6' - '0') << "\n";
}
komentarz 26 kwietnia 2018 przez mokrowski Mędrzec (155,460 p.)

@Swypeiro, Nie trzeba. To jest promocja. 1 bajt char, zawsze zmieści się w (conajmniej) 2 bajtach int.

Dodatkowo jest to bezpieczne bo znaki cyfr nie przekraczają wartości 128 w kodzie ASCII więc nie ma dyskusji o interpretacji signed char i unsigned char. char -> int to signed char -> signed int.

komentarz 26 kwietnia 2018 przez mokrowski Mędrzec (155,460 p.)

@Marcin Reguła, w najprostszym przypadku jeśli chcesz sprawdzić czy NIP ma poprawny format, sprawdź czy długość napisu to 11 i wszystkie jego znaki to cyfry. std::isdigit(...) zwracające bool, znajdziesz w <cctype>. Jeśli jednak formaty mają być różnorodne (np. 3-3-2-2 lub 3-2-2-3 lub 11), to niestety ale rozwiązaniem są wyrażenia regularne.

Do sprawdzenia czy wszystkie znaki spełniają warunek bycia cyfrą, użyć możesz std::all_of(...) z <algorithm> a do sumowania wyników mnożeń proszczególnych cyfr przez wagi std::inner_product(...) z <numerics>.

1
komentarz 26 kwietnia 2018 przez niezalogowany

Wspomniałbym jeszcze o tablicy, aby początkujący unikali takich sytuacji:

(pesel[0]-'0')*3 + (pesel[1]-'0')*1 + ... + (pesel[10]-'0')*6

Z jedną pętlą będzie ładnie wyglądać:

(pesel[i]-'0')*pattern[i]

To chyba jest najczęstsza wada w tym zadaniu (JPESEL - SPOJ) z tego co zauważyłem na forum.

komentarz 26 kwietnia 2018 przez mokrowski Mędrzec (155,460 p.)

@Hipcio, racja... no ale to wynika z std::inner_product

Z użyciem algorytmów wygląda nieźle:

#include <iostream>
#include <cctype>
#include <numeric>
#include <iomanip>
#include <functional>

bool is_pesel_valid(const std::string& pesel) {
    // Algorithm source: https://pl.wikipedia.org/wiki/PESEL
    // 11 chars && all digit && ctrl sum correct
    const int weights[] = {1, 3, 7, 9, 1, 3, 7, 9, 1, 3, 1};
    return (pesel.size() == 11)
        && std::all_of(pesel.cbegin(), pesel.cend(), ::isdigit)
        && !(std::inner_product(pesel.cbegin(), pesel.cend(), std::cbegin(weights), 0,
                std::plus<int>(), [](char c, int wght) { return (c - '0') * wght;}
            ) % 10);
}

int main() {
    auto peselOK = "81100216357";
    auto peselBAD = "44051401358";
    std::cout << "PeselOK  valid?: " << std::boolalpha << is_pesel_valid(peselOK) << '\n'
              << "PeselBAD valid?: " << std::boolalpha << is_pesel_valid(peselBAD) << '\n';
}

 

komentarz 26 kwietnia 2018 przez niezalogowany

@mokrowski Również zdaję sobie sprawę, że to tak wynika, ale to nie musi być oczywiste dla wszystkich ;)

0 głosów
odpowiedź 26 kwietnia 2018 przez Beginer Pasjonat (22,110 p.)
#include <iostream>
using namespace std;

int main()
{  string pesel;
   cin >> pesel;
   int c = (pesel[0] - 48) * 3;
   cout << c << endl;
   return 0;
}

P.S. Wystarczyło odjąć 48 (bo cyfry w ASCII zaczynają się od wartości 48). 

Podobne pytania

0 głosów
0 odpowiedzi 132 wizyt
pytanie zadane 18 listopada 2023 w Matematyka, fizyka, logika przez Kr1zu Nowicjusz (120 p.)
0 głosów
0 odpowiedzi 2,451 wizyt
pytanie zadane 24 listopada 2019 w C i C++ przez Kenzy Obywatel (1,160 p.)
–1 głos
2 odpowiedzi 280 wizyt
pytanie zadane 23 marca 2019 w C i C++ przez mikolaj_d Nowicjusz (120 p.)

92,568 zapytań

141,420 odpowiedzi

319,624 komentarzy

61,956 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...