《算法笔记》第7章——数据结构专题(1)栈,队列,以及链表

7.1 栈

7.2 队列

栈和队列最经典的题目就是下面两个,中缀转前缀表达式实现计算器的功能,第二个是判断表达式是否正确;
第一个上次囫囵的看了一遍,其实也没咋懂
⭐⭐⭐⭐问题 A: 简单计算器
问题描述:读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。

  • 输入
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
  • 输出
在这里插入代码片对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。```
- 样例输入
 ```cpp
30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
0
  • 样例输出
12178.21

在这里插入图片描述
参考网址:https://www.cnblogs.com/zhengxunjie/p/10372329.html

⭐⭐⭐⭐问题 B: Problem E
问题描述:请写一个程序,判断给定表达式中的括号是否匹配,表达式中的合法括号为”(“, “)”, “[", "]“, “{“, ”}”,这三个括号可以按照任意的次序嵌套使用。

  • 输入
有多个表达式,输入数据的第一行是表达式的数目,每个表达式占一行。
  • 输出
对每个表达式,若其中的括号是匹配的,则输出”yes”,否则输出”no”。
  • 样例输入
4
[(d+f)*{}]
[(2+3))
()}
[4(6]7)9
  • 样例输出
yes
no
no
no

这里是直接计算中缀表达式的方法

#include<iostream>  
#include<string>  
#include<stack>  

using namespace std;

int getPriority(char ch)
{
    //获取优先级  
    if (ch == '(') return 1;
    else if (ch == '+' || ch == '-') return 2;
    else if (ch == '*' || ch == '/') return 3;
    else return 4;
}

void calculate(stack<double>& mystack, char operation)
{
    double num1, num2, num3;
    num2 = mystack.top();
    mystack.pop();
    num1 = mystack.top();
    mystack.pop();
    if (operation == '+') {
        num3 = num1 + num2;
    }
    else if (operation == '-') {
        num3 = num1 - num2;
    }
    else if (operation == '*') {
        num3 = num1 * num2;
    }
    else if (operation == '/') {
        num3 = num1 / num2;
    }

    mystack.push(num3);
}

double calculator(string str)
{
    //计算中缀表达式,默认输入是合法的  
    stack<double> mystack_number;
    stack<char> mystack_operation;
    int i = 0, j;
    int size = str.size();
    char tmp_operation;
    string tmp_num;
    while (i < size) {
        if (str[i] >= '0' && str[i] <= '9') {
            j = i;
            while (j < size && str[j] >= '0' && str[j] <= '9') { j++; }
            tmp_num = str.substr(i, j - i);
            mystack_number.push(atoi(tmp_num.c_str()));
            i = j;
        }
        else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/') {
            if (mystack_operation.empty()) {
                mystack_operation.push(str[i]);
            }
            else {
                while (!mystack_operation.empty()) {
                    tmp_operation = mystack_operation.top();
                    if (getPriority(tmp_operation) >= getPriority(str[i])) {
                        //计算  
                        calculate(mystack_number, tmp_operation);
                        mystack_operation.pop();
                    }
                    else break;
                }
                mystack_operation.push(str[i]);
            }
            i++;
        }
        else {
            if (str[i] == '(') mystack_operation.push(str[i]);
            else {
                while (mystack_operation.top() != '(') {
                    tmp_operation = mystack_operation.top();
                    //计算  
                    calculate(mystack_number, tmp_operation);
                    mystack_operation.pop();
                }
                mystack_operation.pop();
            }
            i++;
        }

    }
    //遍历完后,若栈非空,弹出所有元素  
    while (!mystack_operation.empty()) {
        tmp_operation = mystack_operation.top();
        //计算  
        calculate(mystack_number, tmp_operation);
        mystack_operation.pop();
    }
    return mystack_number.top();
}

int main()
{
    string str;
    while (getline(cin, str), str != "0")
    {

        for (string::iterator it = str.begin(); it != str.end(); it++)
        {
            if (*it == ' ') str.erase(it);
        }
        //cout << "中缀表达式为:" << endl << str << endl;
        double num_res = calculator(str);
        printf("%.2f\n",num_res);
    }    
 
    return 0;
}

这份代码是错的,不知道原因:

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <cstdio>
#include <string>
#include <stack>
#include<queue>
#include<map>
using namespace std;
struct node {
    double num;
    char op;
    int flag;//flag=0表示操作符,=1表示操作数
};
string str;
stack<node> s;
queue<node> q;
map<char, int> op;
//生成后缀表达式,默认输入的中缀表达式是合法的
void Change()
{
    double num;
    node temp;
    for (int i = 0; i < str.length();)
    {
        if (str[i] >= '0' && str[i] <= '9')
        {
            temp.flag = 1;
            temp.num = str[i++] - '0';
            //printf("%c-%d\n",str[i],temp.num);
            while (i < str.length() && str[i] >= '0' && str[i] <= '9')
            {
                temp.num = temp.num * 10 + (str[i] - '0');
                i++;
            }
            q.push(temp);//将数字直接放进队列中
           
        }
        else
        {
            temp.flag = 0;
            while (!s.empty() && op[str[i]] <= op[s.top().op])//比较操作符的优先级
            {
                q.push(s.top());//不断把栈顶的操作符弹出到队列中
               // printf("%c",s.top().op);
                s.pop();
            }
            temp.op = str[i];
            s.push(temp);
            i++;
        }
        while (!s.empty())//如果还有操作符,全都放到队列中
        {
            q.push(s.top());         
            s.pop();
        }
    }
   
}

double Cal()//计算后缀表达式
{
    double temp1, temp2;
    node cur, temp;
    while (!q.empty())
    {
        cur = q.front();
        q.pop();
        if (cur.flag == 1) s.push(cur);
        else
        {
            temp2 = s.top().num;//弹出第二操作数
            s.pop();
            temp1 = s.top().num;
            s.pop();//弹出第一操作数
            temp.flag = 1;
            if (cur.op == '+') temp.num = temp1 + temp2;
            else if (cur.op == '-') temp.num = temp1 - temp2;
            else if (cur.op == '*') temp.num = temp1 * temp2;
            else temp.num = temp1 / temp2;
            s.push(temp);
        }
    }
    return s.top().num;
}
int main()
{
    op['+'] = op['-'] = 1;
    op['*']=op['/']=2;
    while (getline(cin,str),str!="0")
    {
       
        for (string::iterator it=str.begin(); it != str.end(); it++)
        {
            if (*it == ' ') str.erase(it);
        }
        
        while (!s.empty()) s.pop();//初始化栈s
       
       // cout << str;
       // printf("\n");
        Change();
        printf("%.2f\n",Cal());
    }
    return 0;
}

7.3 链表

怎样判断何时使用顺序表何时使用链表呢?就要看它们的特点了。顺序表的特点是随机存取、随机访问,也就是说如果存取和查询比较频繁的话使用顺序表比较合适;链表的特点是插入和删除时不必移动其后的节点,如果插入和删除操作比较频繁的话使用链表比较合适。
链表的基本操作
1.创建链表
2.查找元素
3.删除元素

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
struct node {
	int data;
	node* next;
};
//创建链表
node* create(int Array[])
{
	node* p, * pre, * head;
	head = new node;
	head->next = NULL;
	pre = head;
	for (int i = 0; i < 5; i++)
	{
		p = new node;
		p->data = Array[i];
		p->next = NULL;
		pre->next = p;
		pre = p;
	}
	return head;
}
int search(node* head, int x)
{
	int count = 0;
	node* p = head->next;
	while (p != NULL)
	{
		if (p->data == x)
		{
			count++;
		}
		p = p->next;
	}
	return count;
}
void del(node* head, int x)
{
	node* p = head->next;
	node* pre = head;
	while (p != NULL)
	{
		if (p->data == x)
		{
			pre->next = p->next;
			delete(p);
			p = pre->next;
		}
		else
		{
			pre = p;
			p = p->next;
		}
	}
}
int main()
{
	int Array[5] = { 5,4,3,2,1 };
	node* head = create(Array);
	node* temp;
	temp = head;
	temp = temp->next;
	while(temp !=NULL){
		printf("%d ", temp->data);
		temp = temp->next;
	}
	//下面删除3
	temp = head;
	del(temp,3);
	temp = head;
	while (temp != NULL) {
		printf("%d ", temp->data);
		temp = temp->next;
	}
	return 0;
}

静态链表
一般使用结构体数组存放静态链表
PAT A1032 Sharing (25 分)
问题描述:在这里插入图片描述

  • 输入
每个输入文件包含一个测试用例。对于每种情况,第一行包含两个节点地址和一个正N (10 
5
 ),其中两个地址是两个字的第一个节点的地址,并且 N是节点总数。节点地址为5位正整数,NULL表示为−1.

然后 N 下面几行,每行描述一个节点的格式:

Address Data Next
其中Address是节点的位置,Data是该节点包含的字母是从{ az, AZ } 中选择的一个英文字母,Next是下一个节点的位置。
  • 输出
对于每种情况,只需输出公共后缀的 5 位起始位置。如果这两个词没有共同的后缀,则-1改为输出。
  • 样例输入
11111 22222 9
67890 i 00002
00010 a 12345
00003 g -1
12345 D 67890
00002 n 00003
22222 B 23456
11111 L 00001
23456 e 67890
00001 o 00010
  • 样例输出
67890
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<cstring>
const int maxn = 100010;
struct Node {
	char data;//存放的字母
	int next;//下一个节点的地址
	int flag;
}node[maxn];
int main()
{
	int i;
	for (i = 0; i < maxn; i++)
	{
		node[i].flag = 0;
	}//所有节点的flag初始化为0,表示没有出现过
	int s1, s2, n;
	scanf("%d %d %d", &s1, &s2, &n);
	int address, next;
	char data;
	for (i = 0; i < n; i++)
	{
		scanf("%d %c %d",&address,&data,&next);
		node[address].data = data;
		node[address].next = next;
	}
	int p ;
	for (p = s1; p != -1; p = node[p].next)
	{
		node[p].flag = 1;
	}
	for (p = s2; p != -1; p = node[p].next)
	{
		if (node[p].flag == 1)
			break;
	}
	if (p != -1)
		printf("%05d\n", p);
	else
		printf("-1\n");
	return 0;
}

PAT A1052链表排序(25分)
问题描述:链表由一系列结构组成,这些结构在内存中不一定相邻。我们假设每个结构都包含一个整数key和一个Next指向下一个结构的指针。现在给定一个链表,您应该根据它们的键值按递增顺序对结构进行排序。

  • 输入
每个输入文件包含一个测试用例。对于每种情况,第一行包含一个正数N (<10 
5
 ) 和头节点的地址,其中 N是内存中节点的总数,节点的地址是一个 5 位正整数。NULL 表示为−1.

然后 N 下面几行,每行描述一个节点的格式:

Address Key Next
其中Address是节点在内存中的地址,Key是[中的整数−10 5 ,10 5 ],Next是下一个节点的地址。保证所有的key都是不同的,从头节点开始的链表中没有循环。
  • 输出
对于每个测试用例,输出格式与输入格式相同,其中 N 是列表中的节点总数,所有节点必须排序。
  • 样例输入
5 00001
11111 100 -1
00001 0 22222
33333 100000 11111
12345 -1 33333
22222 1000 12345
  • 样例输出
5 12345
12345 -1 00001
00001 0 11111
11111 100 22222
22222 1000 33333
33333 100000 -1

这题说是静态链表,其实就是结构体的排序啦,注意区别
1.判断节点在不在链表里面,有可能题目给的节点不在链表里面
2.在排好序之后,链表内每个节点的后继节点还没有改掉,这时候可以省事的直接输出node[i+1].address,也可以改node[i].next为node[i+1].address

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100010;
struct Node {

	int next;//下一个节点的地址
	int key;//键值
	int flag;//=0表示不在链表里面,=1表示在链表里面
	int address;//本节点的地址
}node[maxn];
bool cmp(Node a,Node b){
	if (a.flag == 0 || b.flag == 0)
		return a.flag > b.flag;
	else
		return a.key < b.key;
}
int main()
{
	int s1, n;
	int i;
	int address, key, next;
	scanf("%d %d",&n,&s1);
	for (i = 0; i < maxn; i++)
	{
		node[i].flag = 0;//表示都不在链表里面
	}

	for (i = 0; i < n; i++)
	{
		scanf("%d %d %d", &address, &key, &next);		
		node[address].key = key;
		node[address].next = next;
		node[address].address = address;
	}
	int p = s1;
	int count = 0;
	while (p != -1)
	{
		node[p].flag = 1;
		count++;
		p = node[p].next;
	}
	if (count == 0)
		printf("0 1");
	else
	{
		sort(node, node + maxn, cmp);
		
		printf("%d %05d\n", count, node[0].address);
		for (i = 0; i < count-1; i++)
		{
			node[i].next = node[i + 1].address;
		}
		node[count - 1].next = -1;
		for (i = 0; i < count-1; i++)
		{
			printf("%05d %d %05d\n", node[i].address, node[i].key, node[i].next);
		}
		printf("%05d %d %d\n", node[count-1].address, node[count-1].key, node[count-1].next);
	}
	return 0;
}

问题 A: 算法2-8~2-11:链表的基本操作
大量的查找与删除操作需要使用链表,比较节省时间。
问题描述:

  • 输入
输入数据只有一组,第一行有n+1个整数,第一个整数是这行余下的整数数目n,后面是n个整数。这一行整数是用来初始化列表的,并且输入的顺序与列表中的顺序相反,也就是说如果列表中是123那么输入的顺序是321。
第二行有一个整数m,代表下面还有m行。每行有一个字符串,字符串是“get”,“insert”,“delete”,“show”中的一种。如果是“get”或者“delete”,则其后跟着一个整数a,代表获得或者删除第a个元素;如果是“insert”,则其后跟着两个整数a和e,代表在第a个位置前面插入e;“show”之后没有整数。
  • 输出
如果获取成功,则输出该元素;如果删除成功则输出“delete OK”;如果获取失败或者删除失败,则输出“get fail”以及“delete fail”。如果插入成功则输出“insert OK”,否则输出“insert fail”。如果是“show”则输出列表中的所有元素,如果列表是空的,则输出“Link list is empty”。注:所有的双引号均不输出。
  • 样例输入
3 3 2 1
21
show
delete 1
show
delete 2
show
delete 1
show
delete 2
insert 2 5
show
insert 1 5
show
insert 1 7
show
insert 2 5
show
insert 3 6
show
insert 1 8
show
get 2
  • 样例输出
1 2 3
delete OK
2 3
delete OK
2
delete OK
Link list is empty
delete fail
insert fail
Link list is empty
insert OK
5
insert OK
7 5
insert OK
7 5 5
insert OK
7 5 6 5
insert OK
8 7 5 6 5
7
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node {
	int data;
	node* next;
};
//创建链表
node * create(int n)
{
	node* p;
	int i;
	node* head;
	head = new node;
	head->next = NULL;
	for (i = n; i > 0; i--)
	{
		p = new node;
		scanf("%d",&p->data);
		//printf("%d\n",p->data);
		p->next = head -> next;
		head->next = p;
	}	
	return head;
}
void show(node* head, int num)
{
	if (num == 0)
	{
		printf("Link list is empty\n");
		
	}
	else
	{
		node* p;
		p = head->next;
		for (int i = 0; i < num - 1; i++)
		{
			printf("%d ", p->data);
			p = p->next;
		}
		printf("%d\n", p->data);
	}
	return;
}

void insert(node* head, int a,int e,int num)
{
	if (a > num + 1)
	{
		printf("insert fail\n");
	}
	else
	{		
		node* p = head->next;
		node* pre=head;
		for (int i = 0; i < a - 1; i++)
		{
			pre = p;
			p = p->next;
		}
		node* q;
		q = new node;
		q->data = e;
		q->next = p;
		pre->next = q;
		printf("insert OK\n");
	}

	return;
}
void get(node* head, int x,int num)
{
	if (x > num)
	{
		printf("get fail\n");
	}
	else
	{
		node* p = head->next;
		
		for (int i = 0; i < x - 1; i++)
		{
			
			p = p->next;
		}
		printf("%d\n",p->data);
	}
	
	
	return;
	
}
void del(node* head, int x,int num)//删除第x号元素
{
	if(x>num)
	{
		printf("delete fail\n");
		return;
	}
	node* p = head->next;
	node* pre = head;

	for (int i = 0; i < x-1; i++)
	{
		pre = p;
		p = p->next;
	}
	pre->next = p->next;
	delete(p);
	printf("delete OK\n");
	return;
	
}
int main()
{
	int n, m;
	scanf("%d", &n);
	int i,j;
	char s[10];
	node* head;
	int num;
	int temp;
	int temp2;
	head=create(n);//创建链表
	
	num = n;

	
	scanf("%d", &m);
	for (i = 0; i < m; i++)
	{
		scanf("%s",s);
		
		if (strcmp(s,"show")==0)
		{
			//printf("!!!");
			show(head,num);
		}
		else if (strcmp(s, "delete") == 0)
		{
			scanf("%d", &temp);
			del(head, temp,num);
			num--;
		}
		else if (strcmp(s, "get") == 0)
		{
			scanf("%d", &temp);
			get(head, temp,num);			
		}
		else if (strcmp(s, "insert") == 0)
		{
			scanf("%d %d", &temp,&temp2);
			insert(head, temp, temp2,num);
			num++;
		}
	}
	return 0;
}

问题 B: C语言-链表排序
问题描述:已有a、b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号升序排列。

  • 输入
第一行,a、b两个链表元素的数量N、M,用空格隔开。 接下来N行是a的数据 然后M行是b的数据 每行数据由学号和成绩两部分组成
  • 输出
按照学号升序排列的数据
  • 样例输入
2 3
5 100
6 89
3 82
4 95
2 10
  • 样例输出
2 10
3 82
4 95
5 100
6 89

静态链表+结构体排序

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 100010;
struct student {
	int id;
	int scores;
	int flag;
}stu[maxn];
bool cmp(student a, student b)
{
	if (a.flag == 0 || b.flag == 0)
		return a.flag > b.flag;
	else
		return a.id < b.id;
}
int main()
{
	int n, m;
	scanf("%d %d", &n,&m);
	int sum = m + n;

	int i;
	int id, scores;
	for (i = 0; i < maxn; i++)
	{
		stu[i].flag = 0;
	}
	for (i = 0; i < sum; i++)
	{
		scanf("%d %d",&id,&scores);
		stu[id].id = id;
		stu[id].scores = scores;
		stu[id].flag = 1;
	}
	sort(stu, stu + maxn, cmp);
	for (i = 0; i < sum; i++)
	{
		printf("%d %d\n",stu[i].id,stu[i].scores);
	}
	return 0;
}

问题 C: 最快合并链表(线性表)
问题描述:知L1、L2分别为两循环单链表的头结点指针,m,n分别为L1、L2表中数据结点个数。要求设计一算法,用最快速度将两表合并成一个带头结点的循环单链表。

  • 输入
m=5
3 6 1 3 5
n=4.
7 10 8 4
  • 输出
3 6 1 3 5 7 10 8 4
  • 样例输入
7
3 5 1 3 4 6 0
5
5 4 8 9 5
  • 样例输出
3 5 1 3 4 6 0 5 4 8 9 5

偷懒写法(逃

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;

int main()
{
	int num;
	int i, n;
	while (scanf("%d", &n) != EOF)
	{
		for (i = 0; i < n; i++)
		{
			scanf("%d",&num);
			printf("%d ",num);
		}
		//printf("!!!");
	}
	return 0;
}

问题 D: 链表查找(线性表)
问题描述:线性表(a1,a2,a3,…,an)中元素递增有序且按顺序存储于计算机内。要求设计一算法完成:
(1) 用最少时间在表中查找数值为x的元素。
(2) 若找到将其与后继元素位置相交换。
(3) 若找不到将其插入表中并使表中元素仍递增有序。

  • 输入
输入:x=3
输入长度:9
输入数据:2 3 5 7 12 15 17 23 45
  • 输出
相同元素为:3
交换后的链表为:2 5 3 7 12 15 17 23 45
  • 样例输入
4
9
2 3 5 7 12 15 17 23 45
  • 样例输出
no
2 3 4 5 7 12 15 17 23 45 

使用set,自动有序,如果找到了该元素,就先输出后面的元素,再输出该元素

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<set>
using namespace std;

int main()
{
	int num;
	int n;
	int temp,temp1;
	int i;
	set<int> st;
	scanf("%d%d",&num,&n);//计算得到Num和n
	for (i = 0; i < n; i++)
	{
		scanf("%d",&temp);
		st.insert(temp);
	}
	set<int>::iterator it = st.find(num);
	if (it == st.end())//如果没有找到该元素
	{
		printf("no\n");
		st.insert(num);
		for (it = st.begin(); it != st.end(); it++)
		{
			printf("%d ",*it);
		}
	}
	else//如果找到了该元素
	{
		//printf();
		for (set<int>::iterator it1 = st.begin(); it1 != st.end(); it1++)
		{
			if (it1 == it)
			{
				it1++;
				printf("%d ", *it1);				
				printf("%d ", *it);
			}
			else
			{
				printf("%d ", *it1);
			}
			
		}
	}
	return 0;
}

问题 E: 算法2-24 单链表反转
问题描述:根据一个整数序列构造一个单链表,然后将其反转。
例如:原单链表为 2 3 4 5 ,反转之后为5 4 3 2

  • 输入
输入包括多组测试数据,每组测试数据占一行,第一个为大于等于0的整数n,表示该单链表的长度,后面跟着n个整数,表示链表的每一个元素。整数之间用空格隔开
  • 输出
针对每组测试数据,输出包括两行,分别是反转前和反转后的链表元素,用空格隔开
如果链表为空,则只输出一行,list is empty
  • 样例输入
5 1 2 3 4 5 
0
  • 样例输出
1 2 3 4 5 
5 4 3 2 1 
list is empty

基础题,我对链表的信心猛涨(一定是错觉)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<set>
using namespace std;
const int maxn = 100010;
int a[maxn];
int main()
{
	int i;
	int n;
	while (scanf("%d", &n) != EOF)
	{
		if (n == 0)
			printf("list is empty\n");
		else
		{
			for (i = 0; i < n; i++)
			{
				scanf("%d",&a[i]);
				printf("%d ",a[i]);
			}
			printf("\n");
			for (i = n-1; i >=0; i--)
			{
				
				printf("%d ", a[i]);
			}
			printf("\n");
		}
	}
	
	return 0;
}

问题 F: 算法2-25 有序单链表删除重复元素
问题描述:根据一个递增的整数序列构造有序单链表,删除其中的重复元素

  • 输入
输入包括多组测试数据,每组测试数据占一行,第一个为大于等于0的整数n,表示该单链表的长度,后面跟着n个整数,表示链表的每一个元素。整数之间用空格隔开
  • 输出
针对每组测试数据,输出包括两行,分别是删除前和删除后的链表元素,用空格隔开
如果链表为空,则只输出一行,list is empty
  • 样例输入
5 1 2 3 4 5
5 1 1 2 2 3
0
  • 样例输出
1 2 3 4 5 
1 2 3 4 5 
1 1 2 2 3 
1 2 3 
list is empty

基础题,同样用set保证序列递增且去重

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<set>
using namespace std;

int main()
{
	int i;
	int n;
	int num;
	
	while (scanf("%d", &n) != EOF)
	{
		if (n == 0)
			printf("list is empty\n");
		else
		{
			set<int> st;
			for (i = 0; i < n; i++)
			{
				scanf("%d",&num);
				printf("%d ",num);
				st.insert(num);
			}
			printf("\n");
			for (set<int>::iterator it = st.begin(); it != st.end(); it++)
			{
				printf("%d ", *it);
			}
			printf("\n");
		}
	}
	
	return 0;
}

★,°:.☆( ̄▽ ̄)/$:.°★ 第七章完结撒花花!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值