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.
Člen
Zobrazeno 31 zpráv z 31.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
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.
"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.
Palindrom je veta, slovo alebo cislo, ktore je rovnake od predu aj
odzadu.
Matej je tam
kolok
1234321
Pismen s diakritikou sa zbavis tak, ze v retazci nechas len pismena bez
diakritiky.
Teda, kontrolujes ho na znaky a - z A - Z.
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?
Mal som ten istý nápad a dal som to do switchu, ale dostal som error, ze 'á' nie je charakter.
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;
}
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...
"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.
Máš pravdu so špatným výstupom.
Ja som zadal reťazec napevno v programe, ale keď sa zadá z klávesnice,
nefunguje to.
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.
Ale musíš uznať ,že na SŠ to nie je až také ľahké.
Ale funguje, videl si môj výstup.
Na strednej škole od vás podľa nechcú riešiť diakritiku.
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: Ź, Ő, Ÿ, Ǔ, Ț, Ĉ, Õ, Ȯ...
Pisal som to na windowse v code:blocks.
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);
}
Díky. Na teba by sa mi hodil aj mail. Vždy dokážeš poradiť.
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.
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íš?
Už nič. A nedala by sa funkcia memcpy nahradit obycajnou funkciou na kopirovanie stringu?
Proč by ne. Tím memcpy prostě jen kopíruju ten string, to můžeš udělat jak chceš.
Zobrazeno 31 zpráv z 31.