Zaloguj się, aby obserwować  
Bartuc

Język C / C++ / C# / Java - pytania, problemy...

1979 postów w tym temacie

Dnia 24.10.2007 o 21:24, logray napisał:

po pierwsze pętla z jednym średnikiem się nie skompiluje. zawsze muszą być dwa.

Jestem początkujący, dlatego wielu rzeczy nie wiem (ale naprawdę program czasami kompiluje się bez problemu kiedy w pętli nie ma średników).

Dnia 24.10.2007 o 21:24, logray napisał:

Po drugie na przykładzie pierwszej pętli:
for(d!=0;d--;)
Ten kod będzie się wykonywał dopóty dopóki d-- nie osiągnie 0.

O to właśnie chodziło :)

Po dłuższym namyśle program zrobiłem i, nie chwaląc się, uważam go za dość sprytny ;)

#include<cstdio>
using namespace std;
int main()
{
int a,b,x;
x=1;
scanf("%d %d",&a,&b);
a=a%10;
for(;b>0;)
{
if(b%2==1)
{x=x*a;
x=x%10;
b=b/2;
a=a*a;
a=a%10;}
else {b=b/2;
a=a*a;
a=a%10;;}
}
printf("%d\n", x);
return 0;
}

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 25.10.2007 o 17:51, Bimbermistrz napisał:

> for(d!=0;d--;)
> Ten kod będzie się wykonywał dopóty dopóki d-- nie osiągnie 0.
O to właśnie chodziło :)

Z pętli jest jeszcze while i do while. Poczytaj sobie zwłaszcza o while. W Twoim kodzie będzie wyglądało ładniej od for.
Druga sprawa to linie typu x=x*a. Można to też zapisać tak: x*=a. Analogicznie jest dla %, /, +, - i kilku innych Poczytaj sobie o operatorach.

Dobry pomysł z tą optymalizacją.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 25.10.2007 o 20:45, logray napisał:

Z pętli jest jeszcze while i do while. Poczytaj sobie zwłaszcza o while. W Twoim kodzie będzie
wyglądało ładniej od for.

Wiem, czasami używam while''a.

Dnia 25.10.2007 o 20:45, logray napisał:

Druga sprawa to linie typu x=x*a. Można to też zapisać tak: x*=a. Analogicznie jest dla %,
/, +, - i kilku innych Poczytaj sobie o operatorach.

Napisałem w tamtej postaci, bo jest to dla mnie bardziej czytelne :)
---
Niestety, mam kolejny problem :/
Mam wysłać na Spoja rozwiązanie zadania "Szyfr Cezara". Otóż za każdym razem wyskakuje mi przekroczenie limitu czasu, a ja nie mam pojęcia, jak można skrócić czas działania tego programu (scanf''ów nie używałem, bo wywołują problemy ze stringami).

#include <iostream>
#include <string>
using namespace std;
int main()
{int j=0;
string str1;
do
{
cin >> str1;
while(j<str1.length())
{
if(str1[j]==' ')
{str1[j] = ' ';}
else if(str1[j]<'X')
{str1[j] = int(str1[j]) + 3;}
else if(str1[j]=='X')
{str1[j] = 'A';}
else if(str1[j]=='Y')
{str1[j] = 'B';}
else if(str1=='Z')
{str1[j] = 'C';}
i++;
}
cout << str1 << endl;
j=0;
string str1;
}
while(str1[j]!='\n');
return 0;
}

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Nie zdążyłem w pełni wyedytować posta :/ (Wszystko przez kursywę.) Tutaj jest poprawny kod:

#include <iostream>
#include <string>
using namespace std;
int main()
{int j=0;
string str1;
do
{
cin >> str1;
while(j<str1.length())
{
if(str1[j]=='' '')
{str1[j] = '' '';}
else if(str1[j]<''X'')
{str1[j] = int(str1[j]) + 3;}
else if(str1[j]==''X'')
{str1[j] = ''A'';}
else if(str1[j]==''Y'')
{str1[j] = ''B'';}
else if(str1[j]==''Z'')
{str1[j] = ''C'';}
j++;
}
cout << str1 << endl;
j=0;
string str1;
}
while(str1[j]!=''\n'');
return 0;
}

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 27.10.2007 o 14:22, Bimbermistrz napisał:

Nie zdążyłem w pełni wyedytować posta :/ (Wszystko przez kursywę.) Tutaj jest poprawny kod:

(...)


warunek: while(str1[j]!=''\n'')
Nigdy nie będzie prawdziwy: cin >> str1 nigdy nie wprowadzi do stringa znaku białej spacji (z tego samego powodu warunek (str1[j]=='' '') nie ma żadnego sensu). Jest jeszcze parę niezrozumiałych rzeczy w Twoim kodzie (redefinicja string str1?), a całość można by było zrobić troszkę bardziej czytelnie, prościej i tak, by wielkość liter nie miała znaczenia (u Ciebie ma).

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 25.10.2007 o 17:51, Bimbermistrz napisał:

Po dłuższym namyśle program zrobiłem i, nie chwaląc się, uważam go za dość sprytny ;)
(...)


Fajne, ale jak już świrujemy z optymalizacją to może świrujmy na maksa? Niestety różnica w prędkości jest tak śmieszna że nawet nie mogę jej uchwycić na moim kompie, ale podejrzewam, że w 100% przypadków poniższe jest szybsze:

inline int jednosc(int a, int b) {
static const unsigned char square [] = {0,1,4,9,6,5,6,9,4,1};
a %= 10;
switch(b = b > 4 ? (b - 1) % 4 + 1 : b) {
case 0: return 1;
case 1: return a;
case 2: return square[a];
case 3: return a * square[a] % 10;
default: return square[a * a % 10];
}
}

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Poddałem program krótkiej przeróbce, ale nadal nie chce zaliczyć (tym razem błędna odpowiedź).

#include <iostream>
#include <string>
using namespace std;

int main()
{int j=0;
string str1;
getline(cin,str1);
while(j<str1.length ())
{
if(str1[j]>=''A'' && str1[j]<=''Z'')
{
if(str1[j]<''X'')
{str1[j] = int(str1[j]) + 3;}
else if(str1[j]==''X'')
{str1[j] = ''A'';}
else if(str1[j]==''Y'')
{str1[j] = ''B'';}
else if(str1[j]==''Z'')
{str1[j] = ''C'';}
}
else {str1[j]='' '';}
j++;
}
cout << str1<<endl;
return 0;
}

Link do treści zadania --> https://www.spoj.pl/problems/JSZYCER/

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 28.10.2007 o 13:42, Bimbermistrz napisał:

Poddałem program krótkiej przeróbce, ale nadal nie chce zaliczyć (tym razem błędna odpowiedź).

(...)


I nic dziwnego: getline kończy wczytywanie znaku na pierwszym napotkanym znaku nowej linii (domyślnie). Czyli jak tylko skończysz wczytywać "ABC DEF" (z przykładu), program drukuje zaszyfrowany tekst i kończy działanie. Można oczywiście zapętlić getline, by wczytywać wszystkie linie dopóki jest co wczytywać (tylko ostrożnie - trzeba jeszcze badać długość stringa, bo bez tego można wciskać ENTER do jutra a getline wciąż będzie miał co robić), ale wtedy w tej samej pętli trzeba by wyświetlić wynik (cout << str1 << endl;), co też nie jest do końca dobre, bo (wnioskując z treści zadania) wynik powinien zostać wyświetlony tylko RAZ: na końcu i ma zawierać cały przetłumaczony string. Moja propozycja - badać wejście znak po znaku (cin.get(ch)) lub linia po linii (getline(cin,buf)) i zapisywać wynik na bieżąco w buforze (typu string). Po zakończeniu pętli (kiedy nie ma już czego czytać z wejścia) wystarczy wypluć zapisany bufor :)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Jednak nie trzeba było używać bufora (program miał wczytać linię tekstu, a po przejściu do nowej linii wyświetlić zaszyfrowany tekst i ponownie przejść do nowej linii w celu wpisania kolejnej linii do zaszyfrowania). Zaakceptowało mi ten program, kiedy zamiast stringów użyłem getchar''ów i uwzględniłem EOF.
---
Mam jednak kolejny problem (program, który oblicza NWW n podanych liczb, przy czym liczby jak i wynik nie przekraczają zakresu 2^64 - 1).
Zakres 2^64 - 1 odpowiada long long int''om (z tego co wyczytałem). Dlaczego więc program po skompilowaniu i tak nie działa dla większych liczb?

#include<cstdio>
using namespace std;
int main ()
{
int n;
scanf("%d",&n);
unsigned long long int tab[n];
int j=1;
unsigned long long int a,b,c;
scanf("%d",&tab[0]);
for(;j<n;j++)
{
scanf("%d",&tab[j]);

if(tab[j]>tab[j-1])
{a=tab[j];
b=tab[j-1];}
else {a=tab[j-1];
b=tab[j];}
for(;b!=0;)
{c=a%b;
a=b;
b=c;}
tab[j]=tab[j]/a;
tab[j]=tab[j]*tab[j-1];
}
j--;
printf("%d\n",tab[j]);
return 0;
}

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Kto wie jak napisać program w c++ który przeliczałby podaną przez użytkownika liczbę z systemu binarnego na system szesnastkowy (albo chociaż dziesiętny)? Miałem takie zadanie domowe, ale nie mam zielonego pojęcia jak to zrobić. Z dziesiętnego na dwójkowy zrobiłem, z dziesiętnego na szesnatkowy też, ( chociaż nieco ograniczony ;)). Natomiast do tego co mam zrobić to nijak nie wiem jak sie mam zabrać...

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

dwójkowy -> dziesiętny

1. wczytujesz ciąg do tablicy
2. sumujesz od końca ciągu wartości komórek z wagą 2^i, gdzie i = 0, 1, 2...
3. wypisujesz wynik


dwójkowy -> szesnastkowy

1. wczytujesz ciąg do tablicy
2. sumujesz od końca ciągu wartości komórek z wagami jak wyżej, tyle że w paczkach po 4 komórki i dla każdej paczki wagi zaczynają się od 2^0. wpisujesz wynik sumowania elementów każdej paczki już w kodzie szesnastkowym do kolejnej wolnej komórki wcześniej utworzonej tablicy char.
3. wypisujesz zawartość tablicy char od końca

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

jak sprawdzić czy dana liczba we w floacie jest całkowita?

Myślałem o czymś takim:

...
float a;
int b=(int)a;
cin>>a;

if (a-b==0) to cośtam;
else zrób cośtam;
...
ale nie działa, wcześniej wpadłem jeszcze na coś takiego:
...
if (a!=(int)a) cout<<cośtam;
else if (a=(int)a) cout<<cośtam;
...
ale też dupa... w obydwu przypadkach program nawet jak podaje całkowitą to wybieta 'else'
Pomóżcie!

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 26.11.2007 o 18:37, Klimos napisał:

A może użyć funkcji modf() dzielącej podaną liczbę na część całkowitą i ułamkową?
Szczegóły: http://www.cplusplus.com/reference/clibrary/cmath/modf.html


ale jak ją wykorzystać do sprawdzenia czy liczba jest całkowita? bo potrzebuję zrobić program obliczający sufit i podłogę z podanej liczby, nie używając ceil''a i floor''a. Niby proste, wystarczy kilka if''ów, ale tego jednego nie wiem jak zrobić

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 26.11.2007 o 18:45, misioo napisał:

/.../


Jeżeli liczba jest całkowita to funkcja powinna zwrócić zero (według tego co napisano pod linkiem, który podałem).
Poza tym, przy zwykłym rzutowaniu: y = (int) x, gdzie y jest int a x to float, część ułamkowa jest po prostu obcinana. Zatem jeżeli x>0, rzutujesz na int i masz floor, dodajesz jeden masz ceil. Jeżeli x<0 po rzutowaniu masz ceil a jak od tego odejmiesz jeden otrzymujesz floor.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 26.11.2007 o 19:01, Klimos napisał:

> /.../

Jeżeli liczba jest całkowita to funkcja powinna zwrócić zero (według tego co napisano pod linkiem,
który podałem).
Poza tym, przy zwykłym rzutowaniu: y = (int) x, gdzie y jest int a x to float, część ułamkowa
jest po prostu obcinana. Zatem jeżeli x>0, rzutujesz na int i masz floor, dodajesz jeden
masz ceil. Jeżeli x<0 po rzutowaniu masz ceil a jak od tego odejmiesz jeden otrzymujesz
floor.

tak, ale przy liczbach całkowitych ma nic nie dodawać ani nic nie odejmować.
ale dzięki za pomoc

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

hehe... ja się ostatnio uśmiałem na konkursie z informatyki (3 gimnazjum). Stawiałem na wiedzę informatyczną a tam... programowanie w Pascalu... i jak głupi 3h siedziałem:P I tak sobie myślę, dlaczego w podstawie programowej nie miałem o tym nic a nic? A kółko informatyczne, na które chodze jest bardziej kronikarskie... I zastanawiam się czy się nie zacząć bawić, ale chyba jednka z tym poczekam do liceum...

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

A nie da się sprawdzić po prostu czy liczba da się podzielić przez 2 a wynik z dzielenia będzie liczbą całkowitą? Wtedy będzie wiadomo czy dana liczba jest całkowita czy ułamkowa.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Utwórz konto lub zaloguj się, aby skomentować

Musisz być użytkownikiem, aby dodać komentarz

Utwórz konto

Zarejestruj nowe konto na forum. To jest łatwe!


Zarejestruj nowe konto

Zaloguj się

Masz już konto? Zaloguj się.


Zaloguj się
Zaloguj się, aby obserwować