Laboratorium programowania zad 15

Zadanie z laboratorium programowania na Informatyce UW.

Zadanie 15 (termin wysylania rozwiazan: 21 maja 2008, godz. 23:59)

(Permutowanie napisu)

Napisz program, ktory wczyta z wejscia ciag znakow zakonczony koncem
wiersza oraz niepusty ciag liczb calkowitych zakonczony liczba zero,
ktorej nie uznajemy za czesc ciagu.

Nie znamy maksymalnej dlugosci zadnego z ciagow, wiec bedziemy je
przechowywac w strukturach listowych. Po listach bedziemy sie
poruszali cyklicznie - po liscie liczb w jednym kierunku a po
liscie znakow w dwoch kierunkach. Oznacza to, ze program bedzie sie
poslugiwal dwukierunkowa lista cykliczna znakow oraz jednokierunkowa
lista cykliczna liczb.

Po utworzeniu obu list, program powinien wypisac zawartosc ciagu
znakow, w kolejnosci wyznaczonej przez ciag liczb, rozpoczynajac
od pierwszego znaku i pierwszej liczby, zgodnie z nastepujacym
przepisem:

* wypisujemy aktualny znak
* usuwamy go z listy
* niech k bedzie aktualna liczba na liscie liczb
  - jesli k jest wieksze od zera, to przesuwamy sie o k znakow do
    przodu (wzgledem usunietego znaku) na liscie cyklicznej znakow
  - jesli k jest mniejsze od zera, to przesuwamy sie o k znakow do
    tylu (wzgledem usunietego znaku)
* zmieniamy k na nastepna liczbe (uwzgledniajac cyklicznosc listy)

Np. dla danych:

alamakota
3 -2 0

program powinien wypisac:

amlkataoa

A oto rozwiązanie:

#include 
#include 
#include 

//Struktura dla znakow zasugerowana w zadaniu
typedef struct znak_el{     
      char znak;           
      struct znak_el * nastepny; 
	  struct znak_el * poprzedni; 
};


struct liczba_el {
      int liczba;   
      struct liczba_el* nastepny; 
};



int main (int argc, char *argv[])
{

	//Inicjujemy
	int liczba,kierunek,wynik,skok;
	char znak;
	struct znak_el *teraz_znak=NULL;
	struct znak_el *start_znak=NULL;
	struct znak_el *tmp_znak=NULL;
	struct liczba_el *teraz_liczba=NULL;
	struct liczba_el *start_liczba=NULL;
	struct liczba_el *tmp_liczba=NULL;

	
	wynik=scanf("%c",&znak);

	if((znak!='r')&&(znak!='n')&&(wynik!=EOF))//jesli nie bylo znakow w pierwszym wierszu.
	{
		//pierwszy element ciagu znakow
		start_znak=malloc(sizeof(struct znak_el));
		start_znak->nastepny=start_znak;
		start_znak->poprzedni=start_znak;
		start_znak->znak=znak;		
		wynik=scanf("%c",&znak);
		teraz_znak=start_znak;
		

		while((znak!='r')&&(znak!='n')&&(wynik!=EOF))	//wesole atrakcjie dla koncow znakow w roznych systemach.
		{
			teraz_znak->nastepny=malloc(sizeof(struct liczba_el));
			teraz_znak->nastepny->poprzedni=teraz_znak;
			teraz_znak->nastepny->nastepny=start_znak;
			teraz_znak=teraz_znak->nastepny;
			teraz_znak->znak=znak;
			wynik=scanf("%c",&znak);
		}
		start_znak->poprzedni=teraz_znak; //Zapetlamy koncowke
		
		//znaki powinny byc wczytane.
		
		//wczytujemy liczby
		wynik=scanf("%d",&liczba);
		
		if((wynik!=EOF)&&(liczba!=0))	//Jesli sa liczby
		{
			
			start_liczba=malloc(sizeof(struct liczba_el));
			start_liczba->nastepny=start_liczba;

			start_liczba->liczba=liczba;		
			wynik=scanf("%d",&liczba);
			teraz_liczba=start_liczba;
			
			while((liczba!=0)&&(wynik!=EOF))	//dopoki....
			{
				
				teraz_liczba->nastepny=malloc(sizeof(struct liczba_el));
				teraz_liczba->nastepny->nastepny=start_liczba;
				teraz_liczba=teraz_liczba->nastepny;
				teraz_liczba->liczba=liczba;
				wynik=scanf("%d",&liczba);

			}
			
			teraz_znak=start_znak;
			teraz_liczba=start_liczba;
			//OK. Powinno byc wczytane, Trzeba wypisac.
			
		
			
			//I teraz trzeba wypisac!!
			
			while(teraz_znak->nastepny!=teraz_znak)	//Jesli jest wiecej niz jeden znak w liscie
			{
				//dopoku nie zostal jeden znak na liscie.
				//wypisujemy,
				printf("%c",teraz_znak->znak);
				//usuwamy
				tmp_znak=teraz_znak;
				teraz_znak->poprzedni->nastepny=teraz_znak->nastepny;
				teraz_znak->nastepny->poprzedni=teraz_znak->poprzedni;

				
				//ustalamy wlasnosci skoku
				if(teraz_liczba->liczba>0)
				{
					kierunek=1;
					skok=teraz_liczba->liczba;
				}
				else
				{
					kierunek=-1;
					skok=teraz_liczba->liczba*-1;
				}
				teraz_liczba=teraz_liczba->nastepny;
				
				//teraz wlasciwy skok.
				
				while(skok>0)
				{
					if(kierunek==1)
					{
						//skok do przodu
						teraz_znak=teraz_znak->nastepny;
					}
					else
					{
						//skok do tylu
						teraz_znak=teraz_znak->poprzedni;
					}
					skok+=-1;
				}
				//przesunieto nastepny znak do wypisania.

				//faktyczne usuwanie znaku.
				free(tmp_znak);
			}
			
			//dobrze. W tej chwili powinien zostac jeden znak w liscie.
			printf("%cn",teraz_znak->znak);

			free(teraz_znak);

		
			//no dobrze, ale tez byloby milo po sobie posprzatac. zostaly nam liczby..
			
			while(teraz_liczba->nastepny!=start_liczba)
			{
				tmp_liczba=teraz_liczba;
				teraz_liczba=teraz_liczba->nastepny;
				free(tmp_liczba);
			}
		}
		else
		{
			//Szwindel. Nie bylo liczb.
			return 2;
		}

	}
	else
	{
		//Szwindel. Nie bylo znakow.
		return 1;
	}

return 0;
}

Leave a Reply