Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Описание структуры хранения данных

Факультет вычислительной математики и кибернетики

 

ОТЧЕТ

по лабораторной работе № 4

«Аналитические преобразования полиномов

от нескольких переменных»

 

Выполнил: студент группы 8210

__________________Баранов А.М. Проверил:

__________________Сидоров С.В.

 

 

Нижний Новгород

2011 г.

Оглавление

Аннотация. 3

Введение. 3

Постановка задачи. 3

Руководство пользователя. 4

Руководство программиста. 6

Описание структуры хранения данных. 6

Описание программы.. 7

Описание алгоритма. 7

Заключение. 10

Литература. 11

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

 

 


Аннотация

В данной работе рассматриваются вопросы реализации некоторых базовых аналитических преобразований и операций над полиномами от нескольких переменных.

Для хранения полиномов используются однонаправленные динамические списки.

Введение

Списки являются чрезвычайно гибкой структурой, так как их легко сделать большими или меньшими, и их элементы доступны для вставки или удаления в любой позиции списка. Списки также можно объединять или разбивать на меньшие списки.

Списки регулярно используются в приложениях, например в программах информационного поиска, трансляторах программных языков или при моделировании различных процессов. Методы управления памятью в современных вычислительных системах широко используют технику обработки списков.

Постановка задачи

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

· ввод полиномов;

· вывод полиномов;

· удаление полиномов;

· приведение полиномов

· сложение полиномов;

· Вычитание полиномов;

· Производная от полинома;

· Умножение полиномов

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

Программа должна обеспечивать диалоговый интерфейс с пользователем обеспечивающий ввод исходных данных из заранее подготовленного файла с заданным именем.

 


Руководство пользователя

 

После запуска исполняемого файла программы вы увидите главное окно программы (рис. 1).

Рис. 1. Главное окно программы.

 

Основные операции.

 

Операция сложения/вычитания/умножения полиномов:

· Выбирается пункт меню 1/2/4;

· Вводится имя файла с первым полиномом;

· Выводится исходный неприведенный полином;

· Выводится приведенный полином;

· Вводится имя файла со вторым полиномом;

· Выводится исходный неприведенный полином;

· Выводится приведенный полином;

· Выводится результат в приведенном виде.

Рис. 2. Выполнение операции сложения.

 

 

Рис.3. Результат операции вычитания.

Рис.4. Результат операции умножения.

 

 

Операция вычисления производной:

· Выбирается пункт меню 3;

· Вводится имя файла с полиномом;

· Выводится исходный неприведенный полином;

· Выводится приведенный полином;

· Выводится результат в приведенном виде.

 

 

Рис.5.Результат вычисления производной.

 

Руководство программиста

Описание структуры хранения данных

 

При манипуляции разреженными полиномами эффективной структурой хранения являются списки.

В качестве структуры хранения данных полинома был выбран однонаправленный динамический список. Каждый узел содержит два элемента содержащие атрибуты монома

elem - коэфффициент монома

pol – свертка монома

под сверткой монома имеется в виду вычисляемое целое число без знака вычисляемое в соответствии со следующими правилами

 

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

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

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

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

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

Свертка монома служит в дальнейшем ключом для идентификации монома

Кроме этого в каждый узел входит ссылка на следующий элемент списка

Для хранения промежуточного результата синтаксического разбора исходной строки используется массив Mpars

unsigned int Mpars[500];

 

node *Bfirst, *Blast;

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

node *Afirst, *Alast;

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

 

struct node {

int elem;

unsigned int pol;

node *next;

};

Для хранения полинома класс Spisok

class Spisok

{

private:

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 ();

};

 

Описание программы

 

Программа использует класс Spisok

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 ();

};

 

Описание алгоритма

Работа программы начинается с вывода основного меню. Для начала работы выбирается пункт

"1.Операции"

 

При этом осуществляется запрос имени файла, где хранится описание полинома.

 

Ввод полинома. Ввод полинома реализуется как текстовая строка с формульным выражением, описывающим вводимый полином. Форма задания полинома производится образом, аналогичным примеру:

P='x7y2z1+3x2z1-6y2-3z9 '

Q='-7x2z1+6y2+5'

Коэффициенты мономов имеют целочисленный тип. При вводе полинома производится синтаксический разбор строки и приведение монома к стандартному виду – коэффициент со знаком и свертка.

Вывод полинома. Вывод полинома осуществляется обходом списка и печатью коэффициента и степеней переменных каждого монома. Следует отметить, что голова полинома играет роль барьера при обходе списка: цикл завершается, когда текущим звеном окажется головное звено.

Рекомендуемая форма печати полинома состоит в представлении полинома в виде текстовой строки с формульным выражением, описывающим полином. Например, полином P(x,y,z) из контрольного примера может быть представлен как строка:

P(x,y,z)='x7y2z1-4x2z1-3x9+5'

Реализация алгоритмов обработки полиномов организуется путем следующих шагов

1. Производится считывание исходной строки полинома с stdin ()

2. Выполняется анализ исходной строки на наличие запрещенных символов

3. Организуется однонаправленный список мономов многочлена каждый элемент которого содержит коэффициент монома, свертку степеней переменных и ссылку на следующий элемент. При создании списка производится нормализация полинома по совпадающим сверткам и его реорганизация в соответствии с убыванием модуля сверток

4. Если свернутые степени мономов совпадают, то осуществляется приведение подобных членов: к коэффициенту монома полинома P прибавляется коэффициент монома полинома Q. Если при этом сумма коэффициентов оказывается равной нулю, то соответствующий моном полинома P исключается из списка.

 

 

Для полиномов реализованы следующие функции:

· Сложение и вычитание

· Умножение

· Взятие производной. Для сложения полиномов P и Q производится одновременный обход обоих списков, начиная с головных звеньев, по правилу слияния упорядоченных массивов. Сумма формируется на месте первого слагаемого (P). При этом, если свернутая степень текущего монома полинома Q больше свернутой степени текущего монома полинома P, то копия монома полинома Q вставляется в полином P; в полиноме Q осуществляется переход на следующее звено. Если свернутая степень текущего монома полинома P больше свернутой степени текущего монома полинома Q, то в полиноме P осуществляется переход на следующее звено. Если свернутые степени текущих мономов полиномов P и Q совпадают, то осуществляется приведение подобных членов: к коэффициенту монома полинома P прибавляется коэффициент монома полинома Q. Если при этом сумма коэффициентов оказывается равной нулю, то соответствующий моном полинома P исключается из списка. В обоих списках осуществляется переход к следующему звену. Для реализации операций вставки и удаления звеньев в односвязных списках необходимы указатели как текущего, так и предыдущего звеньев.

· Удаление полинома. При удалении полинома предлагается немедленно возвращать освободившуюся память в кучу. В этом случае не образуется мусор из освободившихся звеньев. При удалении полинома осуществляется обход списка аналогично предыдущей операции, и каждое звено возвращается в кучу процедурой Dispose(q).

 


Заключение

 

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

 


Литература

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);// количество мономов

}

 



<== предыдущая лекция | следующая лекция ==>
Межгосударственные региональные конфликты. | Сведения о государственной регистрации общества.
Поделиться с друзьями:


Дата добавления: 2016-11-18; Мы поможем в написании ваших работ!; просмотров: 582 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Студенческая общага - это место, где меня научили готовить 20 блюд из макарон и 40 из доширака. А майонез - это вообще десерт. © Неизвестно
==> читать все изречения...

2389 - | 2339 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.014 с.