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

przesunięcia binarne w C

VPS Starter Arubacloud
0 głosów
197 wizyt
pytanie zadane 7 listopada 2019 w C i C++ przez kaco189 Nowicjusz (170 p.)
otwarte ponownie 8 listopada 2019 przez kaco189

mam problem z poniższym zadaniem : 


Napisz program, który wczytuje dane wejściowe (aż do EOF) i wypisuje te dane z następującą modyfikacją w reprezentacji bitowej: każda jedynka poprzedzona conajmniej trzema zerami zamieniona jest na zero. Program musi być w stanie wczytywać dane wejściowe nieograniczone długością.

Przykład 1: #

Wynik: !

Wyjaśnienie: W ciągu 00100011 zamieniamy drugą jedynkę i powstaje 00100001.

Przykład 2: bacxy

Wynik: ‘‘ax9

Mój kod działa tylko dla jednego znaku. Nie wiem jak bez używania tablic rozwiązać ten problem dla więcej niż jednego znaku, proszę o pomoc.
 

#include <stdio.h>
#include <stdbool.h>

int licznikzer=0;


int zamiana(int znak)
{
    for(int i=0;i<8;i++)
    {
        if(licznikzer>0)
        {

        }

        if(znak & (1<<i))
        {
            licznikzer=0;
            if (i >= 5)
            {

            }
            else
            {
            for(int j=i+1;j<i+4;j++)
            {
                if(znak & (1<<j))
                {
                    break;
                }
                else
                {
                    licznikzer++;
                }
            }
           if(licznikzer==3)
           {
            znak = znak & ~ (1<<i);
            licznikzer=0;
           }
           }
        }


    }
    return znak;

}


int main()
{
    int znak;
    while((znak=getchar())!=EOF)
    {
    znak=zamiana(znak);
    putchar(znak);
    }

    return 0;
}

 

komentarz 8 listopada 2019 przez adrian17 Ekspert (344,100 p.)

Mój kod działa tylko dla jednego znaku.

Nie za bardzo rozumiem. Odpaliłem i działa dla stringa "bacxy".

komentarz 8 listopada 2019 przez kaco189 Nowicjusz (170 p.)

Działa ale wynikiem dla bacxy ma być ``ax9, a mój program daje ``axy. Chodzi o to, że mój program nie rozpatruje sytuacji gdy np. jedynka jest na bicie piątym szóstym lub siódmym (licząc od zerowego) i kolejny znak może kontynuować podciąg zer. Przykład :
np. dla 10010010 00101101 powinno zamienić tą jedynkę, gdyż podciąg trzech zer jest kontynuowany dla kolejnego znaku, mój program tego nie robi (nie wiem jak zaimplementować to) 10010010 00101101 - > 00000010 00000011.

komentarz 8 listopada 2019 przez adrian17 Ekspert (344,100 p.)
Oh, w sensie że ma patrzeć też na granice między bajtami. To to ciekawsze. Ale niestety idę spać, może jutro na to spojrzę jeszcze.
komentarz 8 listopada 2019 przez kaco189 Nowicjusz (170 p.)
Tak właśnie mogą się łączyć te podciągi zer między bajtami. Byłbym bardzo wdzięczny : - )
komentarz 8 listopada 2019 przez mokrowski Mędrzec (155,460 p.)

@kaco189, wystarczy zapamiętać ilość wyzerowanych bitów nawet po wykonanej konwersji jednego znaku i wyzerować licznik zerowych bitów jeśli konwersja zaszła lub bit był ustawiony na 1. Tu zwykła zmienna static będzie odpowiednia jeśli podzielisz to na funkcje. Stąd pytanie czy znasz/możesz użyć funkcji?

komentarz 8 listopada 2019 przez kaco189 Nowicjusz (170 p.)
Nie mam pojęcia jak mógłbym to sensownie zaimplementować i odwołać się do jedynki z poprzedniego z znaku. Jeśli to nie problem proszę o jakieś małe przekształcenie mojego kodu.
komentarz 8 listopada 2019 przez mokrowski Mędrzec (155,460 p.)
Wiesz co ale masz to bardzo zakręcone. Zamiast iść od bardziej znaczących bitów i sprawdzać ilość zgaszonych, wyliczasz zbędne przesunięcia. Masz jakieś puste warunki i pętle.

Spróbuję Ci udokumentować możliwe rozwiązanie. Nie obraź się na dużą ilość komentarzy. Normalnie tyle ich się nie umieszcza.
komentarz 8 listopada 2019 przez kaco189 Nowicjusz (170 p.)
Ok dziękuję

1 odpowiedź

0 głosów
odpowiedź 8 listopada 2019 przez mokrowski Mędrzec (155,460 p.)
wybrane 8 listopada 2019 przez kaco189
 
Najlepsza

Użyj static by zapamiętać ilość bitów wyzerowanych pomiędzy znakami. Podziel to ładnie na funkcje:

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

/* Ilość bitów zerowych po których zerować bit bieżący */
#define DISABLE_AFTER 3

/* Przechowuje bieżącą ilość "bitów zerowych" */
static size_t zero_bit_counter;

/* Ustawia ilość bitów zerowych na zero przed następnym ciągiem konwersji */
static inline void reset_encoder(void);

/*
 * Koduje pojedynczy znak.
 * Uwaga: Funkcja ma efekt uboczny. Odkłada informację o ilości
 *        "bitów zerowych" tak aby użyć jej w następnej konwersji.
 */
static unsigned char encode_char(char c);

/* Koduje tablicę znaków terminowaną zerem "w miejscu" */
void encode_str(char * msg);

/* Prosty test prawidłowości działania */
int main(void) {
    char msg[] = "bacxy";

    printf("|%s| -> ", msg);
    encode_str(msg);
    printf("|%s|\n", msg);

    return EXIT_SUCCESS;
}

static inline void reset_encoder(void) {
    zero_bit_counter = 0;
}

static unsigned char encode_char(char c) {
    /* Rezultat kodowania */
    unsigned char result = 0;
    /* Ilość bitów w znaku (wbrew pozorom może być więcej niż 8) */
    size_t bit_counter = CHAR_BIT;
    /* Pętla od nastarszego bitu do najmłodszego */
    while(bit_counter--) {
        /* Jeśli bit zapalony to...  */
        if(c & (1 << bit_counter)) {
            /*
             * Zapal bit tylko w jeśli ilość poporzednio wyzerowanych większa
             * lub równa od DISABLE_AFTER
             */
            result |= (zero_bit_counter >= DISABLE_AFTER) ? 0: (1 << bit_counter);
            zero_bit_counter = 0;
        } else {
            /* Bit nie był zapalony, inkrementacja licznika */
            ++zero_bit_counter;
        }
    }
    return result;
}

void encode_str(char * msg) {
    /*
     * Wyzerowanie licznika ilości bitów zerowych
     * bo to nowe kodowanie znaków
     */
    reset_encoder();
    /* Pętla do znaku '\0' czyli końca napisu */
    while(*msg) {
        char c = encode_char(*msg);
        *(msg++) = c;
    }
}

 

Podobne pytania

0 głosów
1 odpowiedź 3,082 wizyt
pytanie zadane 3 czerwca 2018 w Java przez xnerwo Gaduła (3,270 p.)
+3 głosów
3 odpowiedzi 666 wizyt
pytanie zadane 29 czerwca 2015 w C i C++ przez krecik1334 Maniak (58,390 p.)
0 głosów
1 odpowiedź 163 wizyt
pytanie zadane 6 sierpnia 2022 w C i C++ przez RufinB Obywatel (1,830 p.)

92,452 zapytań

141,262 odpowiedzi

319,080 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...