Zaloguj się, aby obserwować  
Bartuc

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

1979 postów w tym temacie

Dnia 12.01.2008 o 15:58, Bimbermistrz napisał:

Czy jest jakiś szybki sposób na znalezienie wszystkich dzielników danej liczby (rzędu do połowy
miliona)? Sposób z wyszukiwaniem ich po kolei (sprawdzaniem kolejnych liczb od 2 do połowy
wartości liczby) nie jest raczej dobry.


Nie musisz szukać do połowy ;] Szukanie dzielników ma to do siebie, że na raz znajdujemy dwa - więc jeśli idąc od 1 będziesz odkładał na stos z dodatkową możliwością podejrzenia elementu na wierzchu, najpierw mniejszy z dzielników, a potem jego większego brata, to wystarczy, że będziesz szedł pętlą for (int i=1; i < stos.top(); i++) {...}. Powinno to już pozwolić zbić złożoność obliczeniową z O(n). Ja żadnego bardziej zaawansowanego algorytmu nie znam.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

hej.. pomożesz mi ?
chce napisac w programie TCLITE program :

który zczyta mi tekst który ja napisze i np :
1. powie mi czy z duzej czy z małej zaczołem litery
2. napisze mi przedostatnią litere z tekstu

bardzo bym był wdzięczny jakbyś napisał mi.. miałem z tego kolokwium i poległem :/

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Zobaczę co sa się zrobić, ale mam wcześniej pytanie, żeby przez przypadek nie napisać zbyt długiego niż trzeba.
Czy tekst może zawierać znaki inne niż liter i jeśli tak, to czy dla pytania:
1. w przypadku w którym tekst nie zaczynał się literą tylko innym znakiem, ma znaleźć pierwszą literę w napisie czy może wyświetlić komunikat, że pierwszy znak napisu nie jest literą.
2. ma wypisać być przedostatnią literę, czy przedostatni znak.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 12.01.2008 o 16:25, Chester001 napisał:

który zczyta mi tekst który ja napisze i np :
1. powie mi czy z duzej czy z małej zaczołem litery
2. napisze mi przedostatnią litere z tekstu


#include <string>
#include <iostream>

using namespace std;
#define MAX_INT 32767
#define EXIT_SUCCESS 0

int main(int argc, char** argv)
{
string tekst;
bool duzalitera = true;

do
{
cout << "Podaj tekst\n";
cin.clear(); cin >> tekst;
}while (!cin);

switch(tekst[0])
{
case ''ą'': case ''ć'': case ''ę'': case ''ł'': case ''ń'':
case ''ó'': case ''ś'': case ''ź'': case ''ż'':
duzalitera = false; //mała polska litera
default:
if(tekst[0] >= ''a'' && tekst[0] <= ''z'') //czy mała litera w kodzie ASCII
duzalitera = false;
}
cout << "Zaczęto z " << (duzalitera ? "dużej": "małej") << " litery.\n";

if( tekst.length() >= 2)
cout << "Przedostatnia litera to: " << tekst[tekst.length()- 2];
else
cout << "Nie ma przedostatniej litery bo tekst był zbyt krótki";
cout << endl;

cin.get();
return (EXIT_SUCCESS);
}

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Dla współczesnego kompilatora c++ to prawie zadziała, prawie, bo:
1. Program napisze, że tekst "1123" zaczyna się z dużej litery, a to niekoniecznie prawda.
2. A dla napisu co w przykładzie wyżej napisze, że przedostatnią literą jest 2, a niekoniecznie (nie wiemy z polecenia) litera == znak.

Ale jak kolega napisał, pracuje na TCLITE, a to jest stare, brzydkie i jeszcze z czasów samego C. I tam ten program się nie skompiluje, choćby tylko dlatego, że tamta biblioteka string (przy czym zakładając, że będzie dołączana jako string.h) to odpowiednik współczesnej cstring.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 12.01.2008 o 18:00, vBoguSv napisał:

Dla współczesnego kompilatora c++ to prawie zadziała, prawie, bo:
1. Program napisze, że tekst "1123" zaczyna się z dużej litery, a to niekoniecznie prawda.
2. A dla napisu co w przykładzie wyżej napisze, że przedostatnią literą jest 2, a niekoniecznie
(nie wiemy z polecenia) litera == znak.

Ale jak kolega napisał, pracuje na TCLITE, a to jest stare, brzydkie i jeszcze z czasów samego
C. I tam ten program się nie skompiluje, choćby tylko dlatego, że tamta biblioteka string (przy
czym zakładając, że będzie dołączana jako string.h) to odpowiednik współczesnej cstring.

wiesz co..
mozesz mi po rostu napisac jaką komędą ja moge zczytywac tekst
co jest potrzebne aby PC mi powiedział czy z duzej czy z małej zaczynam...
oraz co musze zrobic aby mi wypisał przed ostatnią / lub ostatnią literke w tekscie patrze na ten praogram i dziwne komędy moderator tam stosuje ... :/ nie rozumiem :/

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 12.01.2008 o 18:36, Chester001 napisał:

mozesz mi po rostu napisac jaką komędą ja moge zczytywac tekst

cin >>

Dnia 12.01.2008 o 18:36, Chester001 napisał:

co jest potrzebne aby PC mi powiedział czy z duzej czy z małej zaczynam...

Sprawdzenie, czy pierwszy znak w tekście należy do zbioru liter od a do z lub małych polskich liter, czy też od A do Z lub wielkich polskich liter.

Dnia 12.01.2008 o 18:36, Chester001 napisał:

oraz co musze zrobic aby mi wypisał przed ostatnią / lub ostatnią literke w tekscie patrze
na ten praogram i dziwne komędy moderator tam stosuje ... :/ nie rozumiem :/

Odczytać długość łańcucha, do którego zapisany jest tekst i skorzystać z niej jako odpowiednio zmodyfikowanej pozycji w tym łańcuchu.

Najlepiej sam zacznij pisać ten program i zamieść kod, który w razie potrzeby będzie poprawiany.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 12.01.2008 o 19:04, Treant napisał:

> mozesz mi po rostu napisac jaką komędą ja moge zczytywac tekst
cin >>
> co jest potrzebne aby PC mi powiedział czy z duzej czy z małej zaczynam...
Sprawdzenie, czy pierwszy znak w tekście należy do zbioru liter od a do z lub małych polskich
liter, czy też od A do Z lub wielkich polskich liter.
> oraz co musze zrobic aby mi wypisał przed ostatnią / lub ostatnią literke w tekscie patrze

> na ten praogram i dziwne komędy moderator tam stosuje ... :/ nie rozumiem :/
Odczytać długość łańcucha, do którego zapisany jest tekst i skorzystać z niej jako odpowiednio
zmodyfikowanej pozycji w tym łańcuchu.

Najlepiej sam zacznij pisać ten program i zamieść kod, który w razie potrzeby będzie poprawiany.

wiesz to co napisałes mi to ja sam wiem.. ja nie wiem jakie i co mam pisac dokładnie.... o to chodzi :/

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Treant dobrze ci radzi, ale tekst (jeśli ma zawierać białe znaki, a nie być jednym wyrazem) wczytuj jednak poleceniami cin.get(napis, dlugosc_napisu, znak_konczacy); lub cin.getline(napis, dlugosc_napisu, znak_konczacy);
gdzie:
napis - to nazwa tablicy znakowej w której chcesz mieć napis.
dlugosc_napisu - to maksymalna długość napisu, czyli najprawdopodobniej wielkość twojej tablicy
znak kończący - to znak, po którego pierwszym odnalezieniu program skończy wczytywanie napisu np. ''\n'' - to znak nowej linii, ale też możesz kończyć po kropce, spacji, przecinku czym tam potrzebujesz.
A get() od getline() różni się tym, że get() nie dołącza znaku kończącego do wczytywanego tekstu, a getline() tak

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 12.01.2008 o 18:00, vBoguSv napisał:

Dla współczesnego kompilatora c++ to prawie zadziała, prawie, bo:
1. Program napisze, że tekst "1123" zaczyna się z dużej litery, a to niekoniecznie prawda.

A fakt, brakuje jeszcze jednego warunku sprawdzającego. Gdyby jednak wpisywać cyfry lub inne znaki niż litery (= tekst), to program nie ma sensu i w ogóle nie powinien przyjmować takich łańcuchów.

Dnia 12.01.2008 o 18:00, vBoguSv napisał:

Ale jak kolega napisał, pracuje na TCLITE, a to jest stare, brzydkie i jeszcze z czasów samego C.

Nie znam tclite. Jakby napisał, że chodzi o C, a nie C++ to by było jasne.

Natomiast jedno jest pewne. Nie ma gorszego sposobu uczenia zarówno C jak i C++ mieszając oba te języki. Elementy nieobiektowe w C++ pozostały tylko ze względu na możliwość kompilowania starego istniejącego kodu w C i w żadnym innym celu.
Czasem mi się nóż w kieszeni otwiera jak widzę programy w których autor (często "nauczyciel") sprawdza czy środowiskiem na pewno jest C++, a potem bezmyślnie używa sobie cin, printf, getch itd. Powstaje z tego hybryda, która ani nie jest C, ani porządnym C++, ani programem przenośnym.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 13.01.2008 o 12:11, Olamagato napisał:

Gdyby jednak wpisywać cyfry lub inne znaki niż litery (= tekst),
to program nie ma sensu i w ogóle nie powinien przyjmować takich łańcuchów.


Dlaczego nie ma sensu? Imho w takim wypadku pozwala sprawdzić czy osoba odpowiedzialna za kod potrafi przewidzieć mogące wystąpić różne przypadki i zabezpieczyć się przed ich niepożądanym wpływem na poprawne działanie programu - przynajmniej takie doświadczenia mam po kursach wstępu do programowania i algorytmów.
A założenie że tekst składa się z samach liter nie jest najlepszym rozwiązaniem, bo w takim przypadku mówiłyśmy raczej o wyrazie - tekst, z definicji, musi zawierać dodatkowe znaki, choćby spacje.

Dnia 13.01.2008 o 12:11, Olamagato napisał:

Natomiast jedno jest pewne. Nie ma gorszego sposobu uczenia zarówno C jak i C++ mieszając oba
te języki.


Też się z tym zgadzam. Ale to już niestety jest efektem geniuszu niektórych prowadzących zajęcia. I dotyczy to niestety wszystkich typów szkół. Nawet u nas na informatyce zajęcia prowadzi osoba, która zaczynała od pascala, potem napisaną książkę o tym języku przepisała na C++ i na tej podstawie prowadziła zajęcia, a teraz szykuje się (i nie wiadomo czy jej się nie uda) do prowadzenia zajęć z javy - a materiałami do kursu będzie pewnie jej książka, którą z pseudo C++ "przetłumaczy" na jave ;/ Strach się bać, co po takim kursie zostanie w głowach przyszłych programistów.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 13.01.2008 o 13:44, vBoguSv napisał:

Imho w takim wypadku pozwala sprawdzić czy osoba odpowiedzialna za kod
potrafi przewidzieć mogące wystąpić różne przypadki i zabezpieczyć się przed ich niepożądanym wpływem na poprawne działanie programu

No w sumie masz rację. W tym wypadku jeżeli założeniem jest wczytanie tekstu, to już na etapie wczytywania powinna być eliminacja niepożądanego wejścia.

Dnia 13.01.2008 o 13:44, vBoguSv napisał:

Nawet u nas na informatyce zajęcia prowadzi osoba, która zaczynała od pascala, potem napisaną książkę o tym języku przepisała na C++ i na tej
podstawie prowadziła zajęcia, a teraz szykuje się (i nie wiadomo czy jej się nie uda) do prowadzenia zajęć z javy

Moim zdaniem nie uda się bo java wymusza zupełnie inne podejście do programowania - a przy takiej zmianie nauczyciele muszą się tego wcześniej sami nauczyć, albo przestają być dobrymi nauczycielami. Zapewne po jakimś czasie przestanie się uczyć języków proceduralnych zaczynając od razu od obiektowych ze sterowaniem zdarzeniowym bo jest to kompletnie inne podejście do programowania.

Dnia 13.01.2008 o 13:44, vBoguSv napisał:

Strach się bać, co po takim kursie zostanie w głowach przyszłych programistów.

Zapewne to, co widać na różnych forach dot. programowania, a zaczynających się od postów "pomocy". :)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

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

/**************/

/*****************/
main()
{
clrscr();
char a;

{
cout<<"Podaj dowolny tekst ";
cin>>a; //lub gets>>a;

}while (a )
cout<<"Przedostatni znak podanego tekstu to: "<<strlen;
getch();
}

wszystko cacy tylko ze program się zapętla...
jak coś pracuje w TCLITE
możecie go poprawic aby wyświetlił mi przed ostatnią litere?

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 13.01.2008 o 14:26, Chester001 napisał:

clrscr();

Po co mażesz ekran znakowy? To jest narzut starych nauczycieli z Turbo Pascala i działa tylko na IDE Borlanda z biblioteką BGI.

Dnia 13.01.2008 o 14:26, Chester001 napisał:

char a;

Tutaj deklarujesz, że a jest jednym znakiem, a nie ciągiem znaków/napisem/tablicą znaków

Dnia 13.01.2008 o 14:26, Chester001 napisał:

cin>>a; //lub gets>>a;

To używa się tak: gets(a).
cin >> a; to skrót od wywołania metody cin.operator>>(a); lub funkcji operator>>(cin, a);
gets jest funkcją, więc to co napisałeś rozwijałoby się do błędu składniowego ponieważ nie ma funkcji, która przyjmuje takie argumenty jak wskazanie funkcji i zmienna tekstowa, a gets nie jest obiektem, więc nie ma metod.

Dnia 13.01.2008 o 14:26, Chester001 napisał:

}while (a )

Tutaj sprawdzasz warunek powtórzenia pętli przez sprawdzenie czy a jest różne od zera. Czy a byłoby napisem czy znakiem nie miałoby to sensu ponieważ ani tablica znakowa nie może być równa zeru, ani nie można wczytać znaku o kodzie zero. Mógłbyś ewentualnie zrobić warunek while(strlen(a) > 0); żeby sprawdzić czy łańcuch znaków typu char[] w ogóle ma jakieś znaki.

Dnia 13.01.2008 o 14:26, Chester001 napisał:

cout<<"Przedostatni znak podanego tekstu to: "<<strlen;

Tutaj strlen jest funkcją C, którą wywołuje się jako strlen(a), aby wynikiem była długość tekstu. W obecnej postaci na wyjście wypisałoby Ci w zapewne wartość wskaźnika tej funkcji lub wywaliło błąd błędnego argumentu funkcji operator>>(x, y)

Dnia 13.01.2008 o 14:26, Chester001 napisał:

getch();

Ta funkcja niestandardowa pochodzi z języka C i to tylko z kompilatorów Borlanda. Można ją użyć do zatrzymania programu przy założeniu, że system nie ma niczego w buforze wejściowym klawiatury. Jeżeli jednak ma, to zatrzymanie nie nastąpi, a znak zostanie wczytany i odrzucony bo instrukcja wyrażenie getch(); nie zawiera żadnego wykorzystania tej wartości z wyniku funkcji.

Dnia 13.01.2008 o 14:26, Chester001 napisał:

wszystko cacy tylko ze program się zapętla...

na pierwszym while, gdzie warunek zakończenia pętli jest nigdy niespełnialny.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Zadałem pytanie niezbyt adekwatne do treści zadania, gdzie trzeba było nie tyle znaleźć, co policzyć sumę wszystkich dzielników danej liczby ;)

Dnia 12.01.2008 o 16:17, vBoguSv napisał:

Nie musisz szukać do połowy ;] Szukanie dzielników ma to do siebie, że na raz znajdujemy dwa
- więc jeśli idąc od 1 będziesz odkładał na stos z dodatkową możliwością podejrzenia elementu
na wierzchu, najpierw mniejszy z dzielników, a potem jego większego brata

Pomysł dobry, ale nie sprawdził się na internetowej sprawdzaczce (był tam krótki limit czasu na wiele testów, bo 3 sekundy na obliczenie ok. 200000 liczb). Na szczęście, wymyśliłem inny :)
Zmieniłem trochę sito Eratostenesa - dzięki temu algorytm zamiast zapamiętywać w tablicy informację, czy dana liczba jest pierwsza czy nie, zapamiętywał sumę jej dzielników :)
A to wszystko dzięki małej zmianie pętli wypełniającej:

vector <int> tab(T_SIZE);
tab[0] = 0; tab [1] = 0;
for(k=2; k<T_SIZE; k++) tab[k] = 1;

for(k=2; k*2<=T_SIZE-1; k++)
for(j=2*k; j<=T_SIZE-1; j=k+j) tab[j] +=k;

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Ten sam program prawie bez żadnych sprawdzeń, czyli kompletnie nieidiotoodporny:
int main()
{
char s [80];
cout << "Podaj tekst: ";
cin >> s;
if(strlen(s) >=2)
cout << "\nPrzedostatni znak " << s[strlen(s) - 2];
else
cout << "\nZbyt krótki tekst";
return 0;
}

Kluczowe wyrażenie, to s[ strlen(s) - 2 ]. strlen(s) daje nam prawdziwą długość tekstu zakończonego znakiem o kodzie zero czyli \0, co oznacza, że s[strlen(s)], to daje nam właśnie pozycję tego kończącego znaku \0 nazywanego terminatorem, strlen(s) - 1 daje nam ostatni znak w ciągu, a strlen(s) - 2 daje nam znak przedostatni. Trzeba tylko pamiętać, że strlen(s) może być równe zero, co oznacza, że cały łańcuch składa się tylko z terminatora, 1 co oznacza, że mamy tylko jeden znak i znak przedostatni dawałby nam znak znajdujący się przed pierwszym znakiem tablicy, co nie ma sensu i jest błędem adresowania. W przypadku gdy tekst ma dwa znaki - znak przedostatni jest jednocześnie pierwszym bo strlen("ab") - 2 == 0, a zero indeksuje pierwszy znak w napisach języka C i C++.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 13.01.2008 o 15:09, Bimbermistrz napisał:

for(k=2; k<T_SIZE; k++) tab[k] = 1;

Jeszcze być to przyspieszył gdybyś stosował preinkrementację zamiast postinkrementacji bo *bez optymalizacji* wynik inkrementacji jest zapisywany w drugim rejestrze procesora i następnie gubiony jako niepotrzebny. Np.:
mov ax,(k)
inc ax
mov bx,ax //niepotrzebne do niczego
mov (k),ax
Przy preinkrementacji mamy tylko:
mov ax,(k)
inc ax
mov (k), ax
lub wręcz jedna instrukcja maszynowa
inc (k)

Dnia 13.01.2008 o 15:09, Bimbermistrz napisał:

for(k=2; k*2<=T_SIZE-1; k++)
for(j=2*k; j<=T_SIZE-1; j=k+j) tab[j] +=k;

Tu też wszędzie gdzie używasz k*2 możesz zastąpić to wyrażeniem 10 razy szybszym:
k << 1
lub j = k << 1;
oraz nieefektywne j = k + j zastąpić przez j += k
Na szczęscie kompilator sam zwinie wyrażenie (T_SIZE - 1) do stałej jeszcze w czasie kompilacji. Ale dobrze o tym wiedzieć.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

#include<iostream.h>
#include<conio.h>
#include<string.h>
#include<stdio.h>
/**************/
/*****************/
main()
{
char s[80];
cout<<"podaj tekst : ";
cin>>s;
if(strln(s)>=2)
cout<<" przedostatni znak "<<s [ strln(s)-2 ];
else
cout<<"zbyt krotki tekst";
return 0;
}
i pojawia mi sie w TCLITE błąd

function strln should have a prototype in function main()

i dupa..

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 13.01.2008 o 15:40, Chester001 napisał:

function strln should have a prototype in function main()

Programowanie chyba dla Ciebie nie jest. ;) Przyjrzałeś się, że "strln()" znacząco różni się od "strlen()"? Takiej funkcji jaką podałeś rzeczywiście nie ma. Pisząc programy każda najmniejsza literka czy duża litera ma znaczenie. Precyzja i dokładność jest niezbędna. Dlatego najlepiej używać ctrl+c i ctrl+v bo człowiek i jego pamięć jest zawsze najbardziej zawodnym elementem całej tej branży. :)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Precyzja i dokładność jest niezbędna. Dlatego najlepiej

Dnia 14.01.2008 o 14:51, Olamagato napisał:

używać ctrl+c i ctrl+v bo człowiek i jego pamięć jest zawsze najbardziej zawodnym elementem
całej tej branży. :)

no tak.. tylko ze w tym programie te skróty nie działają :):):):):):):):)

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ć