Kompresja pliku przez zwinięcie powtarzających się liter.

0

ZAD 1: Napisz program który wczyta tekst i go skompresuje zastępując powtarzające się litery, cyfrą zgodną z liczbą powtórzeń litery np.:

podaj tekst: abbbaa baabaaaa
po skompresowaniu: a3b2a b2ab4a

Jak mam liczyć te litery, bo raz pisałem program, który miał wypisać powtarzające się litery. Ale tu nie mam pojęcia jak np. policzyć te 3xb pomiędzy abbbaa, z policzeniem globalnym nie miałbym problemu, ale tak.

Stworzyć pętlę for, w której będę sprawdzał po kolei każdy element czy jest równy następnemu, jeśli nie, przerywam liczenie, zwracam liczbę i zaczynam od następnego elementu?

Działać lepiej na stringach czy tablicy charów? Jak potem zamienić np. abbbaa na a3b2a, jakąś wyciągać te elementy z tablicy, tworzyć nową?

0

Stworzyć pętlę for, w której będę sprawdzał po kolei każdy element czy jest równy następnemu, jeśli nie, przerywam liczenie, zwracam liczbę i zaczynam od następnego elementu?

Coś w tym guście

0

Zadanie jest źle sprecyzowane, co ma być wynikiem kompresowania napisu: xyyyy?
a napisu: x4y ?
a napisu: xyyyyyyyyyyyy?

0

Nieważne ja go nie wymyślałem, masz przykład, widocznie zadanie bazuje tylko na literach. a napisu: xyyyyyyyyyyyy -> xy12

0

Widzę że nie zrozumiałeś zadania, z napisu: xyyyyyyyyyyyy -> x12y
Więc może dowiedz się co ma być z licznikami przekraczającymi 9

0

dla xyyyyyyyyyyyyy -> xy12 na początku jest litera zaś ilość wystąpień jeśli > 1

0

podaj tekst: abbbaa baabaaaa
po skompresowaniu: a3b2a b2ab4a

Skoro najpierw litera to czemu skompresowany nie zaczyna się z: ab3 ?
Powtarzam, nie zrozumiałeś treści zadania.

0

Faktycznie źle spojrzałem, więc na początku ilość wystąpień zaś ta litera, zajmijmy się kodem.

0

No teraz zataczamy koło, odpowiedz na: http://4programmers.net/Forum/1085657

0

Co?

0

@_13th_Dragon

Zadanie jest źle sprecyzowane, co ma być wynikiem kompresowania napisu: xyyyy? -> x4y
a napisu: x4y ? -> nie ma takiej możliwości, raczej w grę wchodzą tylko litery,
a napisu: xyyyyyyyyyyyy? -> x12y

Mam taki kod jak na razie:

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

using namespace std;

int main()
{
	string n;
	cin >> n;

		for (int i = 1, licznik = 1; i < n.length(); i++)
		{
			if (n[i - 1] == n[i] )
		{
			licznik++;
		}
			else if (n[i-1]!=n[i] || i == n.length() - 1)
		{
			if (licznik > 1)
			{
				cout << licznik << n[i - 1];
			}
			else
			{
				cout << n[i - 1];
			}

			licznik = 1;
		}

		
		}


	cout << "\n";
	_getch();
}

Problem leży w wyświetlaniu ostatnich takich samych elementów, starałem się to załatwić w ten sposób:

else if (n[i-1]!=n[i] || i == n.length() - 1)
		{
			if (licznik > 1)
			{
				cout << licznik << n[i - 1];
			}
			else
			{
				cout << n[i - 1];
			}

			licznik = 1;
		}

  • ale nie wychodzi. Jakiś pomysł?

@Edit

Załatwiłem to tak:

if (n[i - 1] == n[i] )
		{
			licznik++;

			if (i == n.length() -1)
			{
				if (licznik > 1)
				{
					cout << licznik << n[i - 1];
				}
				else
				{
					cout << n[i - 1];
				}
			}

Problem teraz w tym, że

n.length()

zwraca długość do pierwszej spacji i reszta wyrazów nie jest brana pod uwagę co robić?

0
  1. Czy wiesz że znaki w napisie indeksowane są od 0 ?
  2. Czy rozumiesz różnicę pomiędzy cyfra a liczbą ?
  3. Czy wiesz że n[n.length()] musi mieć wartość '\0'?
for(int ch=1;prv=0,count=0,i=0;;++i)
  {
   ch=str[i];
   ...
   if(!ch) break;
   prv=ch;
  }
0
_13th_Dragon napisał(a):

Czy rozumiesz różnicę pomiędzy cyfra a liczbą ?

Jeśli masz zamiar pisać własny kod od nowa, to nie trać czasu. Ja chcę zmodyfikować mój kod tak aby działał w pełni, teraz problem leży tylko w tym, że kompresuje tylko do pierwszego wyrazu.

Nie interesują mnie różnice pomiędzy cyfrą a liczbą, zadanie jest tak skonstruowane jak jest, widocznie, powyżej 9 też ma się wyświetlać liczba wyświetleń, więc nie szukaj na siłę problemów.

PS: Już sobie poradziłem stworzyłem tablicę charów i skorzystałem z

cin.getline(...), strlen(...)
0
#include <iostream>
#include <string>

using namespace std;

void compress(string input)
{
	int counter=1;
	char lastChar=input[0];
	
	for(int i=1; i<=input.length(); i++)
	{
		if(input[i]==lastChar)
		{
			lastChar=input[i];
			counter++;
			
			if(i==input.length()-1)
				cout << counter << lastChar;
		}
		else	// Combo broken
		{
			if(counter == 1)
				cout << lastChar;
			else
				cout << counter << lastChar;
			
			lastChar=input[i];
			counter=1;
		}
	}
}

int main() {
	
	compress("bbbb a");
	
	return 0;
}

http://ideone.com/9CdRTe

O to chodziło autorowi? Zignorowałem kilka ifów sprawdzających czy się nie wykrzaczy program (sam już nie pamiętam gdzie)

Note: Nie programuję w CPP, więc proszę o nie hejtowanie mnie za jakiekolwiek UB

0

@Hell4Ge

Masz ten sam problem co ja, dla wejścia: bbbb a ->4b

tzn. jeśli ostatnia litera się nie powtarza to jej nie wyświetla, ja też mam ten sam problem.

0

@Hell4Ge

Muszę Cię zmartwić, teraz np. dla wejścia ffff -> 4f4f ;/

0
SPOJowiecaa napisał(a):

Jeśli masz zamiar pisać własny kod od nowa, to nie trać czasu.
To zobacz jak to powinno wyglądać i zmodyfikuj swój kod aby działał.
Zamiast brnąć w beznadziejne pomysły lepiej kilka razy przepisać od nowa. Dopiero z doświadczeniem będziesz pisał od razu prawie optymalnie.

string compress(const string &str)
  {
   ostringstream ss;
   for(int ch=0,prv=str[0],count=1,i=1;prv;++i,prv=ch)
     {
      if((ch=str[i])==prv) ++count;
      else if(count==1) ss<<(char)prv;
      else
        {
         ss<<count<<(char)prv;
         count=1;
        }
     }
   return ss.str();
  }

http://ideone.com/2TuEhY

0
_13th_Dragon napisał(a):
SPOJowiecaa napisał(a):

Jeśli masz zamiar pisać własny kod od nowa, to nie trać czasu.
To zobacz jak to powinno wyglądać i zmodyfikuj swój kod aby działał.

Ale ja twoich kodów nigdy nie mogę zrozumieć:D Mógłbyś chociaż nazwy zmiennych dobierać tak, żeby było jasne co się w kodzie dzieje.

@Edit

Poprawiłem kod i działa:

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

using namespace std;

int main()
{
	char n[100];
	cin.getline(n, 100);
	int licznik = 1;

	

	for (int i = 1; i < strlen(n); i++)
	{
		if (n[i - 1] == n[i])
		{
			licznik++;
			
			if (i == strlen(n) - 1)
			{
				if (licznik > 1)
				{
					cout << licznik << n[i];
				}
				else
				{
					cout << n[i];
				}
			}

			
		}
		else if (i == strlen(n) - 1 && licznik == 1  || strlen(n) == 1)
		{
			cout <<" "<<n[i];
		}
		else
		{
			if (licznik > 1)
			{
				cout << licznik << n[i - 1];
			}
			else
			{
				
				cout << n[i-1];
			}

			licznik = 1;
			
		}


	}

	if (strlen(n) == 1) { cout << n[0]; }

	cout << "\n";
	_getch();
}
0

To jest bardzo dobry przykład jak nie należy pisać programów.

0

Nie interesuje mnie to ważne, że działa. Ja też dopiero zaczynam, i się uczę. PS: Te rady tzn. ten algorytm który zastosowałem dostałem od innego użytkownika.

1

Nie uczysz się, tylko bezmyślnie klepiesz kod dla sprawdzaczki. Co gorsze, gdy ktoś chce Ci pomóc to się obruszasz i pokazujesz swoją ignorancję.

Przeanalizowanie linijka po linijce, zmienna po zmiennej i zrozumienie kodu @_13th_Dragon da Ci więcej niż produkowanie tak zagmatwanego rozwiązania do kolejnych 100 problemów.

0
SPOJowiecaa napisał(a):

Nie interesuje mnie to ważne, że działa. Ja też dopiero zaczynam, i się uczę. PS: Te rady tzn. ten algorytm który zastosowałem dostałem od innego użytkownika.

Teraz wyobraź sobie że jesteś programistą w firmie softwerowej i dostajesz polecenie zmienić ten kod to tak aby dane pobierać ze strumienia rozmiar którego może być w TB (czyli do pamięci nie załadujesz). Twój kod leci do kosza i zaczynasz od nowa. W moim - zmiana w jednym wierszu.

SPOJowiecaa napisał(a):

Ten algorytm który zastosowałem dostałem od innego użytkownika.

Do takich rzeczy potrzebujesz algorytm?
Na zmywanie naczyń też potrzebujesz algorytm?

0

@_13th_Dragon -> określony sposób rozwiązania jakiegoś problemu, składający się z ciągu następujących po sobie czynności (lub instrukcji)

twój kod, też można nazwać algorytmem, to zadanie na potrzeby kolokwium, a nie firmy softwarowej

Vardamir napisał(a):

Nie uczysz się, tylko bezmyślnie klepiesz kod dla sprawdzaczki. Co gorsze, gdy ktoś chce Ci pomóc to się obruszasz i pokazujesz swoją ignorancję.

Nie mam na to czasu człowieku zrozum, że oprócz tego mam multum innych zadań, a kolokwium niedługo. Zamiast pisania o mojej arogancji, której nie ma. Piszcie kod jasny i komentujcie swoje kody, to wtedy nie będę miał problemów ze zrozumieniem go. Poza tym lepiej już napisać własny kod który działa niż bezmyślnie kopiować wasz.

1

Ja studiuję dziennie i pracuje na pełny etat. Mimo to staram się zrozumieć materiał, a nie wykuć. Przyjdą kiedyś przedmioty trudniejsze, traktujące to co teraz piszesz jako elementarną wiedzę i wtedy zamiast skupić się na bardziej zaawansowanych aspektach będziesz to od nowa przerabiał.

Podejście 'kod do kolokwium' jest świetne. Później tylko płacz i pretensje, że studia nie przygotowują do pracy w zawodzie oraz nie pozwalają nabyć praktycznej wiedzy.

Dziękuję, do widzenia.

0

@Vardamir

Już wypisałeś wszystkie swoje mądrości? Uważasz, że lepiej skopiować kogoś kod niż napisać własny, otóż nawet jeśli mój kod zawierał na początku błędy i nie wyświetlał wszystkiego poprawnie, to więcej nauczę się poprawiając go tak, żeby działał niż biorąc gotowca, jakieś polecenia, których zupełnie nie znam.

Do kolokwium trzeba się przygotować, po kolokwium będę miał mnóstwo czasu, żeby dalej się rozwijać, dopiero miałem około 7 ćwiczeń z informatyki, więc nie wiem czego ode mnie wymagasz. Więc skończ już, bo się Ciebie słuchać nie chce, poza tym zakładasz z góry, że będę programistą, a mój kierunek studiów nie jest tak bardzo z tym związany jak myślisz.

1

@SPOJowiecaa, masz jakiś problem z logicznym rozumowaniem (tak a propos mocno to nie pasuje do studiów informatycznych). Kiedy ktoś mówi ci "przeanalizować" oznacza to nie skopiować kod zaś właśnie przeanalizować, czyli sprawdzić co to za "jakieś polecenia, których zupełnie nie znam" w google lub dokumentacji, zrozumieć jak to działa, nauczyć się to stosować.
Jak teraz nie interesuje cię że to co zrobiłeś w 45 wierszach da się zrobić w 12 wierszach to prawdopodobnie nie zaliczysz tego kolokwium z powodu braku czasu (bo zwyczajnie 45 wierszy piszę się co najmniej czterokrotnie dłużej niż 12 wierszy), zaś po kolokwium (patrząc na twoje podejście) nie będziesz się tym zajmować w ogóle.

0

Ja się akurat nie mądrze, zasugerowałem się tym, że dwa tygodnie temu sam prosiłeś o przykładowe projekty do zrealizowania dla początkującego programisty. Teraz za to, szybko szybko bo kolokwium niedługo. Oczywiście, że warto pisać własny kod. Tylko warto też ambitnie podejść do nauki.

Jak się ma sprawa z Elektroniką i Telekomunikacją (zakładam, że o ten kierunek chodzi), a programowaniem to nie wiem bo nie studiowałem tego (Informatyki zresztą też nie). Ale wielu moich znajomych pracuje po takich studiach w nokii i warto było umieć programować przy rekrutacji, choć faktycznie nie było to konieczne. Możesz faktycznie to olać, jednak warto wynieść ile się da z uczelni oraz tak jak wcześniej mówiłem, podejść ambitnie do zdobywania wiedzy bo to procentuje. Wiem, że to slogany, ale też najprawdziwsza prawda.

0

@Vardamir

Chodzi o AiR, nie wiem jak wiele będę korzystał z programowania, ale może i dość sporo, ale to pewnie w samym C.

Wiem, że warto ambitnie podejść do tego, ale akurat teraz naprawdę nie mam czasu. W wolnych chwilach rozwiązuję zadania ze SPOJa i tu też jak np. ktoś jakiś kod wrzuci, analizuję tzn. rozwiązuje niektóre zadania na kilka sposobów, ale chcę się przygotować z każdego przykładowego zadania.

1 użytkowników online, w tym zalogowanych: 0, gości: 1