NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Palindróm, odstránenie dlhých písmen

V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
ra3sk
Člen
Avatar
ra3sk:15.5.2016 10:46

Ahoj, znova som tu ja :D. Mám za úlohu zistiť či je veta palindróm a mám zenedbať medezere a písmena s dĺžňami. Medzere som odstránil (viď. nižšie), ale na dlhé písmená nie. Neviem ako na to. Testovacia veta je: Kobyla má malý bok

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

int main(){
    char text[100];
    int dlzka_textu,i;

    printf("Zadaj vetu\n:");
    gets(text);

    dlzka_textu=strlen(text);

    for(i=0;i<dlzka_textu;i++){
        if(text[i]==' '){
            text[i]='\b' ;
        }
    }
    puts(text);

    for(i=0;i<dlzka_textu;i++){
        if(text[i]==text[-i]){

        }
    }


    return 0;
}
 
Odpovědět
15.5.2016 10:46
Avatar
tomisoka
Tvůrce
Avatar
Odpovídá na ra3sk
tomisoka:15.5.2016 20:55

Nejdříve odstraň ty mezery (viz http://www.itnetwork.cz/…738b3da76529#…).
A potom to testování na palindrom:

bool palindrom = 1;
for(i=0;i<dlzka_textu/2;i++){//stačí ti zkontrolovat 1. polovinu, v 2. polovině by se ti znovu zkontrolovaly znaky, které už zkontrolované jsou.
        if(text[i]!=text[dlzka_textu-1-i]){ //kontroluješ zda znak 'i' se shoduje se znakem 'i' od konce.
                palindrom = 0;
                break;
        }
    }

Jinak kódem "text[-i]" se dostáváš před pole a může ti to spadnout, minimálně dostaneš nesmysly.

 
Nahoru Odpovědět
15.5.2016 20:55
Avatar
ra3sk
Člen
Avatar
Odpovídá na tomisoka
ra3sk:15.5.2016 21:55

A jak by si mi poradil ísť na tie dlhé znaky?

 
Nahoru Odpovědět
15.5.2016 21:55
Avatar
tomisoka
Tvůrce
Avatar
Odpovídá na ra3sk
tomisoka:15.5.2016 22:29

"dlhé znaky" - tím máš na mysli znaky s diakritikou? Jestli jo, tak s tím ti moc nepomůžu, nikdy jsem nepracoval s textem tolik, takže jsem to nikdy moc neřešil. Přeci jenom se pracuje dost blbě s polem, ve kterém nemají prvky jednotnou délku.

 
Nahoru Odpovědět
15.5.2016 22:29
Avatar
Odpovídá na tomisoka
Libor Šimo (libcosenior):16.5.2016 6:03

Palindrom je veta, slovo alebo cislo, ktore je rovnake od predu aj odzadu.
Matej je tam
kolok
1234321

Nahoru Odpovědět
16.5.2016 6:03
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na ra3sk
Libor Šimo (libcosenior):16.5.2016 6:06

Pismen s diakritikou sa zbavis tak, ze v retazci nechas len pismena bez diakritiky.
Teda, kontrolujes ho na znaky a - z A - Z.

Nahoru Odpovědět
16.5.2016 6:06
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
ra3sk
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
ra3sk:16.5.2016 6:53

To mi je jasné ale ako ich nahradiť. Napr: kobyla má malý bok

Ako nahradit alebo ignorovat tie pismena tak, aby bola veta stale rovnaka?

 
Nahoru Odpovědět
16.5.2016 6:53
Avatar
martanec
Člen
Avatar
martanec:16.5.2016 7:53

Substituciou. Ak narazis na znak, dajme tomu 'á', nahradis ho v poli 'a'. Ak narazis na 'ý' nahradis ho 'y', atd...

if( 'á' == text[i])
  text[i] = 'a';

Podobne to robis s medzerou medzi slovami ;)

Editováno 16.5.2016 7:54
 
Nahoru Odpovědět
16.5.2016 7:53
Avatar
ra3sk
Člen
Avatar
Odpovídá na martanec
ra3sk:16.5.2016 9:38

Mal som ten istý nápad a dal som to do switchu, ale dostal som error, ze 'á' nie je charakter.

 
Nahoru Odpovědět
16.5.2016 9:38
Avatar
Veles
Člen
Avatar
Veles:16.5.2016 10:55

Ja by som take veci osetroval uz pri vstupe:
Ak pismeno s dlznom / makcenom, tak nahrad bez znaku
Ak medzera - vynechaj zapis do pola
Potom ti uz len staci kontrolovat text.

 
Nahoru Odpovědět
16.5.2016 10:55
Avatar
ra3sk
Člen
Avatar
ra3sk:16.5.2016 11:31

ale ako?

 
Nahoru Odpovědět
16.5.2016 11:31
Avatar
Odpovídá na ra3sk
Libor Šimo (libcosenior):16.5.2016 12:40

Napríklad:

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

void bez_diakritiky(char * text)
{
    char *s   = "áäčďéíľĺňóŕšťúžý";
    char *bez = "aacdeillnorstuzy";

    int i, j;

    for (i = 0; i < strlen(text); i++) {
        for (j = 0; j < strlen(s); j++)
            text[i] = (text[i] == s[j]) ? bez[j] : text[i];
    }
}

void bez_medzier(char * text)
{
    char vysledok[40];
    int i, j = 0;

    for (i = strlen(text) - 1; i >= 0 ; i--) {
        if (text[i] != ' ') {
            vysledok[j] = text[i];
            j++;
        }
    }
    vysledok[j] = '\0';
    strcpy(text, vysledok);
}

int je_palindrom(char * text)
{
    int i, j = strlen(text) - 1;

    for (i = 0; i <= strlen(text) / 2; i++) {
        if (text[i] != text[j]) {
            printf("Nie je palindrom\n");
            return 0;
        }
        j--;
    }
    return 1;
}

int main(void)
{
    char text[] = "kobyla má malý bok";

    printf("Povodny retazec: %s\n\n", text); // kontrola
    bez_diakritiky(text);
    printf("bez diakritiky: %s\n\n", text); // kontrola
    bez_medzier(text);
    printf("bez medzier: %s\n\n", text); // kontrola
    if (je_palindrom(text))
        printf("Je to palindrom.\n");

    return 0;
}
Nahoru Odpovědět
16.5.2016 12:40
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
tomisoka
Tvůrce
Avatar
Odpovídá na Libor Šimo (libcosenior)
tomisoka:16.5.2016 14:07

Jo, to kdyby fungovalo... Ale protože znaky s diakritikou mají jinou délku než znaky bez ní (znaky ASCII se zaznamenávají jedním bytem, zatímco ostatní jsou ve více bytech), tak ti to vyhodí toto:

Povodny retazec: kobyla má malý bok

bez diakritiky: kobyla maa mala

bez medzier: alamaamalybok

Nie je palindrom

Mimochodem, je docela hnusná funkce s názvem "bez_medzier", která zároveň uloží text pozpátku...

 
Nahoru Odpovědět
16.5.2016 14:07
Avatar
Odpovídá na tomisoka
Libor Šimo (libcosenior):16.5.2016 14:29

"Jo, to kdyby fungovalo... Ale protože znaky s diakritikou mají jinou délku než znaky bez ní (znaky ASCII se zaznamenávají jedním bytem, zatímco ostatní jsou ve více bytech), tak ti to vyhodí toto:"

Mne to vypisuje normálne.

"Mimochodem, je docela hnusná funkce s názvem "bez_medzier", která zároveň uloží text pozpátku..."
Sorry, to som si ani neuvedomil, pôvodne som to myslel spraviť inakšie a ten opačný cyklus som nezmenil.

Nahoru Odpovědět
16.5.2016 14:29
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na tomisoka
Libor Šimo (libcosenior):16.5.2016 14:33

Máš pravdu so špatným výstupom.
Ja som zadal reťazec napevno v programe, ale keď sa zadá z klávesnice, nefunguje to.

Nahoru Odpovědět
16.5.2016 14:33
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na tomisoka
Libor Šimo (libcosenior):16.5.2016 15:29

Nakoniec som to vyriešil tak, že som si z klávesnice vytvoril textový súbor s písmen s diakritikou vporadí, ako som to mal pôvodne a vo funkcii: bez_diakritiky() ho načítam do reťazca *s.
Potom to už funguje korektne, aj keď text načítam z klávesnice.
Obsah súboru vyzerá exkluzívne. :-D

Nahoru Odpovědět
16.5.2016 15:29
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
ra3sk
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
ra3sk:16.5.2016 15:32

Nefunguje ani keď je to v programe.

 
Nahoru Odpovědět
16.5.2016 15:32
Avatar
ra3sk
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
ra3sk:16.5.2016 15:32

Ale musíš uznať ,že na SŠ to nie je až také ľahké.

 
Nahoru Odpovědět
16.5.2016 15:32
Avatar
Odpovídá na ra3sk
Libor Šimo (libcosenior):16.5.2016 15:40

Ale funguje, videl si môj výstup.
Na strednej škole od vás podľa nechcú riešiť diakritiku.

Nahoru Odpovědět
16.5.2016 15:40
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
tomisoka
Tvůrce
Avatar
Odpovídá na Libor Šimo (libcosenior)
tomisoka:16.5.2016 15:43

Co používáš za kódování? Ten problém co jsem popisoval se vyskytuje ve standardním UTF-8, který používá Linux a (předpokládám) Mac OS X. Pokud používáš nějakou Windows znakovou sadu, která podporuje jen 256 znaků, tak je možné obejít tento problém. Pak se ale naskytuje jiný problém: Co kdybych ti zadal ignorovat třeba i tyto znaky: Ź, Ő, Ÿ, Ǔ, Ț, Ĉ, Õ, Ȯ...

 
Nahoru Odpovědět
16.5.2016 15:43
Avatar
Odpovídá na tomisoka
Libor Šimo (libcosenior):16.5.2016 16:35

Pisal som to na windowse v code:blocks.

Nahoru Odpovědět
16.5.2016 16:35
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
ra3sk
Člen
Avatar
Odpovídá na tomisoka
ra3sk:16.5.2016 16:53

používam štandart UTF-8 na OS X

 
Nahoru Odpovědět
16.5.2016 16:53
Avatar
Odpovídá na ra3sk
Libor Šimo (libcosenior):16.5.2016 18:48

Na strednej skole?

Nahoru Odpovědět
16.5.2016 18:48
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
ra3sk
Člen
Avatar
ra3sk:16.5.2016 19:30

Áno, prečo?

 
Nahoru Odpovědět
16.5.2016 19:30
Avatar
tomisoka
Tvůrce
Avatar
Odpovídá na ra3sk
tomisoka:16.5.2016 19:42

Povedlo se mi sepsat nějaký kód, který zvládne nahrazovat znaky v UTF-8, rozhodně to není nějak výborný nebo pěkný kód, určitě by se do dalo nějak zkompresovat, ale funguje to.

#define REPLACELEN 16
void bez_diakritiky(char * text){

  char s[REPLACELEN][7]   = {"á","ä","č","ď","é","í","ľ","ĺ","ň","ó","ŕ","š","ť","ú","ž","ý"};
  char bez[REPLACELEN][7] = {"a","a","c","d","e","i","l","l","n","o","r","s","t","u","z","y"};

  int i, j, k, ps;

  char newText[1024];

  ps=0;
  for (i = 0; i < strlen(text);){
    for (j = 0; j < REPLACELEN; ++j){
      if(strncmp(s[j], text+i, strlen(s[j])) == 0)//začíná znakem s[j]
        break;
    }

    if(j>=REPLACELEN){
      newText[ps++] = text[i++];
    }else{
      for(k=0;k<strlen(bez[j]);++k, ++ps)
        newText[ps] = bez[j][k];

      i+=strlen(s[j]);
    }
  }
  newText[ps]=0;
  memcpy(text, newText, strlen(newText)+1);
}
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
16.5.2016 19:42
Avatar
ra3sk
Člen
Avatar
Odpovídá na tomisoka
ra3sk:16.5.2016 20:06

Díky. Na teba by sa mi hodil aj mail. Vždy dokážeš poradiť.

 
Nahoru Odpovědět
16.5.2016 20:06
Avatar
ra3sk
Člen
Avatar
Odpovídá na tomisoka
ra3sk:16.5.2016 20:58

Ale mohol by si mi prosim ta vysvetlit

char s[REPLACELEN][7]   = {"á","ä","č","ď","é","í","ľ","ĺ","ň","ó","ŕ","š","ť","ú","ž","ý"};
  char bez[REPLACELEN][7] = {"a","a","c","d","e","i","l","l","n","o","r","s","t","u","z","y"};

Nechapem preco su dve hranate zatvorky za sebou jedna s 16 a druha 7. Diky.

 
Nahoru Odpovědět
16.5.2016 20:58
Avatar
ra3sk
Člen
Avatar
Odpovídá na tomisoka
ra3sk:16.5.2016 21:19

A rovnako ako to je s tým ifom v tych cykloch?

 
Nahoru Odpovědět
16.5.2016 21:19
Avatar
tomisoka
Tvůrce
Avatar
Odpovídá na ra3sk
tomisoka:16.5.2016 22:21

První závorka ti určuje kolik tam bude "stringů" (používám string, protože UTF-8 znaky se nemusí vejít do jednoho char). Druhá závorka ti určuje maximální délku "stringu" - UTF-8 znak může být maximálně 6 bytů dlouhý a protože se jedná o string, tak musí být ukončen nulovým bytem - z toho vychází maximální potřebná délka na 7.
A kterej if myslíš?

 
Nahoru Odpovědět
16.5.2016 22:21
Avatar
ra3sk
Člen
Avatar
Odpovídá na tomisoka
ra3sk:16.5.2016 22:29

Už nič. A nedala by sa funkcia memcpy nahradit obycajnou funkciou na kopirovanie stringu?

 
Nahoru Odpovědět
16.5.2016 22:29
Avatar
tomisoka
Tvůrce
Avatar
Odpovídá na ra3sk
tomisoka:16.5.2016 22:42

Proč by ne. Tím memcpy prostě jen kopíruju ten string, to můžeš udělat jak chceš.

 
Nahoru Odpovědět
16.5.2016 22:42
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 31 zpráv z 31.