Data structure - array - polynomial representation (with complete code)

array

As an abstract data type

  • Abstract data type (ADT)
    For details, see: Data structure - basic concepts - Data
  • For arrays, we can't just treat them as continuous locations of memory locations;
  • Intuitively, an array is a binary < i n d e x , v a l u e > <index, value> Set of < index, value >, each subscript i n d e x index index corresponds to a value associated with it v a l u e value value, mathematically, its correlation becomes correspondence or mapping;
  • Three basic operations of an array: generating a new array, retrieving a value, and storing a value.

Polynomial abstract data type

Ordered table

Array is not only a data structure in itself, but also can be used to implement other abstract data types, including one of the simplest and most commonly used data structures: ordered table. For example, the following examples:

  • The value of the poker decor (Ace, 1, 2...)
  • Every day of the week (Monday, Tuesday...)

Actions to implement in the ordered table:

  • Find the length of the ordered table;
  • Take out and delete the ith element in the table;
  • Storing and inserting a new value at position i;
    . . . . . .

Representation of polynomials

Describe and operate univariate polynomials with ordered tables, such as:

  • a ( x ) = 3 x 2 + 2 x − 4 a(x)=3x^2+2x-4 a(x)=3x2+2x−4
  • b ( x ) = x 8 − 10 x 5 − 3 x 3 + 1 b(x)=x^8-10x^5-3x^3+1 b(x)=x8−10x5−3x3+1

Each polynomial has its order and its corresponding coefficients. For the sum and product of polynomials, suppose a ( x ) = ∑ a i x i a(x)=\sum a_ix^i a(x) = Σ ai xi and b ( x ) = ∑ b i x i b(x)=\sum b_ix^i b(x) = Σ bi xi, then,

  • a ( x ) + b ( x ) = ∑ ( a i + b i ) x i a(x)+b(x)=\sum (a_i+b_i)x^i a(x)+b(x)=∑(ai​+bi​)xi
  • a ( x ) × b ( x ) = ∑ ( a i x i × ∑ ( b j x j ) ) a(x)\times b(x)=\sum (a_ix^i \times\sum(b_jx^j)) a(x)×b(x)=∑(ai​xi×∑(bj​xj))

about P ( x ) = a 0 x e 0 + . . . + a n x e n P(x)=a_0x^{e_0}+...+a_nx^{e_n} P(x)=a0 * xe0 +... + an * xen, polynomial ADT part (member function) is defined as follows, including addition, multiplication and other functions:

class Polynomial 
{
	//P(x) is an ordered set of < e_i, a_i >,
	//a_i (float) is the coefficient of order e_i (int);
public:
	Polynomial();
	//Default constructor 

	Polynomial Add(Polynomial temp);
	//Return the sum of polynomials < * this + temp >

	Polynomial Mult(Polynomial temp);
	//Return polynomial product < * this * temp >

	float Eval(float x);
	//Calculate the value when the * this polynomial variable is x

private:
	// To be determined
};

Next, to determine the representation of private member data, that is, how to represent a polynomial, three representation methods will be introduced below.

Notation 1

private:
	int degree;            //degree<=MaxDegree
	float coef[MaxDegree+1]  //Coefficient array
  • MaxDegree is a constant representing the maximum order of the polynomial class;
  • If a is a class object, the maximum order of a is n , And n ≤ M a x D e g r e e n. And n\le MaxDegree n. And N ≤ MaxDegree, then a ( x ) a(x) a(x) can be expressed as:
    a . d e g r e e = n a.degree = n a.degree=n
    a . c o e f [ i ] = a n − i , 0 ≤ i ≤ n a.coef[i] = a_{n-i},0\le i\le n a.coef[i]=an−i​,0≤i≤n
  • The coefficients are stored in exponential descending order.

Representation 2

If a . d e g r e e a.degree a.degree ratio M a x D e g r e e MaxDegree If MaxDegree is much smaller, it will result in an array a . c o e f [ ] a.coef[ ] a.coef [] most locations will not be used, resulting in a waste of memory. You can define variables c o e f coef coef, with a size of d e g r e e + 1 degree+1 degree+1, private data types are as follows:

private:
	int degree;            //degree<=MaxDegree
	float *coef;           //Coefficient array

Add the constructor as follows:

Polynomial::Polynomial(int d)
{
	degree = d;
	coef = new float[degree+1];
}

Representation 3

Representation 2 solves the problem of representation 1, but for a polynomial, many of its coefficients are 0, that is, "sparse polynomial". For example, polynomial x 1000 + 1 x^{1000}+1 x1000+1, there are only two non-zero coefficients, and the other 999 coefficients are 0. Therefore, we can only store non-0 items and define one T e r m Term The Term class stores non-zero items.

  • The complete definition of polynomial class is as follows:
class Polynomial;

class Term        //Nonzero term
{
	friend Polynomial;
private:
	int exp;       //Nonzero term index
	float coef;    //The coefficient of the non-zero order
};


class Polynomial 
{
private:
	Term* termArray;    //Polynomial nonzero term
	int terms;          //Nonzero terms

public:
	Polynomial(int e[], float c[], int t);
	//Constructor 1

	Polynomial(int t);
	//Constructor 2

	Polynomial();
	//Default constructor 

	void NewTerm(const float theCoef, const int theExp);
	//termArray capacity + 1

	Polynomial Add(Polynomial temp);
	//Return the sum of polynomials < * this + temp >

	Polynomial Mult(Polynomial temp);
	//Return polynomial product < * this * temp >

	float Eval(float x);
	//Calculate the value when the * this polynomial variable is x

	const Polynomial& operator = (const Polynomial& temp);
	//Equal sign overload, subsequent parameter transfer

	void P_Show();
	//Print results
};

Addition of polynomials

Implementation method

  • The polynomial is stored in representation 3 and added, and the function Add will a ( x ) ( ∗ t h i s ) a(x)(*this) a(x)(* this) and b ( x ) b(x) b(x) additive generation c ( x ) c(x) c(x);
  • Because in construction c ( x ) c(x) Constructor called when c(x) (default) t e r m s terms terms is 0), so when adding item by item, it should be expanded c ( x ) . t e r m A r r a y c(x).termArray c(x).termArray capacity, so we first realize the operation of capacity expansion. The code is as follows:
void Polynomial::NewTerm(const float theCoef, const int theExp)
{
	Term* temp = new Term[terms + 1];

	//Copy old termArray to temp
	copy(termArray, termArray + terms, temp);

	//Free old termArray memory
	if(termArray!=NULL)	
		delete[]termArray;

	//The new termArray pointer points to temp
	termArray = temp;

	termArray[terms].exp = theExp;
	termArray[terms++].coef = theCoef;
}
  • Next, perform the addition operation. The code is as follows:
Polynomial Polynomial::Add(Polynomial temp)
{
	Polynomial result;
	int aPos = 0, bPos = 0;

	while (aPos < terms && bPos < temp.terms)
	{
		if (termArray[aPos].exp == temp.termArray[bPos].exp)
		{
			float f = termArray[aPos].coef + temp.termArray[bPos].coef;
			if (f)result.NewTerm(f, termArray[aPos].exp);
			aPos++;
			bPos++;
		}
		else if (termArray[aPos].exp < temp.termArray[bPos].exp)
		{
			result.NewTerm(temp.termArray[bPos].coef, temp.termArray[bPos].exp);
			bPos++;
		}
		else
		{
			result.NewTerm(termArray[aPos].coef, termArray[aPos].exp);
			aPos++;
		}
	}

	//The end of the loop does not completely traverse termArry
	for (; aPos < terms; aPos++)
		result.NewTerm(termArray[aPos].coef, termArray[aPos].exp);
	//The temp.termArray is not completely traversed at the end of the loop
	for (; bPos < temp.terms; bPos++)
		result.NewTerm(temp.termArray[bPos].coef, temp.termArray[bPos].exp);

	return result;
}

function analysis

  • hypothesis a ( x ) a(x) a(x) and b ( x ) b(x) The number of non-zero terms in b(x) is m m m and n n n. In w h i l e while while in each cycle, a P o s and b P o s aPos and bPos aPos and bPos are either increased by 1 respectively or at the same time w h i l e while When the while loop ends, No a P o s = = a . t e r m s aPos==a.terms aPos==a.terms, i.e b P o s = = b . t e r m s bPos==b.terms bPos==b.terms, not completely traversed in the following f o r for Complete traversal in the for loop;
  • The maximum number of repetitions obtained from the analysis is m + n − 1 m+n-1 m+n − 1, so the whole process takes O ( m + n + expand exhibition Allow amount place use Time between ) O(m+n + time taken to expand capacity) O(m+n + time taken to expand capacity), and the time complexity of expanding capacity is O ( 1 ) O(1) O(1), so the time of the whole process is still O ( m + n ) O(m+n) O(m+n).

Polynomial multiplication

  • The polynomial is stored in representation 3 and multiplied, and the function Add will a ( x ) ( ∗ t h i s ) a(x)(*this) a(x)(* this) and b ( x ) b(x) b(x) multiplication c ( x ) c(x) c(x);
  • take a ( x ) ( ∗ t h i s ) a(x)(*this) a(x)(* this) each item and b ( x ) b(x) b(x) is multiplied t e r m s terms terms is a polynomial, and then t e r m s terms The results can be obtained by adding terms polynomials.
    The code is as follows:
Polynomial Polynomial::Mult(Polynomial temp)
{
	Polynomial result;
	Polynomial temp_m(temp.terms);

	for (int i = 0; i < terms; i++)
	{
		for (int j = 0; j < temp.terms; j++)
		{
			temp_m.termArray[j].exp = termArray[i].exp + temp.termArray[j].exp;
			temp_m.termArray[j].coef = termArray[i].coef * temp.termArray[j].coef;
		}
		
		result = result.Add(temp_m);
	}

	return result;
}

Code overview

  • You can define it yourself. Don't print the result for inspection;
#include<iostream>
using namespace std;

class Polynomial;

class Term        //Nonzero term
{
	friend Polynomial;
private:
	int exp;       //Nonzero term index
	float coef;    //The coefficient of the non-zero order
};


class Polynomial 
{
private:
	Term* termArray;    //Polynomial nonzero term
	int terms;          //Nonzero terms

public:
	Polynomial(int e[], float c[], int t);
	//Constructor 1

	Polynomial(int t);
	//Constructor 2

	Polynomial();
	//Default constructor 

	void NewTerm(const float theCoef, const int theExp);
	//termArray capacity + 1

	Polynomial Add(Polynomial temp);
	//Return the sum of polynomials < * this + temp >

	Polynomial Mult(Polynomial temp);
	//Return polynomial product < * this * temp >

	float Eval(float x);
	//Calculate the value when the * this polynomial variable is x

	const Polynomial& operator = (const Polynomial& temp);
	//Equal sign overload

	void P_Show();
	//Print results
};

Polynomial::Polynomial(int e[], float c[], int t)
{
	terms = t;
	termArray = new Term[t];
	for (int i = 0; i < t; i++)
	{
		termArray[i].exp = e[i];
		termArray[i].coef = c[i];
	}
}

Polynomial::Polynomial(int t)
{
	terms = t;
	termArray = new Term[terms];
}

Polynomial::Polynomial()
{
	terms = 0;
	termArray = NULL;
}

void Polynomial::NewTerm(const float theCoef, const int theExp)
{
	Term* temp = new Term[terms + 1];

	//Copy old termArray to temp
	copy(termArray, termArray + terms, temp);

	//Free old termArray memory
	if(termArray!=NULL)	
		delete[]termArray;

	//The new termArray pointer points to temp
	termArray = temp;

	termArray[terms].exp = theExp;
	termArray[terms++].coef = theCoef;
}

Polynomial Polynomial::Add(Polynomial temp)
{
	Polynomial result;
	int aPos = 0, bPos = 0;

	while (aPos < terms && bPos < temp.terms)
	{
		if (termArray[aPos].exp == temp.termArray[bPos].exp)
		{
			float f = termArray[aPos].coef + temp.termArray[bPos].coef;
			if (f)result.NewTerm(f, termArray[aPos].exp);
			aPos++;
			bPos++;
		}
		else if (termArray[aPos].exp < temp.termArray[bPos].exp)
		{
			result.NewTerm(temp.termArray[bPos].coef, temp.termArray[bPos].exp);
			bPos++;
		}
		else
		{
			result.NewTerm(termArray[aPos].coef, termArray[aPos].exp);
			aPos++;
		}
	}

	//The end of the loop does not completely traverse termArry
	for (; aPos < terms; aPos++)
		result.NewTerm(termArray[aPos].coef, termArray[aPos].exp);
	//The temp.termArray is not completely traversed at the end of the loop
	for (; bPos < temp.terms; bPos++)
		result.NewTerm(temp.termArray[bPos].coef, temp.termArray[bPos].exp);

	return result;
}

Polynomial Polynomial::Mult(Polynomial temp)
{
	Polynomial result;
	Polynomial temp_m(temp.terms);

	for (int i = 0; i < terms; i++)
	{
		for (int j = 0; j < temp.terms; j++)
		{
			temp_m.termArray[j].exp = termArray[i].exp + temp.termArray[j].exp;
			temp_m.termArray[j].coef = termArray[i].coef * temp.termArray[j].coef;
		}
		result = result.Add(temp_m);
	}

	return result;
}

float Polynomial::Eval(float x)
{
	P_Show();
	cout << "x=" << x << "When, P(x)=";
	float result = 0;

	for (int i = 0; i < terms; i++)
	{
		float n = 1;
		for (int j = 0; j < termArray[i].exp; j++)
		{
			n *= x;
		}
		n *= termArray[i].coef;
		result += n;
	}

	return result;
}

const Polynomial& Polynomial:: operator = (const Polynomial& temp)
{
	terms = temp.terms;
	if (termArray != NULL)
		delete[]termArray;

	termArray = new Term[terms];
	copy(temp.termArray, temp.termArray + terms, termArray);

	return *this;
}

void Polynomial::P_Show()
{
	cout << "The polynomial is: P(x)=" ;
	if (terms > 0)
	{
		int i = 0;
		while (i < terms)
		{
			if (termArray[i].coef > 0)cout << "+" << termArray[i].coef;		
			else cout << termArray[i].coef;

			if (termArray[i].exp != 0)cout << "x^" << termArray[i].exp<<"\t";
				i++;
		}
	}
	else cout << 0;
	
	cout << ",\t The number of items is:"<<terms <<endl<< endl;
}


int main()
{
	int e1[5] = { 20,15,12,8,0 }, e2[4] = { 30,20,15,8 };
	float c1[5] = { 4,-1,5,6,9 }, c2[4] = { 2,1,-7,6 };

	Polynomial a(e1, c1, 5), b(e2, c2, 4),c;

	a.P_Show();
	b.P_Show();

	c = a.Add(b);
	c.P_Show();

	c = a.Mult(b);
	c.P_Show();

	cout << a.Eval(2.5);
	
	return 0
}

Tags: Algorithm data structure

Posted on Sat, 20 Nov 2021 19:44:09 -0500 by ThEMakeR