Char na atoi, cechy podzielności liczb przez 11

0

Witajcie, pisze program który sprawdzi czy dana liczba jest podzielna przez 11. Początkowo napisałem funkcję która rozdziela liczbę np.123 na 1 2 i 3. Potem biorę liczby z parzystych miejsc w tablicy (skakałem w pętli) i sprawdzałem dalej, operowałem na long long intach. Było ok, problem pojawił się jak musiałem sprawdzić liczbę 5669390663458168072112136553829401 program się wysypywał i wypadałem z zakresu. Przesiadłem się na chary, chce je skonwertować na inty i potem skakać i wybierać miejsca, niestety program sypie mi się w pętli.

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char liczba[255];
    int i,cyfra;

    scanf("%s", liczba);

    for(i=0; i < 255; i++)
    {
       int cyfra = atoi(liczba[i]);
       // printf("%s", liczba[i]);
    }



    getchar();
    return 0;
}

Jak to poprawić?

Pozdrawiam

0

a nie prościej będzie użyć operatora modulo:

 
bool czy_parzysta;
int x;
scanf("%d",&x);
czy_parzysta = !(x % 11);
if(czy_parzysta) {
printf("liczba jest parzysta");
}
else {
printf("liczba jest nieparzysta");
}
0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main()
{
    char liczba[255];
    int i,cyfra;
    int tablica[255];
    scanf("%s", liczba);
 
    for(i=0; i < strlen(liczba); i++)
    {
       tablica[i] = liczba[i] - '0';
       printf("%d", tablica[i]);
    }

Edit: Seg fault wychodzil dlatego, ze w for'ze bylo i < 255, i odwolywales sie do niezainicjowanych komorek.

0

Ok, ale i tak nie wiem co dalej. Chce po prostu wczytać dużą liczbę i wybrać z niej miejsca parzyste.
Robiłem to tak:
wczytuje liczbę, pojedyncze cyfry zapisuje do tablicy, odwracam tablice, skacze po tablicy, tylko że program nie działał dla większych liczb...

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    long long int n,suma=0,i=0,cyfra,tab[200],x,z,tmp;

    scanf("%lld", &n);

    do
    {
        cyfra = n % 10;
        n /= 10;
        tab[i] = cyfra;
        printf("%lld : tablica %d\n\n", cyfra,i);
        i=i+1;
    }
    while(n>0);


    //odwracam tablice
    for(z = 0; z < i / 2; z++)
    {
        tmp = tab[z];
        tab[z] = tab[i - z - 1];
        tab[i - z - 1] = tmp;
    }

    //wypisuje co 2 element
    for(x = 0; x < i; x++)
    {
        if(x%2==0)
        printf("Wartosci: %lld\n", tab[x++]);
    }


    getchar();
    return 0;
}

0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main()
{
    char liczba[255];
    int i,cyfra;
    int tablica[255];
    scanf("%s", liczba);
 
    for(i=0; i < strlen(liczba); i++)
    {
       tablica[i] = liczba[i] - '0';
       if(tablica[i] % 2 == 0)
       	 printf("%d", tablica[i]);
    }

	return 0;
}

Edit: Zle zrozumialem chyba:
Drugi wczytuje duza liczbe do tablicy intow, odwraca ja i wypisuje co drugie pole ow tablicy.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main()
{
    char liczba[255];
    int i,j,cyfra[255];
    int tablica[255];
    scanf("%s", liczba);
 
    for(i=0; i < strlen(liczba); i++)
    {
       tablica[i] = liczba[i] - '0';
       cyfra[i] = tablica[i];
    }
    for(i = strlen(liczba) - 1, j=0; i >= 0; --i, ++j) {
    	tablica[j] = cyfra[i];
    	if(j % 2 == 0)
    		printf("%d ", tablica[j]);
    }


	return 0;

}

0
 
char big_num[513];
int parzyste[512];
int i = 0;
int j = 0;

scanf("%s",big_num);

while(big_num[i] != 0) {
    int p = atoi(big_num[i]);
    if(!(p% 2)) {
        parzyste[j] = p;
        j++;
    }
    i++;
}

Wszystkie parzyste cyfry z podanej przez uzytkownika liczby znajda sie w tablicy "parzyste". Nie wiem może to ci pomoże jakoś rozwiązać twój problem.

0

Okej, napisałem już całą funkcję. Teraz mam problem ze sprawdzeniem podzielności dla 2. Muszę chara na inta zrobić żeby to sprawdzić, znowu sypie mi się przy dużych liczbach. Cały kod:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int podzielnosc_11(char liczba[255], int tablica[255])
{
    int z,parzyste=0,nieparzyste=0;
    for(z = 0; z < strlen(liczba); z++)
    {
          if(z % 2 == 0)
          {
                parzyste = parzyste + tablica[z];
          }
          else
          {
                nieparzyste = nieparzyste + tablica[z];
          }
    }
    if((parzyste - nieparzyste) % 11 == 0)
    {
       // printf(" 11 ");
    }
}
int podzielnosc_2(char liczba[255], int tablica[255])
{
    int i,cal;
    char * pKoniec;
    long long p = strtol (liczba, & pKoniec, 0 );
    printf("%lld", p);
}

int main()
{
    char liczba[255];
    int i,j,cyfra[255];
    int tablica[255];
    scanf("%s", liczba);

    for(i=0; i < strlen(liczba); i++)
    {
       tablica[i] = liczba[i] - '0';
       cyfra[i] = tablica[i];
    }
    podzielnosc_11(liczba, tablica);
    podzielnosc_2(liczba, tablica);


    getchar();
    return 0;
}
0

Przecież, żeby sprawdzić czy liczba jest podzielna przez dwa wystarczy sprawdzić jej ostatnią cyfrę.

0

jak skorzystasz z zasad:
(a + b) % c = (a % c) + (b % c)
(a * b) % c = ((a % c) * (b % c)) % c

to wystarczy zwykły schemat hornera + %11 na każdym kroku...

pisane z palca:

#include <string>
#include <iostream>

using namespace std;

// działa tylko dla dodatnich
int modulo_11(const string& s)
{
  int ret = 0;
  for (int i = 0; i < s.size(); i++)
  {
    ret *= 10;
    ret += s[i] - '0';
    ret %= 11;
  }
  return ret;
}

int main()
{
  string s;
  cin >> s;
  cout << "Wynik: " << modulo_11(s) << endl;
  return 0;
}
0

@krwq, dla 11 juz mam gotowe ale dzięki za przykład
@byku_guzio, wiem że trzeba sprawdzić ostatnią cyfrę ale nie mogę jej przyrównać bo jest w charze i dostaje błąd

0

Bierzesz ostatni znak, zamieniasz go na cyfrę(odejmujesz '0') i sprawdzasz czy się dzieli przez dwa bez reszty

0

Trochę przesadziłem wczoraj :D

coś takiego wystarczy

int podzielnosc_2(char liczba[255], int tablica[255])
{

    if( tablica[strlen(liczba)-1] == 2 | tablica[strlen(liczba)-1] == 0 | tablica[strlen(liczba)-1] == 4 | tablica[strlen(liczba)-1] == 8)
    {
        printf(" 2 ");
    }

}
0

Jeszcze jedno pytanie mam, jak połączyć wybrane elementy tablicy w jedne ciąg? Np. mam w tablicy liczbę 1234 a chce do zmiennej wrzucić 34?

0

Trochę przesadziłem wczoraj :D

coś takiego wystarczy
(...)

Dlaczego nie: ?

if(tablica[strlen(liczba)-1] % 2 == 0)

Będzie krócej, szybciej i mniej miejsca na zrobienie błędu (tak, Twój kod ma błąd - brakuje 6).
(I takie coś sugerował już byku_guzio)

0

No tak, racja. Teraz robię dla czwórki i muszę sprawdzić czy 2 ostatnie liczby w tablicy są podzielne przez 4. Dlatego pytałem się jak można połączyć 2 miejsca w tablicy w całość. Czy po prostu sprawdzić czy ostatnia cyfra jest podzielna przez 4?

0

No to liczba składająca się z dwóch ostatnich cyfr liczby będzie równa:
tablica[strlen(liczba)-2] * 10 + tablica[strlen(liczba)-1]

(pamiętaj że jeśli liczba < 10 to strlen(liczba) = 1 i musisz do tego dodać specjalny przypadek)

0

Ok, napisałem coś takiego

int podzielnosc_4(char liczba[255], int tablica[255])
{
    int i = tablica[strlen(liczba)-2] * 10 + tablica[strlen(liczba)-1];
    if(strlen(liczba) < 1)
    {
        if(tablica[0] % 4 == 0)
        {
            printf(" 4 ");
        }
    }
    else
    {

        if(i % 4 == 0)
        {
            printf(" 4 ");
        }
    }
}

i jest ok

0

ok, teraz robie dla 6 i muszę sprawdzić całą liczbę
teraz moje pytanie które już chciałem zadać wcześniej, jak sprowadzić całą liczbę z tablicy do jednej zmiennej? Czy wystarczy w pętli mnożyć razy 10 poszczególne składniki liczby?

0

Hm, no racja. Badana liczba będzie miała co najwyżej 255 cyfr. Jak w takim razie łatwo sprawdzić podzielność dla 6?

0

Rekurencyjnie sumowac wszystkie cyfry, a gdy zostanie tylko 1 z nich sprawdzac czy jest podzielna przez 3 oraz sprawdzac ostatnia cyfre czy jest podzielna przez 2.

0

coś takiego?

int podzielnosc_6(char liczba[255], int tablica[255])
{
    int i,suma=0;

    for(i=0; i<strlen(liczba); i++)
    {
        suma = suma*10 + tablica[i];
    }
}

edit:

w sumie do dopisalem coś takiego

int z,i,suma=0;
    if( tablica[strlen(liczba)-1] % 2 == 0)
    {

        z = 1;
    }


    for(i=0; i < strlen(liczba); i++)
    {
        suma = suma + tablica[i];
    }

    if(suma % 3 == 0)
    {

        z = z + 1;
    }
    if(z == 2)
    {
        printf(" 6 ");
    }
0

Po kiego do tych wszystkich funkcji przekazujesz dwie tablicy?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int podzielna_3(char liczba[])
  {
   int i,ret=0;
   for(i=strlen(liczba)-1;i>=0;--i) if(ret+=liczba[i]-'0'>10) ret-=9;
   return !(ret%3);
  }

int podzielna_2(char liczba[])
  {
   return !(liczba[strlen(liczba)-1]%2);
  }

int podzielna_6(char liczba[])
  {
   return podzielna_2(liczba) && podzielna_3(liczba);
  }

czyliczba(char liczba[])
  {
   int i=strlen(liczba);
   if(!i) return 0;
   for(--i;i>=0;--i) if(!isdigit(liczba[i])) return 0;
   return 1;
  }

int main()
  {
   char liczba[256];
   scanf("%255s",liczba);
   if(czyliczba(liczba))
     {
      if(podzielna_2(liczba)) printf("Podzielna przez 2\n");
      if(podzielna_3(liczba)) printf("Podzielna przez 3\n");
      if(podzielna_6(liczba)) printf("Podzielna przez 6\n");
     }
   else printf("to nie liczba\n");
   return 0;
  }

Reszta może wyglądać podobnie.

0

Nie przesadzacie z kombinowaniem z modulo dla wszysctkich możliwych liczb? ;]
Jasne że w szczególnych przypadkach da się szybciej (jak np. dla 2), ale w ogólności można napisać taką oto prostą funkcję do wszystkiego, samiast kombinować z podzielna_2, podzielna_3, podzielna_6,podzielna_11, podzielna_666 itd:

int str_mod(const std::string& str, int mod) {
    int result = 0;
    for (int i = 0; i < str.size(); i++) {
        result = (result * 10 + str[i] - '0') % mod;
    }
    return result;
}
0

Dzięki za przykłady, ale to chyba jeszcze nie mój level :D

0

póki co nie wiem jeszcze jak rozwiązać to z liczbą 17, muszę korzystać z cech podzielności.

0

Znalazłem taką zasadę:
Pomnóz cyfrę jedności przez 12 i dodaj do liczby utworzonej z pozostałych cyfr.Gdy wynik dzieli się przez 17 to liczba początkowa też(można powtarzać wielokrotnie)
Dla 51 mamy 5+12=17 czyli 51 dzieli się przez 17

Napisałem taką funkję

int podzielnosc_17(char liczba[255], int tablica[255])
{
    int j = tablica[strlen(liczba)-1] * 12,i,y,x=0;
    int g = strlen(liczba)-1;
    int c=g-1;
    long long int a=0;

    if(g>1)
    {

        for(i=0; i < g ; i++)
        {
              if(c>=0)
              {
                    a += tablica[i] * pow(10,c);
                    printf("tablica[%d]*pow(10,%d)\n",i,c);
                    c--;

              }
        }

         printf("\n\n\n%d", a);

    }
    else
    {
        for(i=0; i < g ; i++)
        {
             a += tablica[i] * pow(10,i);

        }
    }

     if((j+a) % 17 == 0)
     {
         printf(" 17 ");
     }

}

niby działa np. dla liczby 51 ale dla np. 102815688922899 już się zakres sypie

0
int podzielna_17(char liczba[])
  {
   int i,p,last,add,ret=0;
   char *copy;
   last=strlen(liczba);
   copy=(char*)malloc(last+2);
   copy[0]='0';
   memcpy(copy+1,liczba,last+1);
   for(p=1,add=0;p+2<last;)
     {
      add=12*(copy[last]-'0');
      for(i=last;i>p;--i)
        {
         add+=copy[i-1]-'0';
         copy[i]='0'+add%10;
         add/=10;
        }
      copy[p]='0'+add%10;
      if(!add) ++p;
      else
        {
         add/=10;
         if(add) copy[--p]='0'+add%10;
        }
     }
   ret=atoi(copy+p);
   free(copy);
   return !(ret%17);
  }
0

możesz mi trochę objaśnić ten kod?

0

Proszę: Pomnóz cyfrę jedności przez 12 i dodaj do liczby utworzonej z pozostałych cyfr.Gdy wynik dzieli się przez 17 to liczba początkowa też.
Pytaj konkretnie to co nie rozumiesz.

0

'Delikatnie' mówiąc trochę zmodyfikowałeś moją funkcję :D. Możesz mi powiedzieć czemu moja funkcja zawiodła i czym twoja to nadrobiła? :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1