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

C++ C a C++ Palindróm, odstránenie dlhých písmen

Avatar
ra3sk
Člen
Avatar
ra3sk:

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. května 10:46
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na ra3sk
tomisoka:

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. května 20:55
Avatar
ra3sk
Člen
Avatar
Odpovídá na tomisoka
ra3sk:

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

 
Nahoru Odpovědět 15. května 21:55
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na ra3sk
tomisoka:

"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. května 22:29
Avatar
Odpovídá na tomisoka
Libor Šimo (libcosenior):

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

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

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. května 6:06
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
ra3sk
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
ra3sk:

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. května 6:53
Avatar
martanec
Člen
Avatar
martanec:

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. května 7:54
 
Nahoru Odpovědět 16. května 7:53
Avatar
ra3sk
Člen
Avatar
Odpovídá na martanec
ra3sk:

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. května 9:38
Avatar
Veles
Člen
Avatar
Veles:

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. května 10:55
Avatar
ra3sk
Člen
Avatar
ra3sk:

ale ako?

 
Nahoru Odpovědět 16. května 11:31
Avatar
Odpovídá na ra3sk
Libor Šimo (libcosenior):

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. května 12:40
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na Libor Šimo (libcosenior)
tomisoka:

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. května 14:07
Avatar
Odpovídá na tomisoka
Libor Šimo (libcosenior):

"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. května 14:29
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na tomisoka
Libor Šimo (libcosenior):

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. května 14:33
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na tomisoka
Libor Šimo (libcosenior):

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. května 15:29
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
ra3sk
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
ra3sk:

Nefunguje ani keď je to v programe.

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

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

 
Nahoru Odpovědět 16. května 15:32
Avatar
Odpovídá na ra3sk
Libor Šimo (libcosenior):

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. května 15:40
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na Libor Šimo (libcosenior)
tomisoka:

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. května 15:43
Avatar
Odpovídá na tomisoka
Libor Šimo (libcosenior):

Pisal som to na windowse v code:blocks.

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

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

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

Áno, prečo?

 
Nahoru Odpovědět 16. května 19:30
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na ra3sk
tomisoka:

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í
+1 bodů
Řešení problému
 
Nahoru Odpovědět 16. května 19:42
Avatar
ra3sk
Člen
Avatar
Odpovídá na tomisoka
ra3sk:

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

 
Nahoru Odpovědět 16. května 20:06
Avatar
ra3sk
Člen
Avatar
Odpovídá na tomisoka
ra3sk:

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. května 20:58
Avatar
ra3sk
Člen
Avatar
Odpovídá na tomisoka
ra3sk:

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

 
Nahoru Odpovědět 16. května 21:19
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na ra3sk
tomisoka:

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. května 22:21
Avatar
ra3sk
Člen
Avatar
Odpovídá na tomisoka
ra3sk:

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

 
Nahoru Odpovědět 16. května 22:29
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na ra3sk
tomisoka:

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

 
Nahoru Odpovědět 16. května 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.