Experiment 2, stack and queue use 2021-10-27

Keywords: C++ data structure linked list

1, Experimental purpose and experimental environment
1. Objective: to master the application of two data structure stacks and queues and complete the corresponding experimental topics;
2. Experimental environment: Window10 64 bit, Dev-C++
2, Experimental content, test data and program operation result analysis
Question 1:

[problem description] suppose that at the weekend ball, men and women form a line when they enter the ballroom. At the beginning of the dance, one person from the head of the men's team and one from the head of the women's team shall be matched as a dance partner. It is stipulated that each dance music can have a pair of dancers. If the initial numbers of the two teams are different, the unpaired in the longer team will wait for the next round of dance music. Now it is required to write a program to simulate the above partner matching problem. (0<m,n,k<1000)
[input form] number of men m and number of women n in the first line; The number of the second line k.
[output form] a total of k lines, with two numbers in each line, indicating the serial number of the paired partner. The man is in the front and the woman is in the back.

[sample input]

2 4
6

[sample output]

1 1
2 2
1 3
2 4
1 1
2 2

Idea: from the title, it is easy to take out the key: the women's team and the men's team are output circularly at the same time, so the circular queue is encapsulated and used.

//SeqQueue.h
#include <iostream>
#include<cstdio>
using namespace std;
class Node {//Define node
	public:
		Node *next;
		int data;
};
class SeqQueue {
	private:
		Node* head;
		int length;//Number of circular list elements 
	public:
		SeqQueue () {
			head = new Node(); 
			head->next = head;
			head->data = 0;
			length = 0;
		}
		~SeqQueue () {
			delete(head);
		}
		void createSeqQueue (int n);  //Create a one-way circular linked list
		void traverseNode(); 		   //Traversal linked list
		void deleteNode(int n);        //Delete node with position n
		void insertNode(int n,int data);//Insert node at specified location
		int getLength();               //Get the length of the linked list
		bool isEmpty();                //Determine whether the linked list is empty
		int getNumber(int n);//Get the element at position n
};
void SeqQueue ::createSeqQueue (int n) {   //Create a one-way circular linked list
	if(n<0) {
		cout << "n error " << endl;
	} else {
		length = n;
		Node *p,*q;
		p = head;
		for(int i=1; i<=n; i++) {
			q = new Node();
			q->data=i;
			p->next = q;
			q->next = head;		//Tail node refers to head node
			p = q;
		}
	}
}
void SeqQueue ::traverseNode() { //Traversal linked list
	Node *p;
	p = head->next;
	while(p!=head) {
		printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}

void SeqQueue ::deleteNode(int n) {    //Delete node at position n
	if(n<0||n>length) {
		printf("delete is  illegal\n");
		return;
	} else {
		Node *p,*q;
		p = head;
		for(int i=1; i<n; i++)//Find n location 
			p=p->next;
		q = p->next;	 
		p->next = q->next;
		delete q;
		q = NULL;
		length--;
	}
}
void SeqQueue ::insertNode(int n,int data) {  //Insert a node at position n, and the value of the node is data
   Node *q,*p = new Node();
   p->data = data;
   q = head;
	for(int i = 1; i<n; i++)//Find n location 
		q = q->next;
	p->next = q->next;//insert 
	q->next = p;
}
int SeqQueue ::getNumber(int n) {
	Node *q = new Node();
	q = head;
	for(int i = 1; i<=n; i++)
		q = q->next;
	return q->data;
}
int SeqQueue ::getLength() {   //Return the length of circular linked list
	return length;
}
bool SeqQueue ::isEmpty() {    //Judge whether it is empty
	return head==head->next;	
}

main

#include <iostream>
#include<cstdio>
#include"SeqQueue.h"
using namespace std;
int main() {
	SeqQueue que_women,que_men;
	int NumberOfwomen,NumberOfmen;//Number of women's team, number of men's team 
	int NumberOfsong;//Number of songs 
	
	scanf("%d%d%d",&NumberOfmen,&NumberOfwomen,&NumberOfsong);
	que_women.createSeqQueue(NumberOfwomen);
	que_men.createSeqQueue(NumberOfmen);
	int i=1;//The men's team is No. i 
	int j=1;//Women's team No. j 
	for(int k=0; k<NumberOfsong; k++) {
		if(i>NumberOfmen) i=1;
		if(j>NumberOfwomen) j=1;
		printf("%d %d\n",que_men.getNumber(i),que_women.getNumber(j));
		i++;
		j++;
	}
	return 0;
}

Performance analysis:
The time complexity is O (k), and K is the number of songs.
Optimization scheme:
When the number of men's and women's teams is small, it is more convenient to use the array for direct circular output, but when the amount of data is large, the continuous memory space may not be enough. At this time, the queue linked list is applied.

#include <iostream>
#include<cstdio>
using namespace std;
const int MAXN=1000;
int women[MAXN],men[MAXN];
int main() {
	int NumberOfwomen,NumberOfmen;//Number of women's team, number of men's team 
	int NumberOfsong;//Number of songs 
	cin>>NumberOfmen>>NumberOfwomen>>NumberOfsong;
	int k;
	for(k=1;k<=NumberOfwomen;k++)
	{
		women[k]=k;
	}
	for(k=1;k<=NumberOfmen;k++)
	{
		men[k]=k;
	}
	int i=1;//The men's team is No. i 
	int j=1;//Women's team No. j 
	for(k=0; k<NumberOfsong; k++) {
		if(i>NumberOfmen) i=1;
		if(j>NumberOfwomen) j=1;
		cout<<men[i]<<" "<<women[j]<<endl;
		i++;
		j++;
	}
	return 0;
}

Output results

Question 2:

[problem description]
Enter a suffix expression and find the value of this expression. The input numbers are integers greater than or equal to zero. The operations involved are addition, subtraction and multiplication. Numbers are separated by spaces. The expression ends with #
[input form] suffix expression with # as ending flag
[output form] calculation result of suffix expression

[sample input]

10 5 2 3 * - 2 * + #

[sample output]

8

Idea: it mainly solves the problem. The input types include shaping and character type. Because the character type is easy to convert to integer type and takes # as the input end flag, the input variable type is character.

//Using str input
#include <iostream>
#include<cstdio>
#include<stack>
#include<cstdlib>
using namespace std;

int main() {
	stack<int> sta;
	string str;
	cin>>str;
	while(str!="#") {
		if(str=="+"||str=="-"||str=="*") {//In case of symbols, take out the stacks top1 and top2 for operation, and store the operation results in the stack
			int n1,n2,sum;
			n1=sta.top();
			sta.pop();
			n2=sta.top();
			sta.pop();
			switch(str[0]) {
				case'+':
					sum=n2+n1;
					break;
				case'-':
					sum=n2-n1;
					break;
				case'*':
					sum=n2*n1;
					break;
			}
			sta.push(sum);
		} else {//In case of numbers, they are stored in the stack
			int temp=atoi(str.c_str());//String to integer
			sta.push(temp);
		}
		cin>>str;
	}
	cout<< sta.top()<<endl;
	return 0;
}
//10 5 2 3 * - 2 * + #

//Using char input
#include <iostream>
#include<cstdio>
#include<stack>
#include<cstdlib>
using namespace std;
int main() {
	stack<int> sta;
	char ch;
	char buffer[10];//Buffer to store temporarily entered integers 
	int i=0,n1,n2;
	int sum;
	scanf("%c",&ch);
	while(ch!='#') {
		while(ch>='0'&&ch<='9') {//Enter integer
			buffer[i++]=ch;
			buffer[i]='\0';
			scanf("%c",&ch);
			if(ch==' ') {//If a space is encountered, enter a complete integer
				int temp=atoi(buffer);
				sta.push(temp);
				i=0;
				break;
			}
		}
		if(ch=='+'||ch=='-'||ch=='*') {
			n1=sta.top();
			sta.pop();
			n2=sta.top();
			sta.pop();
			switch(ch) {
				case'+':
					sum=n1+n2;
					break;
				case'-':
					sum=n2-n1;
					break;
				case'*':
					sum=n2*n1;
					break;
			}
			sta.push(sum);
		}
		scanf("%c",&ch);
	}
	printf("%d\n",sta.top());
	return 0;
}

Operation results

Question 3:

[problem description] first, establish a single linked list and realize the in-situ inversion of the linked list through the stack. Note that only the original node space in the linked list is used, and the data members of the nodes are int. Note that this problem requires two classes: single linked list and stack.
[input form] input only one line, input several integers in turn, separate the integers with a space, and finally end with - 1. Create a single linked list by adding nodes at the end of the table.
[output form] there are two lines of output. The first line is the original linked list data, and the second line is the inverted linked list data. See the sample output for the specific format

[sample input]

1 2 3 4 5 -1

[sample output]

1–>2–>3–>4–>5
5–>4–>3–>2–>1

#include <iostream>
#include"list.h"
#include<cstdio>
#include<stack> 
using namespace std;
int main() {
	List<int>L;
	L.inputRear(-1);//Input single linked list 
	L.output();//Output original single linked list 
	stack<int> sta;
	int x;
	for(int i=0; i<L.Length(); i++) {//Input stack 
		L.getData(i+1,x);	
		sta.push(x);
	}
	for(int i=0; i<L.Length(); i++) {//Stack output, using the first in and last out inverse linked list 
		x=sta.top();
		L.setData(i+1,x);
		sta.pop();
	}
	L.output();
	return 0;
}

Performance analysis:
The time complexity is O (length), and length is the length of the list.
Optimization scheme:
Local inversion can be adopted, but for the linked list, double pointers, one pointer points to the head pointer, the other pointer first traverses to the end of the linked list, and then the data pointed by the two pointers exchange with each other and lean towards the middle until the two pointers point to the same. The time complexity of the two ideas is similar, but the space complexity of the second idea is lower.

2, Problems and solutions in the experiment
In the second problem, the input card has been used for a long time. When using char for input, all inputs and outputs use cin and cout. The operation results are as follows

After repeatedly checking the code, the idea is that there is no logic problem. After debug ging for a long time, it is found that it is an input problem, so query the relevant data. The difference between cin and scanf for character input: when scanf inputs characters, it will absorb '\ n', while when cin inputs characters, 'n' will not be absorbed.

Posted by Dream$of$uccess on Wed, 27 Oct 2021 04:40:39 -0700