41 / 85
Feb 2016

Bardzo ciężki kawałek kodu napisałeś Ci powiem. Widziałeś chociaż swój out dla przykładu spod zadania? :

	-1078343384
a 7
k 1
l 2
m 2
o 1
p 1
s 1
t 1
  4

na początku jakaś liczba, poprzedzona tabulacjami, ostatniej litery brakuje. O do ... while możesz spokojnie zapomnieć w programowaniu - więcej z nim kłopotów niż pożytku.

Ja, jako "stary wyjadacz" czytałbym te dane np. tak:

#include <iostream>
using namespace std;
 
int main() {
	int ile;
	char ch;
	cin >> ile;
	while(cin >> ch){
		//zrób to coś z ch
	}
	return 0;
}

Masz wczytane dane w 5 linijkach, bez białych znaków, możesz spokojnie zająć się liczeniem ile razy która była.

Dzięki za szybką odpowiedź. Z tą liczbą na początku to coś sobie sprawdzałem i zapomniałem usunąć przed wrzuceniem tego do postu blush. Ostatnia litera to spacja. Spróbuje to wszystko bardziej przejrzyście napisać i idąc za radą pozbędę się do... while.

5 months later

Hej próbuję odpalić program z zadanka Zliczacz liter na spoju dostaję informację o błędnej odpowiedzi na idleone segmentation fault. https://ideone.com/Eq7jtl29 Lokalnie kompiluje się bez problemu zarówno g++ jak i przez gcc z parametrem --std=c99 Gdyby ktoś podpowiedział gdzie jest błąd będę wdzięczny :wink:

Na pewno masz błąd w tej for(int i=0; i<=ilosc_linijek; i++) linijce, dla danych testowych czyli 2 wykona się 3 razy dla0, 1, 2. Więc albo zmień i na 1 albo usuń = . Błąd jest gdzieś jeszcze ale niestety nie wiem gdzie.

Przy wierszu w którym sugerujesz, że ma być tylko znak mniejszości program wczytywał zawsze o jedną linię mniej niż oczekiwałem przez co zamieniłem go na mniejsze bądź równe. Też się zastanawiałem dlaczego ten getchar łapał EOL z poprzedniej lini. Dla pewności zmieniłem ten parametr i wysłałem ponownie na spoja. Nadal wyświetla się błąd.

scanf("%i", &ilosc_linijek); <-- nie wczytuje znaku końca tej linii.
Możesz to poprawić w poniższy sposób:
scanf("%i\n", &ilosc_linijek);
i wtedy nie musisz już powiększać [sztucznie?] pętli.

Błąd powodowany jest za małą tablicą [o jeden znak]
Trzeba znać tablicę kodów ascii ale nie aż tak dokładnie. :wink:

zamiast:

  int tablica[122]; // + co najmniej 1, a najlepiej od razu 255
  ....... 
  for(int i=0;i<123;i++)
      tablica[i] = 0;

można [lepiej?]

int tab ['z' + 1] = {0}; // = {0} zastępuje twoją pętlę zerującą

zamiast:

while((znak = getchar()) != 10)

bezpieczniej

while((znak = getchar()) >= ' ')

bo uwzględnia znak eof w ostatniej linii, bez entera

zamiast:

for(char i=97; i<123; i++){

dużo czytelniej:

for (char i = 'a'; i <= 'z'; i++){

czy też

for (int i = 'a'; i <= 'z'; i++){

itd

Faktycznie o jeden element za mało zadeklarowałem :slight_smile: dzięki wielkie. Naprawdę fajne te sposoby z czyszczeniem tablicy i przekształcaniem liter na ich odpowiedniki ascii nie znałem ich wcześniej. Jeszcze raz dzięki :slight_smile:

1 month later

Hej,
Pomoże ktoś z zadaniem?
Mianowicie...
To jest program który wykasuje litere 'a' ze zdania. (rozwiazanie tego problemu rozwiążę mój problem z całym zadaniem
(...)
string b = "Karde ale wtopa";
char c;
c = 97;
size_t pozycja=b.find(c);
while(pozycja!=string::npos);
{
b.erase(pozycja,1);
//cout<<pozycja; //dla sprawdzenia
size_t szukaj=b.find(c);
}
(...)

Okazuje się że pod zmienną pozycja po wykasowaniu wszystkich 'a' ze zdania, pojawia się jakaś dziwna wielka wartość 186446744(...). I pętla się nigdy nie kończy, o co chodzi ?

Można też się posłużyć może trochę prostszym kodem:

(...)
string b = "Karde ale wtopa";
char c;
c = 97;
for(int i = 0; i<10; i++)
{
size_t szukaj=b.find(c);
cout<<szukaj;
if(szukaj!=string::npos);
b.erase(szukaj,1);
}
(...)

szukaj wypisze na której pozycji znajduje się 'a' a następnie gdy go nie ma - jakąś wielką wartość.

Rzeczywiście bardzo dziwna.
Jak policzysz: 2⁶⁴ może będzie mniej dziwna?

Ale tym twoim sposobem nie widzę szans na zaliczenie tego zadania, chyba, że dane wejściowe są [bardzo] małe a limit czasu [bardzo] duży - nie sprawdzałem.

Nie znalazł, na żadnej pozycji, więc podstawił taką dużą wartość, która jest dużo większa od każdej rozsądnej [dopuszczalnej] długości stringa.

Dlaczego więc wyrażenie if(szukaj!=string::npos); czy while(szukaj!=string::npos); nadal zwraca wartość true? ;<

Zdecydowanie za długo przed komputerem :joy:
btw; dostałem AC z time 0:00 z tą dziwną moją metodą :stuck_out_tongue:

Faktycznie, danych w tym zadaniu jest jak kot napłakał i uzyskanie czasu powyżej 0.00 w c/c++ tego zadania jest chyba niewykonalne. Dużo łatwiej w innych językach:
http://pl.spoj.com/ranks/JZLICZ/start=384012 i poniżej.

PS
Dziwna metoda, w sensie bardzo nieefektywna, a 0.00 bo małe testy.

Faktycznie musi być tych danych bardzo mało.
Metoda wydawała mi się efektywna z tego względu że po każdym przejściu pętli, string do przeszukiwania będzie coraz mniejszy.
W sensie:
Znajdź 'a', licz ile razy wystąpi 'a', usuń wszystkie 'a' ze stringa, wypisz ile razy wystąpił 'a';
String mniejszy o ilość wystąpień 'a'
Znajdź 'b' licz ile razy wystąpi 'b', usuń wszystkie 'b' ze stringa, wypisz ile razy wystąpił 'b';
String mniejszy o ilość wystąpień 'b'
itd
pętla przejdzie tyle razy ile szukamy literek. (około 50)
Dopiero zaczynam zabawę z programowaniem stąd pewnie błędne założenia :smiley:
efektywniejszy sposób na rozwiązanie tego zadania będzie jaki ?

Każdy inny? :wink:
Zadanie nie polega na znalezieniu szukanej literki, policzeniu jej i wypisaniu poprawionego tekstu, a Ty mniej więcej to robisz. Jeżeli więc zrobisz tylko jedno z poniższych [lub wszystko]:

  1. zrezygnujesz z kasowania
  2. zrezygnujesz z wyszukiwania - metodą find - za każdym razem od początku stringa
  3. tylko jednokrotnie przejście stringu i dodawanie wystąpienia danej literki do tablicy wystąpień

to uzyskasz efektywniejsze rozwiązanie.

7 months later

Witam :slight_smile:
Mam problem z tym zadankiem, a konkretniej z vectorami. Sprawdzalam krok po kroku gdzie jest blad i zaznaczylam ten fragment, jakby ktos wiedzial o co chodzi to bylabym bardzo wdzieczna za kazda odpowiedz :slight_smile:
PS Nie zwracajcie uwagi na to, ze najpierw wyswietlane sa duze litery - jeszcze nie napisalam tego w kodzie, zajme sie tym potem.
PS2 Kod jest w trybie roboczym, wiec moze nie byc do konca jasny. Potem ladnie go streszcze i bedzie cacy :blush:
Moj kod: https://ideone.com/9iB1EG22

Tak, tam jest błąd. Powinno być:

tab.insert(tab.begin()+j+1, x);

Jednak nic to nie da jeśli nie poprawisz błędu, który jest powyżej. No i, jak słusznie zauważyłaś, należy zająć się tymi WIELKIMI literami :slight_smile:

Sprawdzam, analizuje i cos mi nie trybi :smiley: Jakas wskazowka, gdzie jest jeszcze blad?