Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno c-priklad prvre vacsie sumerne cislo od zadaneho cisla

Ahoj ako uz nadpis napoveda ide o program ktory po zadani lubovolneho cisla (do 10 cifier) najde prve vacsie sumerne cislo od zadaneho teda ja napr. zadam 1440 a napise mi to 1441. Neviete kde mozem mat chybu mam do odovzdania zadania malo casu a dnes mi to nejako nemysli prosim poradte

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

//Vytvorte program, ktorý po zadaní prirodzeného èísla "n" nájde prvé, od neho väèšie "súmerné" èíslo,
//t.j. èíslo, ktoré je z obidvoch strán (spredu aj zozadu ) rovnaké!
//Napr. pre n=144 je súmerné èíslo 151
int main()
{
    const int MAX=999999;
    const int POCET=10;
    int cifry_pole[POCET];
    int cislo=0;
    int vacsie_cislo=0;
    int cifry=0;
    int i=0;

    printf("Zadaj prirodzene cislo maximalne 10 ciferne: ");
    scanf("%d",&cislo);

    vacsie_cislo=cislo;

    while(vacsie_cislo<MAX)
    {
        vacsie_cislo++;

        for(i=0;vacsie_cislo>0;i++,cifry++)
        {
            cifry_pole[i]=vacsie_cislo%10;
            vacsie_cislo/=10;
            printf("%d\n",cifry_pole[i]);
        }

        for(i=0;i>cifry;i++,cifry--)
        {
            if(cifry_pole[i]==cifry_pole[cifry])
            {
                printf("Vacsie sumerne cislo od zadaneho je: %d",vacsie_cislo);
                return 0;
            }
        }
    }
    return 0;
}
Předmět Autor Datum
vacsie_cislo/=10; Tohle vacsie_cislo bys měl pouze zvyšovat o jedničky.
Wikan 19.11.2013 17:57
Wikan
V c-neprogramujem, preto Ti chybu hľadať nebudem, ale zaujal ma tento príklad. :-) Myšlienka ako by…
pme 19.11.2013 19:10
pme
Já bych to naopak řešil stále jako čísla, když už jde o čísla. A vynechal bych i to pole pro ukládán…
Wikan 19.11.2013 19:12
Wikan
Asi áno..., mne sa v Delphi dá lepšie/jednoduhšie otočiť-porovnávať string... function IsPalindrome…
pme 19.11.2013 19:18
pme
porovnavat deplhi a C chce vela odvahy :D
wam_Spider007 19.11.2013 20:33
wam_Spider007
Nikto nič neporovnáva... Hlavne, že delphi píšeš s malým "d" a C s veľkým "C" - asi si chcel vyzdvih…
pme 19.11.2013 20:43
pme
milujem taketo dedukcie. ja z lenivosti pisem na kompe vsetko malym a bez diakritiky (pokial nejde o…
wam_Spider007 19.11.2013 21:04
wam_Spider007
No dobre. Hneváš sa? :-)
pme 19.11.2013 21:05
pme
to urcite nie :-) ... a ty? :-)
wam_Spider007 19.11.2013 21:18
wam_Spider007
Jednodušší možná. V C# bych to viděl takhle: var number = int.Parse(Console.ReadLine()); while (tru…
Wikan 19.11.2013 20:34
Wikan
No uz to vyzera lepsie ked dam 120 tak mi to 121 najde :D ale pri takych dalej od vysledku to hlada…
parker 19.11.2013 20:02
parker
vyhod vsetky zbytocne printf z cyklov a pojde to milionkrat rychlejsie
MM.. 19.11.2013 20:04
MM..
o to nejde ide to dost rychlo dam nie 120 ale 119 a hlada a hlada ... podlamna 3ciferne cislo by to…
parker 19.11.2013 20:06
parker
while(delitel>0) { cifry[++i]=delitel%10; delitel/=10; } - neinicializoval si i (pre dalsie prechod…
MM.. 19.11.2013 20:08
MM..
a to "j<=i/2" musi ostat ako <= pretoze to musi ist az po prostrednu cifru ak je pocet cifier neparn…
MM.. 19.11.2013 20:13
MM..
ok spravil som to podla teba ako si napisal poskusal som zjednodusil printf dal prec no ostalo mi to…
parker 19.11.2013 20:22
parker
Stejna vec jak pre i plati aj pre premennu vysledok. Nauc sa nespoliehat na nejake defaultne hodnoty…
MM.. 19.11.2013 20:27
MM..
A nezmenil si to k=i na k=i-1 pristupujes mimo pola
MM.. 19.11.2013 20:29
MM..
A este by som zmenil aj to j<=i/2 na j<i/2 Dovod: ak by i bolo 0, tak by si s tym k=i-1 pristupoval…
MM.. 19.11.2013 20:33
MM..
A este uplne nakoniec ked chces vediet jak by som ten test napisal ja (lebo som spravne lenivy :D) t…
MM.. 19.11.2013 20:36
MM..
resp. este malicka uprava, takto by som to napisal, je to citatelnejsie: for(j=0;j<i/2;j++) if(cifr…
MM.. 19.11.2013 20:44
MM..
A este aj v tom for(i=0; delitel<0; delitel/=10) mas to delitel<0 naopak. Ja som pisal delitel>0
MM.. 19.11.2013 20:41
MM..
uz viem kde je chyba tie cifry tam sa uklada cim dalej tym viac prvkov pola. ako spravim aby som cel…
parker 19.11.2013 20:43
parker
Netrep kraviny. Ty snad vobec nechapes co robis. Este ani copy-paste nezvladas.
MM.. 19.11.2013 20:44
MM..
Si tie moje zmeny asi vobec neskompiloval. To bol tvoj povodny problem s i.
MM.. 19.11.2013 20:45
MM..
Ano mas pravdu i som tam nakonci cyklu zabudol dat na povodnu hodnotu aj ten vysledok bol treba tak…
parker 19.11.2013 21:22
parker
Len tam radsej nechaj to tvoje while namiesto mojho for, lebo ucitel to moje for nemusi pochopit :-)…
MM.. 19.11.2013 21:25
MM..
V Javě to jde celkem rychle: static void pocitej(int startNum) { startNum++; if (Objects.equals(""…
MaSo 20.11.2013 11:04
MaSo
já bych to řešil textově. rozdělit podle počtu číslic na sudá a lichá. U lichých "vynechat" prostře…
touchwood 20.11.2013 12:55
touchwood
"Trochu" efektívnejšia verzia: #include <stdio.h> #include <stdlib.h> #include <string.h> int main(…
los 20.11.2013 20:06
los
Omg. Nějak moc ḱódu, né? :-) poslední
MaSo 21.11.2013 09:44
MaSo

V c-neprogramujem, preto Ti chybu hľadať nebudem, ale zaujal ma tento príklad. :-)

Myšlienka ako by som to riešil ja:
Keďže sa jedná o Palindrome - môže to byť slovo, fráza, číslo, postupnosť znakov..., ktoré musí byť interpretované rovnako z obidvoch strán, tzn. aj z predu aj zo zadu, riešil by som to porovnávaním ako text-string.

Náčrt pre pochopenie:
Zadané číslo napr. 139 zvýšim o jedničku, tzn. bude z toho 140. Toto číslo prevediem na text a porovnám ho s otočeným textom odzadu

140 otočím, dostanem 041, porovnám text: 140 <> 041 nezhoduje sa, idem ďalej - zvýšim číslo (140) o jedničku, dostanem 141
141 otočím, dostanem 141, porovnám text: 141 = 141- mám výsledok - končím...

tento jednoduchý algoritmus sa dá krásne rozložiť do malých celkov a testovať v cykle napr. while do...

Jednodušší možná. V C# bych to viděl takhle:

var number = int.Parse(Console.ReadLine());

while (true)
{
    number++;
	
    var num = number;
    var rev = 0;
	
    while(num > 0)
    {
        var cipher = num % 10;
	rev = 10 * rev + cipher;
	num /= 10;
    }
	
    if (number == rev)
    {
        Console.WriteLine(number);
	break;
    }
}

No uz to vyzera lepsie ked dam 120 tak mi to 121 najde :D ale pri takych dalej od vysledku to hlada a hlada

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

int main()
{
    unsigned int cislo; //skumane cislo
    unsigned int cifry[10]; //pole cifier
    int i=-1; //počítadlo cifier
    int j,k;    //počítadlá do for
    typedef enum {NIE,ANO} v;
    int vysledok=ANO; //označuje, či je sumerne
    int vacsie_cislo;
    int delitel;

    printf("Zadaj cislo (max. 10 cifier):");
    scanf("%d",&cislo);
    vacsie_cislo=cislo;

    while(cislo<999999)
    {
        vacsie_cislo++;
        delitel=vacsie_cislo;

        while(delitel>0)
        {
            cifry[++i]=delitel%10;
            delitel/=10;
        }
        printf("Cifry:\n");
        for(j=0;j<=i;j++)
        {
            printf("%d ",cifry[j]);
        }
        for(j=0,k=i;j<=i/2;++j,--k)
        {
            if(cifry[j]==cifry[k])
            {
                printf("\n%d = %d",cifry[j],cifry[k]);
            }
            else
            {
                printf("\n%d != %d",cifry[j],cifry[k]);
                vysledok=NIE;
            }
        }
        if(vysledok==ANO)
        {
            printf("%\d",vacsie_cislo);
            return 0;
        }
    }
}

while(delitel>0)
{
cifry[++i]=delitel%10;
delitel/=10;
}

- neinicializoval si i (pre dalsie prechody cyklom!). A ta inicializacia na -1 je tiez dementna. Normalne sa to robi
i=0;
while(delitel>0)
{
cifry[i++]=delitel%10;
delitel/=10;
}

ja kedze som spravne lenivy by som to napisal takto:
for(i=0; delitel>0; delitel/=10)
cifry[i++]=delitel%10;

P.S. a potom samozrejme zmenit vsetky nasledne testy oproti i, z <=i na <i, a priradenie k=i-1 pretoze tak je to logicke v C (0-based index) a i je pocet cifier.

ok spravil som to podla teba ako si napisal poskusal som zjednodusil printf dal prec no ostalo mi toto ale stale tam je ta vada :D 120 mi ide ale napr 149 nic

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

int main()
{
    unsigned int cislo=0; //skumane cislo
    unsigned int cifry[10]; //pole cifier
    int i=0; //počítadlo cifier
    int j,k;    //počítadlá do for
    typedef enum {NIE,ANO} v;
    int vysledok=ANO; //označuje, či je sumerne
    int vacsie_cislo;
    int delitel;

    printf("Zadaj cislo (max. 10 cifier):");
    scanf("%d",&cislo);
    vacsie_cislo=cislo;

    while(cislo<999999)
    {
        vacsie_cislo++;
        delitel=vacsie_cislo;

        for(i=0; delitel<0; delitel/=10)
        {
            cifry[i++]=delitel%10;
        }
        for(j=0,k=i;j<=i/2;j++,k--)
        {
            if(cifry[j]!=cifry[k])
            {
                vysledok=NIE;
            }
        }
        if(vysledok==ANO)
        {
            printf("\n%d",vacsie_cislo);
            return 0;
        }
    }
}

A este by som zmenil aj to j<=i/2 na j<i/2
Dovod: ak by i bolo 0, tak by si s tym k=i-1 pristupoval na neplatnu adresu co by malo za nasledok exception a zavretie aplikacie windowsami. Pri i=0 bude j<i/2 neplatne takze nebudes nikam pristupovat.
Ked robis taketo veci vzdy sa snaz okamzite mysliet aj na hranicne hodnoty ktore tam mozu nastat, a aby si za ziadnych okolnosti nepristupoval niekam mimo pole (v pripade potreby davat dalsie if)

A este uplne nakoniec ked chces vediet jak by som ten test napisal ja (lebo som spravne lenivy :D) tak uplne bez premennej vysledok:

for(j=0,k=i-1;j<i/2;j++,k--)
 if(cifry[j]!=cifry[k])
  break;
if(j>=i/2)
{
 printf("\n%d",vacsie_cislo);
 break;
}

ako bonbonik je ze funguje to spravne aj pre jednociferne cisla (jednociferne je tiez symetricke :)

Len tam radsej nechaj to tvoje while namiesto mojho for, lebo ucitel to moje for nemusi pochopit :-)

V podstate mozes zobrat tvoj povodny program z dotazu, a opravit len to co pisal wikan, a potom len pridat 2 riadky na spravne miesta v cykle alebo na zaciatok cyklu
i = -1;
vysledok = ANO;
a musi to fungovat tiez.
P.S. aha sorry ne, v dotaze si toho mal blbo viac. Nechaj to uz tak. Pripadne zmen to moje for zas na tvoje while

já bych to řešil textově.

rozdělit podle počtu číslic na sudá a lichá. U lichých "vynechat" prostřední a v obráceném gardu sepsat číslice zleva doprava. V podstatě jeden if a pak už jen otročina.

obecně:

pocet = zjisti_počet znaků (string)
if pocet mod 2 = 0
   then vystup = substring (1, pocet div 2, string) #sebere prvni pulku (od prvniho znaku)
   else vystup = substring(1, pocet div 2 + 1, string)  #sebere prvni pulku a prostřední znak
endif 
for i in (pocet div 2) to 1 do 
     vystup = vystup + substring (i, 1, string)  #zpetne prida po znaku levou stranu
next
   

edit: místo IFu se dá použít dělení reálných čísel a zaokrouhlení.

edit2: nepochopil jsem zadání. ignorujte. :-)

"Trochu" efektívnejšia verzia:

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

int main() {
	char number[11], buffer[6];
	int len, size, index, left, leftRev, right;

	printf("Zadaj cislo (max. 10 cifier): ");
	fgets(number, 11, stdin);
	len = strlen(number);
	if (number[len - 1] == '\n')
		number[--len] = 0;
	size = (len + 1) / 2;
	index = len / 2;
	buffer[size] = 0;
	strncpy(buffer, number + index, size);
	right = atoi(buffer);
	strncpy(buffer, number, size);
	left = atoi(buffer);
	strrev(buffer);
	leftRev = atoi(buffer);
	if (right >= leftRev) {
		left++;
		itoa(left, number, 10);
		itoa(left, number + index, 10);
		strrev(number + index);
	} else
		strncpy(number + index, buffer, size);
	printf("%s\n", number);
	return 0;
}

Zpět do poradny Odpovědět na původní otázku Nahoru