Блоґ одного кібера

Історія хвороби контуженого інформаційним вибухом

Клас – многочлен

with 3 comments

Маленький клас на C++, який задає тип даних – многочлен, і основні оператори над цим типом. Створений як елемент лаболаторної, тому функціональність не повна. В пам’яті представляється списком одночленів відсортованих за спаданням. Тестувався з Microsoft Visual C++ 2008.

Структура tmonomial задає структуру одночлена. float k – коефіцієнт біля ікса, int pow – степінь ікса.
struct smonomial *next; – посилання на наступний одночлен многочлена.

Клас tpolynomial задає многочлен. В нього є тільки одне захищене поле – head – посилання на список одночленів. Конструктор надає йому нульового значення.

Методи

void addmonomial(float k,int pow) – додає до многочлена одночлен, з коефіцієнтом k і степінню ікса pow. Все одразу скорочується і відсортовується.
void print() – виводить многочлен на консоль в форматі подібному на 2.23x4+1.45x2-7.20x1.
void sscan(char *str) – читає многочлен з рядка такого ж формату.
int maxpow() – максимальна степінь многочлену, або порядок іншими словами
void clear() – обнулити многочлен
void sscan(char *str) – читає многочлен з рядка такого ж формату.

Оператори

+,-,*,/,=,+=,-=,*= – як звичайно, а крім того є *= на тип одночлен, і на число з плаваючою крапкою.

typedef struct smonomial
{
	float k;
	int pow;
	struct smonomial *next;
} tmonomial;
typedef tmonomial *pmonomial;
class tpolynomial
{
protected:
	pmonomial head;
public:
	tpolynomial()
	{
		head=NULL;
	}
	void addmonomial(float k,int pow)
	{
		if(!k) return;
		if(!head)
		{
			head = new tmonomial;
			head->k=k;
			head->pow=pow;
			head->next=NULL;
			return ;
		}
		else
		{
			pmonomial cur=head,curpr;
			pmonomial ins;
			if(cur->pow==pow)
			{
				cur->k+=k;
				return; 
			}
			if(cur->pow<pow) // the highest power
			{
				ins = new tmonomial;
				ins->k=k;
				ins->pow=pow;
				ins->next=cur;
				head=ins;
				return;
			}
			while(cur->next)
			{
				curpr=cur;
				cur=cur->next;
				if(cur->pow==pow) // equal power
				{
					cur->k+=k;
					return; 
				}
				if((cur->pow<pow)&&(curpr->pow>pow))
				{
					//insert between two cursors
					ins= new tmonomial;
					ins->next=cur;
					ins->k=k;
					ins->pow=pow;
					curpr->next=ins;
					return;
				}
			}
			// else the lowest power
			ins=new tmonomial;
			ins->k=k;
			ins->pow=pow;
			ins->next=NULL;
			cur->next=ins;
		}
	}
	void print()
	{
		pmonomial cur=head;
		if(!cur) 
		{
			printf("0x0");
			return;
		}
		while(1)
		{
			printf("%.2fx%d",cur->k,cur->pow);
			if(cur->next)
			{
				if (cur->next->k>=0) printf("+");
			}
			else
				return;
			cur=cur->next;
		}
	}
	void sscan(char *str)
	{
		int p;
		float k;
		char extend[1000];
		char *ep=extend;
		while(*str)
		{
			if(*str=='-')
			{
				*ep='+';
				ep++;
				*ep='-';
			}
			else
			{
				*ep=*str;
			}
			str++;
			ep++;
		}
		*ep='';
		str=extend;
		while(*str)
		{
			sscanf(str,"%fx%d",&k,&p);
			addmonomial(k,p);
			while((*str)&&(*str!='+'))
			{
				str++;
			}
			if(*str=='+') str++;
		}
	}
	int maxpow()
	{
		if(head)
		{
			if(head->k!=0)
				return head->pow;
			else
			{
				pmonomial cur=head;
				while((cur)&&(cur->k==0))
				{
					cur=cur->next;
				}
				if(cur)
					return cur->pow;
				else 
					return -1;
			}
		}
		else return -1;
	}
	void clear()
	{
		pmonomial cur=head;
		pmonomial del;
		while(cur)
		{
			del=cur;
			cur=cur->next;
			delete del;
		}
		head=NULL;
	}
	tpolynomial operator=(tpolynomial op)
	{
		clear();
		pmonomial cur=op.head;
		while(cur)
		{
			addmonomial(cur->k,cur->pow);
			cur=cur->next;
		}
		return *this;
	}
	tpolynomial operator+=(tpolynomial op2)
	{
		pmonomial cur=op2.head;
		while(cur)
		{
			addmonomial(cur->k,cur->pow);
			cur=cur->next;
		}
		return *this;
	}
	tpolynomial operator-=(tpolynomial op2)
	{
		pmonomial cur=op2.head;
		while(cur)
		{
			addmonomial(-cur->k,cur->pow);
			cur=cur->next;
		}
		return *this;
	}
	tpolynomial operator+(tpolynomial op2)
	{
		tpolynomial res;
		res=*this;
		res+=op2;
		return res;
	}
	tpolynomial operator-(tpolynomial op2)
	{
		tpolynomial res;
		res=*this;
		res-=op2;
		return res;
	}
	tpolynomial operator*=(float sc)
	{
		pmonomial cur=head;
		while(cur)
		{
			cur->k*=sc;
			cur=cur->next;
		}
		return *this;
	}
	tpolynomial operator*=(tmonomial mul)
	{
		pmonomial cur=head;
		while(cur)
		{
			cur->k*=mul.k;
			cur->pow+=mul.pow;
			cur=cur->next;
		}
		return *this;	
	}
	tpolynomial operator*(tmonomial mul)
	{
		tpolynomial res;
		res=*this;
		res*=mul;
		return res;
	}
	tpolynomial operator*=(tpolynomial op2)
	{
		pmonomial cur=op2.head;
		tpolynomial res;
		while(cur)
		{
			res+=*this*(*cur);
			cur=cur->next;
		}
		*this=res;
		return res;
	}
	tpolynomial operator*(tpolynomial op2)
	{
		tpolynomial res;
		res=*this;
		res*=op2;
		return res;
	}
	tpolynomial operator/(tpolynomial op2)
	{
		tpolynomial res;
		tpolynomial temp=*this;
		tmonomial t;
		if(temp.maxpow()<op2.maxpow()) return res;
		while(temp.maxpow()>=op2.maxpow())
		{
			t.k=temp.head->k/op2.head->k;
			t.pow=temp.head->pow-op2.head->pow;
			res.addmonomial(t.k,t.pow);
			temp=temp-op2*t;
		}
		return res;
	}

};

Придирайтеся в коментарях, на здоров’я. Особливо хотілось би почути прихильників красивого коду.

Advertisements

Written by bunyk

Лютий 22, 2009 at 20:55

Оприлюднено в Кодерство

Tagged with ,

Відповідей: 3

Subscribe to comments with RSS.

  1. хмм… спробуй повчити Пітон. Тобі, як майстру видумування, повинен сподобатись.

    можливо я вже казав, але з його допомогою я написав програмку, яка вирішує диф-рівняння, і вона займала всього 60 рядочків коду ( це розмір програмки, яка розраховувала всі дані на лабу по Анал Механіці)

    danbst4

    Лютий 26, 2009 at 18:57

  2. Це власне була лаболаторна 2 першого семестру (під білдер, і крім того не моя).

    А нас на кожній лекції вчили, що дифрівняння не розв’язуються, а якщо вийде, то вам пощастило. Значить має бути потужна прога.

    Що ще маю сказати. В планах в мене вивчення архітектури, і … ну по блогу має бути видно що в мене в планах. Заведи свій блог, напиши про Пітон. Українська інформаційна ніша (тим більше про Пітон) майже порожня. Сам подивись, як щвидко я попав в індекс Гуглу. Такими темпами через рік поставлю собі AdWords.

    bunyk

    Лютий 26, 2009 at 21:38

  3. Хоча, важко буде знайти в Гуглі блог про Пітон, коли там купа новин типу
    У США пітон луснув, проковтнувши алігатора | Хрещатик – Київська мунiципальна газета
    :):):):):):):):):):)

    bunyk

    Лютий 26, 2009 at 21:40


Залишити відповідь

Заповніть поля нижче або авторизуйтесь клікнувши по іконці

Лого WordPress.com

Ви коментуєте, використовуючи свій обліковий запис WordPress.com. Log Out / Змінити )

Twitter picture

Ви коментуєте, використовуючи свій обліковий запис Twitter. Log Out / Змінити )

Facebook photo

Ви коментуєте, використовуючи свій обліковий запис Facebook. Log Out / Змінити )

Google+ photo

Ви коментуєте, використовуючи свій обліковий запис Google+. Log Out / Змінити )

З’єднання з %s

%d блогерам подобається це: