Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Otchet_polinom.doc
Скачиваний:
2
Добавлен:
16.11.2019
Размер:
198.66 Кб
Скачать

Заключение

Таким образом, все задачи, поставленные во введении, с успехом достигнуты, а именно: была реализована структура хранения список для прикладной задачи произведение операций над полиномами от трех переменных: сложение, вычитание, умножение полиномов, вычисление производной. Были получены необходимые навыки практического использования и реализации структуры список.

Литература

1. Топп У., Форд У. Структуры данных в C++: Пер. с англ. – М.: ЗАО «Издательство БИНОМ», 1999. – 816 с.: ил.

2. Шилдт Г. Полный справочник по C++ :Пер. с англ. – М.: изд. Вильямс, 2007. – 800 с.

3. Гергель В.П., Курс лекций по предмету «Языки программирования».

Приложение (исходный код программы)

stdafx.h

#ifndef ST_REAL_H

#define ST_REAL_H

#pragma once

#include <stdlib.h >

#include <conio.h>

#include <stdarg.h>

#include <math.h>

#include <windows.h>

#include <process.h>

#include <string.h>

#include <stdio.h>

#include <fstream> // средства для управляемой пользователем обработки файлов.

#include <iostream> // объекты cin, cout, cerr и clog,

#include <iomanip> // управления форматируемым вводом/выводом с помощью параметризованных манипуляторов потока.

using namespace std;

using namespace System;

using std::cin;

using std::cout;

int parse();

void inttoname(int nom,unsigned int pol,char buffer[]);

int Svernut(char s[]);

void AntiPars(int Anom,unsigned int Mpars[]);

void CreatSpis(int Anom);

int getfile();

struct node {

int elem;

unsigned int pol;

node *next;

};

void Proizvodnay(node *first);

class Spisok

{

private:

node *phead; //указатель на начало списка .

node *pend;

node *cursosr;

node *Res; //указатель на найденное звено .

int N_monom;

public:

Spisok() {phead = new (node); (*phead).next=NULL;} //конструктор

~Spisok() { delete phead; } //деструктор.

void Initial(node **first, node **last);

int Empty(node *first);

void Add(node **last,int elem, unsigned int pol);

void Show(node *first);

int Poisk_Eqv (node *first,unsigned int pol,node **last);

int Poisk_Less (node *first,int el,node **last);

void Izm (node *Res, int el,unsigned int pol);

void DelAll(node *first, node **last);

void AddLess (node **Res, int el,unsigned int pol);

int Next (node *first,int el,node **last);

void Del1 ();

};

#endif

spis06.cpp

#include "stdafx.h"

Spisok A,B;

unsigned int Mpars[500];

//unsigned int Mpars1[500];

node *Bfirst, *Blast ;

node *BRes; //Указатель на найденное звено списка.

node *Afirst, *Alast ;

node *ARes; //Указатель на найденное звено списка.

void Spisok::Del1 ()

//Удаление звена, на которое указывает ссылка Res.

{

node *q,*q1,*q2;

//Определяем местоположение следующего за удаляемым элемента.

q = (*ARes).next;

if (q!=NULL)//Если удаляемое звено не является последним

{

(*ARes).elem = (*q).elem;

(*ARes).pol = (*q).pol;

(*ARes).next = (*q).next; // "Переписываем" следующий элемент в удаляемый

delete q;

}

else

{

q1 = Afirst;

q2 = (*q1).next;

while (q2!=ARes)

{

q1 = q2;

q2 = (*q2).next;

}

(*q1).next = NULL;

q2 = NULL;

delete ARes;

}

}

void Spisok::Initial(node **first, node **last)

{

*first=new node;

(*first)->next=NULL;

*last=*first;

N_monom=0;

}

int Spisok::Empty(node *first)

{

if (first->next==NULL)

return 1;

else

return 0;

}

void Spisok::Add(node **last,int elem,unsigned int pol)

{

node *tmp=new node;

tmp->elem=elem;

tmp->pol=pol;

tmp->next=NULL;

(*last)->next=tmp;

*last=tmp;

N_monom++;

}

void Spisok::Izm (node *Res, int el,unsigned int pol)

// изменение содержимого найденого звена на el

{

// cout << endl<<"izmres="<< Res->elem<< Res->pol;

cout << endl;

Res->elem = el;

Res->pol = pol;

// (*Res).pol = pol;

}

void Spisok::DelAll(node *first, node **last)

{

node *tmp;

while(first->next!=NULL)

{

tmp=first->next;

first->next=tmp->next;

delete tmp;

}

*last=first;

}

void Spisok::Show(node *first)

{

node *tmp=first->next;

cout <<endl;

while(tmp!=NULL)

{

cout << tmp->elem << " "<< tmp->pol << ", ";

tmp=tmp->next;

}

cout <<endl;

}

int Spisok::Poisk_Eqv (node *first,unsigned int pol,node **last)

//Поиск звена с элементом равным el в списке, заданном указателем

// *first. В случае успешного поиска в Res заносится 1 а в last находится адрес

//звена списка, содержащего элемент el, в случае неуспеха

//в Res помещается 0.

{

unsigned int r;

int rez=0;

node *tmp=first->next;

while(tmp!=NULL)

{

r=tmp->pol ;

if(pol==r)

{

// cout << r << " ";

rez=1;

break;

}

tmp=tmp->next;

}

*last=tmp;

return(rez);

}

int Spisok::Poisk_Less (node *first,int sv,node **last)

//Поиск звена с элементом меньше el в списке, заданном указателем

// *first. В случае успешного поиска в Res заносится 1 а в last находится адрес

//звена списка, содержащего элемент меньше el, в случае неуспеха

//в Res помещается 0.

{

int rez=0;

int r;

node *tmp=first->next;

while(tmp!=NULL)

{

r=tmp->pol ;

if(sv>r)

{

/// cout << r << " ";

rez=1;

break;

}

tmp=tmp->next;

}

*last=tmp;

return(rez);

}

void Spisok::AddLess (node **Res, int el,unsigned int pol)

//Включение звена с информационным полем el

//перед звеном, на которое указывает *Res.

{

node *q;

// формируем новое звено и перекидываем в него содержимое

q = new (node);

(*q).elem = (**Res).elem;

(*q).pol = (**Res).pol;

(*q).next = (**Res).next;

// заменяем значения в старом звене

(**Res).elem = el;

(**Res).pol = pol;

(**Res).next = q;

N_monom++;

}

int Spisok::Next (node *first,int el,node **last)

//Поиск звена с элементом el в списке, заданном указателем

//phead. В случае успешного поиска в Res находится адрес

//звена списка, содержащего элемент el, в случае неуспеха

//в Res помещается NULL.

{

int r;

node *tmp=first->next;

if (tmp==NULL) return (1);

r=tmp->elem ;

*last=tmp;

return(0);

}

void Show(node *first)

{

node *tmp=first->next;

int el;

unsigned int pol;

char buf[256];

while(tmp!=NULL)

{

el =tmp->elem;

pol =tmp->pol;

inttoname(el ,pol, buf);

tmp=tmp->next;

}

}

void CreatSpisA(int Anom)

{

int dig=0;

unsigned int sv=0;

int dig0=0;

for(int i=0;i<(Anom/2);i++)

{

dig0=0;

dig=Mpars[i*2];// результаты разбора

sv=Mpars[i*2+1];

A.Poisk_Eqv (Afirst, sv,&ARes);

if(ARes!=NULL)

{

dig0=ARes->elem; // такой уже есть- складываем коэффициенты и не добавляем

dig0=dig0+dig;

/// cout << endl<<"poisk pol = "<< ARes->pol<< endl;

if(dig0!=0)

{

A.Izm (ARes, dig0, sv); // складываем коэффициенты и не добавляем

continue;

}

if(dig0==0) // не добавляем и удаляем

{

A.Del1 ();

continue;

}

}

if( A.Poisk_Less (Afirst, sv,&ARes)== 1) {

A.AddLess (&ARes, dig, sv);

}

else {

A.Add(&Alast,dig,sv);

}

}

cout << endl<<"== Приведенный полином A" << endl;

Show(Afirst);

}

void CreatSpisB(int Anom)

{

int dig=0;

unsigned int sv=0;

int dig0=0;

for(int i=0;i<(Anom/2);i++)

{

dig0=0;

dig=Mpars[i*2];// результаты разбора

sv=Mpars[i*2+1];

B.Poisk_Eqv (Bfirst, sv,&BRes);

if(BRes!=NULL)

{

dig0=BRes->elem; // такой уже есть- складываем коэффициенты и не добавляем

dig0=dig0+dig;

if(dig0!=0)

{

B.Izm (BRes, dig0, sv); // складываем коэффициенты и не добавляем

continue;

}

if(dig0==0) // не добавляем и удаляем

{

B.Del1 ();

continue;

}

}

if( B.Poisk_Less (Bfirst, sv,&BRes)== 1) {

B.AddLess (&BRes, dig, sv);

}

else {

B.Add(&Blast,dig,sv);

}

}

cout << endl<<"== Приведенный полином B" << endl;

Show(Bfirst);

}

void Proizvodnay(node *first)

{

node *tmp=first->next;

int el;

unsigned int pol;

char buf[256];

int x,y,z,i;

cout <<endl;

while(tmp!=NULL)

{

el =tmp->elem;

pol =tmp->pol;

x=pol/1000;

y=(pol%1000)/100;

z=((pol%1000)%100)/10;

if(x>1)

{

el=el*x;

x=x-1;

}

pol=x*1000+y*100+z*10;

if(x!=0) B.Add(&Blast,el,pol);

// поскольку исходный полином приведен добавляем все подряд

tmp=tmp->next;

}

cout<<endl<< "производная"<<endl;

Show(Bfirst);

}

void Proizvodnay1(node *Afirst,node *Bfirst,int Anom)

{

node *Atmp=Afirst->next;

int el=5;

int el1;

int rel;

unsigned int pol, pol1, rpol;

char buf[256];

int x,y,z,i;

int x1,y1,z1;

int rx,ry,rz;

int dig=0;

int imonom=0;

unsigned int MMult[500];

int Mi=0;

Mi=0;

imonom=0;

while(Atmp!=NULL)

{

node *Btmp=Bfirst->next;

el =Atmp->elem;

pol =Atmp->pol;

x=pol/1000;

y=(pol%1000)/100;

z=((pol%1000)%100)/10;

// умножаем коэфиициент на степень x

pol=pol*x;

y=0;

z=0;

if (x>1 ) x=x-1;

// вычитаем из степени x

// формируем свертку

pol=x*1000+y*100+z*10;

if(x!=0) B.Add(&Blast,el,pol);

// поскольку исходный полином приведен добавляем все подряд

Atmp=Atmp->next;

} // конец цикла по первому полиному

AntiPars( imonom, Mpars);

// нормализуем результат

cout << endl << "Результат "<< endl;

Show(Bfirst); // антипарсер для полинома

getch();

cout<<endl<< "производная"<<endl;

Show(Bfirst);

}

void Mult(node *Afirst,node *Bfirst,int Anom)

{

node *Atmp=Afirst->next;

int el=5;

int el1;

int rel;

unsigned int pol, pol1, rpol;

char buf[256];

int x,y,z,i;

int x1,y1,z1;

int rx,ry,rz;

int dig=0;

int imonom=0;

unsigned int MMult[500];

int Mi=0;

Mi=0;

imonom=0;

while(Atmp!=NULL)

{

node *Btmp=Bfirst->next;

el =Atmp->elem;

pol =Atmp->pol;

x=pol/1000;

y=(pol%1000)/100;

z=((pol%1000)%100)/10;

while(Btmp!=NULL)

{

el1 =Btmp->elem;

pol =Btmp->pol;

x1=pol/1000;

y1=(pol%1000)/100;

z1=((pol%1000)%100)/10;

// перемножаем элементы

rel=el*el1;

// складывавем степени при x y z

rx=x+x1;

ry=y+y1;

rz=z+z1;

// записываем коэффициент и формируем свертку

Mpars[imonom]=rel;// запоминаем результаты разбора

Mpars[imonom+1]=rx*1000+ry*100+rz*10;

imonom=imonom+2;

Btmp=Btmp->next;

} // конец цикла по второму полиному

Atmp=Atmp->next;

} // конец цикла по первому полиному

AntiPars( imonom, Mpars);

// нормализуем результат

A.DelAll(Afirst,&Alast); // чистим список

CreatSpisA(imonom); //создаем список из массива с доп проверками

cout << endl << "Результат "<< endl;

Show(Afirst); // антипарсер для полинома

getch();

}

int main()

{

A.Initial(&Afirst,&Alast);

B.Initial(&Bfirst,&Blast);

char otv;

int nom;

unsigned int svertka;

char buf[300];

int dig;

int Anom=0;

unsigned int sv;

FILE *in;

do

{

cout // << endl << "1. Отладка" << endl

// << "2. Разбор и свертка полинома" << endl

//<< "3. Развертка и вывод полинома" << endl

///<< "4. Создание списка мономов" << endl

//<< "5. Прогон " << endl

//<< "6. Сдвиг полинома" << endl

<< "1. Операция" << endl

//<< "8. " << endl

//<< "9. " << endl

<< "0. Выход" << endl;

cout << '>';

cin >> otv;

switch(otv)

{

case '88': //+++ отладка

break;

case '2': //

//Anom= getfile(); break;

case '3'://+++

// AntiPars(Anom,Mpars); // разворачиваем полином из буфера

break;

case '4'://+++

// CreatSpis(Anom); //создаем список из массива с доп проверками

break;

case '5'://+++

//Show(Afirst); // антипарсер для полинома

break;

case '6'://+++ // сдвиг полинома

break;

case '1'://+++ операция

cout<<endl<< "--1-сложить";

cout<<endl<< "--2-вычесть";

cout<<endl<< "--3-производная";

cout<<endl<< "--4-умножить"<< endl;

cin >> otv;

//прочитали первый и второй полином для операций с двумя операндами

if(otv=='1') //сложить

{

A.DelAll(Afirst,&Alast); // чистим список

Anom= getfile();

CreatSpisA(Anom); //создаем список из массива с доп проверками

B.DelAll(Bfirst,&Blast); // чистим список

Anom= getfile();

CreatSpisB(Anom); //создаем список из массива с доп проверками

CreatSpisA(Anom); //добавляем в список из массива с доп проверками

getch();

}

if(otv=='2') //вычесть

{

A.DelAll(Afirst,&Alast); // чистим список

Anom= getfile();

CreatSpisA(Anom); //создаем список из массива с доп проверками

B.DelAll(Bfirst,&Blast); // чистим список

Anom= getfile();

CreatSpisB(Anom); //создаем список из массива с доп проверками

AntiPars(Anom, Mpars);

// меняем знак

for(int i=0;i<Anom/2;i++)

{

Mpars[i*2]=(Mpars[i*2])*(-1);// результаты разбора

//dig=Mpars[i*2];

//sv=Mpars[i*2+1];

//inttoname(dig ,sv, buf);

}

AntiPars(Anom, Mpars);

CreatSpisA(Anom); //добавляем в список из массива с доп проверками

getch();

}

if(otv=='3') //призводная нужен только один операнд

{

A.DelAll(Afirst,&Alast); // чистим список

Anom= getfile();

CreatSpisA(Anom); //создаем список из массива с доп проверками

B.DelAll(Bfirst,&Blast); // чистим список

Proizvodnay1(Afirst,Bfirst, Anom);

_getch();

}

if(otv=='4') //умножить

{

A.DelAll(Afirst,&Alast); // чистим список

Anom= getfile();

CreatSpisA(Anom); //создаем список из массива с доп проверками

B.DelAll(Bfirst,&Blast); // чистим список

Anom= getfile();

CreatSpisB(Anom); //создаем список из массива с доп проверками

Mult(Afirst,Bfirst,Anom);

_getch();

}

break;

case '0':// Выход

A.DelAll(Afirst,&Alast);

break;

default:

cout << endl << "Ошибка" << endl;

break;

}

}while(otv!='0');

}

pars6.cpp

#include "stdafx.h"

extern unsigned int Mpars[500];

void AntiPars(int Anom, unsigned int Mpars[])

// разворачивание полинома

// печать полинома из массива в форме xyz

{

int i=0;

int dig;

unsigned int sv;

char buf[256];

printf("\n");

for(int i=0;i<Anom/2;i++)

{

dig=Mpars[i*2];// результаты разбора

sv=Mpars[i*2+1];

inttoname(dig ,sv, buf);

}

printf("\n");

}

void inttoname(int elem ,unsigned int pol,char buffer[])

//разворачивание монома

// вход коэффициент. свертка монома. буфер - строка развернутого монома

{

int j=0;

int x,y,z,i;

i=pol%1000;

x=pol/1000;

y=(pol%1000)/100;

z=((pol%1000)%100)/10;

j = sprintf( buffer," "); // C4996

if(elem!=1) j += sprintf( buffer+j,"%+d",elem); // C4996

if(elem==1) j += sprintf( buffer+j,"+"); // C4996

if(elem==-1) j += sprintf( buffer+j,"-"); // C4996

if(x>1) j += sprintf( buffer+j,"x%d",x); // C4996

if(y>1) j += sprintf( buffer+j,"y%d",y); // C4996

if(z>1) j += sprintf( buffer+j,"z%d",z); // C4996

if(x==1) j += sprintf( buffer+j,"x"); // C4996

if(y==1) j += sprintf( buffer+j,"y"); // C4996

if(z==1) j += sprintf( buffer+j,"z"); // C4996

printf("%s",buffer);

}

int getfile()

{

FILE *in;

char name[200];

char buf[300];

int inom=0;

cout << endl<< "Введите имя файла"<< endl<< "=";

cin >> name;

// printf("\n %s \n",name);

if( (in = fopen( name, "r" )) == NULL ) // C4996

{

printf( "\n Файл не открыт %s\n",name );

_getch();

exit(0);

}

else

{

// printf( "\n Файл открыт %s\n",name );

fgets(buf,200,in);

fclose(in);

inom= Svernut (buf);

}

return(inom);

}

//============================================================

/*

фиксируется старшинство переменных.

Будем считать, что x - самая старшая переменная, затем следует y, затем z.

Для каждого монома определим его "свернутую степень" (индекс).

Для монома xAyBzC+n. индекс равен A*1000+B*100+C*10+n (по условию задачи A, B и C не выше 9).

Старшим считается моном с большей свернутой степенью.

Например, x3y старше xy7z6, так как 310 больше 176.

Например, пусть имеется два полинома:

P(x,y,z)=x7y2z+3x2z-6y2-3z9 и

Q(x,y,z)=-7x2z+6y2+5.

В результате выполнения операции сложения должен быть получен полином R(x,y,z)=x7y2z-4x2z-3z9+5.

вход - исходная строка

выход - свернутый полином в Mpars

выход - количество мономов

*/

int Svernut(char buf[])

{

// int x,y,z;

int i,j,k,l;

char c;

unsigned int sv=0; // 0 to 4,294,967,295

//char buf[128];

char nom[50];

char monom[50];

int pr=0; // признак начала числа

int dig=0;

int imonom=0;

i=0;

cout << endl<< "==Исходный полином: "<< endl ;

cout << buf ;

for(;;)

{

j=0;

if(i>strlen(buf)) break;

c=buf[i];

if(isdigit(c))

{

monom[j]='+';

j++;

}

if(pr==0)

{

if(c=='+'|| c=='-')

{

monom[j]=c;

j++;

i++;

pr=1;

}

if(isdigit(c))

{

monom[j]='+';

j++;

pr=1;

}

} //конец первого монома

for(;;)

{

pr=0;

monom[j]=0x00;

c=buf[i];

if(i>strlen(buf)) break;

if(c=='+'|| c=='-') break;

monom[j]=c;

j++;

i++;

monom[j]=0x00;

} //моном

// разделяем моном на коэффициент и степени

k=0;

for(;;)

{

if(k>=j) break;

c=monom[k];

if(c=='x'|| c=='y'|| c=='z') break;

nom[k]=c;

k++;

}

nom[k]=0x00;

// printf("\n nom=%s",nom); // нашли коффициент

// ищем свертку

for(;;)

{

if(k>=j) break;

c=monom[k];

l=1;

if(k+1<j) // есть что-то дальше

{

if(isdigit( monom[k+1]))

{

l=monom[k+1]-'0';

}

}

if(c=='x')

{

sv=sv+l*1000;

if (l>1 ) k++; // пропускаем степень

}

if(c=='y')

{

sv=sv+l*100;

if (l>1 ) k++; // пропускаем степень

}

if(c=='z')

{

sv=sv+l*10;

if (l>1 ) k++; // пропускаем степень

}

k++;

}

nom[k]=0x00;

dig=atoi(nom);

if(strlen(nom)==1) // это для мономов без коэффициента

{

if(nom[0]=='-') dig=-1;

if(nom[0]=='+' )dig=1;

}

if(dig==0) dig=1;

///printf("\n Коэффициент монома=%s %d",nom ,dig); // нашли коффициент strtoi

if(sv==0) sv=1; // это завершающее число

///printf("\n Свертка монома sv=%d",sv); // нашли свертку

Mpars[imonom]=dig;// запоминаем результаты разбора

Mpars[imonom+1]=sv;

imonom=imonom+2;

sv=0; // пошли наследующий моном

j=0;

} // конец буфера

return(imonom);// количество мономов

}

24

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]