数据结构银行排队问题

实验任务

银行排队模拟程序功能
假设某银行有四个窗口对外接待客户,从早晨银行开门起不断有客户进入银行。由于每个窗口只能接待一个客户,因此在客户人数众多时需在每个窗口前顺次排队,对于刚进入银行的客户,如果某个窗口的业务员正在空闲,则可上前办理业务,反之,若四个窗口均有客户所占,他便会排在队伍的后面。现在需要编制一个程序以模拟银行的这种业务活动并计算一天中客户在银行逗留的平均时间。

前期准备工作

  • 链式队列书写完毕
  • 带头结点单向不循环链表按顺序插入节点已掌握

算法大致思路

1.2个重要的数据结构

  • 事件链表
  • 队列数组

image-20210530102000635

2.某个时刻运行状态

image-20210530102113272

解释如下:

  • 事件链表

    • occurTime :表示事件发生时间
    • ntype:表示事件类型,-1表示新客户到达,0-3表示0-3号窗口老客户离开时间
  • 队列数组:

    由四个队列对象组成

    对每个队列对象:

    • arrivalTime: 表示当前客户到达时间
    • duration:表示当前客户办理业务时间

3.2个重要的数据结构代码

  • 队列数组
#define datatype Client
//银行客户,队列节点的data域
typedef struct Client
{int arrivalTime;//当前客户到达时间int duration;//当前客户的服务时间
}Client;
//队列节点
typedef struct Node
{Clinet data;struct Node *next;
}Node;
//使用带头结点单链表来做,队列类
class LinkQueue
{
private:Node *rear, *front;int length;//队列中的元素个数
public:LinkQueue();~LinkQueue();bool getFront(datatype *item);void enQueue(datatype item);bool deQueue(datatype *item);bool isEmpty();void clearQueue();void displayQueue();int queueLength();
};
  • 事件链表
typedef struct evNode
{int occurTime;//事件发生时间int nType;//事件类型,-1表示到达事件,0-3表示0-3窗口离开事件struct evNode *next;
}evNode;
class EvList
{
private:evNode *head;
public:LinkList();~LinkList();bool insertNode(int occurTime,int nType);//按顺序插入bool deleteNode(int *occurTime,int *nType);//首部删除void displayNode();bool isEmpty();
};

4.运行流程模拟

image-20210530105052553

image-20210530105145652

image-20210530105209745

image-20210530105242810

image-20210530105303345

image-20210530105342301

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

5.结束条件

img

img

6.个人总结

  • 初始化事件链表

  • 判断事件链表是否为空

  • 若事件链表为空则表示所有事件已经处理完毕可以结束循环

  • 事件链表不为空,则进入主循环

    • 删除事件链表中的第一个节点,将第一个节点中的数据导入到evItem中,

    • 判断evItem中的事件类型,nType = -1表示新用户到达,nType>=0&&nType<=3表示老客户离开

    • nType = -1,新客户到达,customerNum++:

      • 生成两个随机数,分别表示当前客户接受服务的时间duration与下一个客户的间隔时间interTime
      • 判断一下,下一个客户是否在银行关门前到达,若在银行关门前到达则做两件事情(1.处理下一个客户2.处理当前客户),若在银行关门后到达则只做一件事情(处理当前用户);
      • 处理下一个客户事件:计算下一个客户到达时间(下一个客户到达时间=当前客户到达时间+下一个客户间隔时间)
      • 处理当前客户事件:1.将当前客户的状态信息记录到人数最少的队列中(arrivalTime,duration),2.判断一下该队列中是否只有一个节点,若是,则将当前客户离开事件加入到事件链表(occurTime = arrivalTime + duration,ntype=队列编号),原因:很简单银行前台一次只能为一名客户提供服务,若为队列中的第二个元素,则不插入事件链表,等着。
    • nType>=0&&nType<=3,老客户离开

      • 删除nType所对应的队列的队首节点,若队列中还有其他节点,则删除节点的下一个节点所对应的客户离开事件加入事件链表
      • 具体来说:
      • 找到离开客户的编号,等于evItem.nType
      • 客户离开,办完业务,删除队列节点,返回客户信息,用于计算总的服务时间
      • 该队列中/该窗口还有其他客户,则下一个客户离开事件加入事件链表

实验代码

bank.h

#ifndef LINKQUEUE_H__
#define LINKQUEUE_H__
#define datatype Client
#define evdatatype EventStruct
const int CLOSE_TIME = 40;//银行关门时间
const int MAX_INTERTIME =10 ;//相邻两个客户最大间隔时间
const int MAX_DURATION =30 ;//每位客户最大服务时间
//银行客户,队列节点的data域
typedef struct Client
{int arrivalTime;//当前客户到达时间int duration;//当前客户的服务时间
}Client;
//队列节点
typedef struct Node
{datatype data;struct Node *next;
}Node;
//使用带头结点单链表来做,队列类
class LinkQueue
{
private:Node *rear, *front;int length;//队列中的元素个数
public:LinkQueue();~LinkQueue();bool getFront(datatype *item);void enQueue(datatype item);bool deQueue(datatype *item);bool isEmpty();void clearQueue();void displayQueue();int queueLength();
};
struct EventStruct
{int occurTime;//事件发生时间int nType;//事件类型,-1表示到达事件,0-3表示0-3窗口离开事件
};
typedef struct evNode
{evdatatype data;struct evNode *next;
}evNode;
class LinkList
{
private:evNode *head;
public:LinkList();~LinkList();bool insertNode(evdatatype elem);//按顺序插入bool deleteNode(evdatatype *elem);//首部删除void displayNode();bool isEmpty();
};
double simulation(LinkList &evList, LinkQueue queueArr[], int size);
#endif

bank.cpp

#include<iostream>
using namespace std;
#include "LinkQueue.h"
#include<time.h>
#include<stdlib.h>
LinkQueue::LinkQueue()
{front = new Node;front->next = NULL;rear = front;length = 0;
}
LinkQueue::~LinkQueue()
{Node *p, *q;for (p = front->next; p != NULL; p = q){q = p->next;delete p;}delete front;front = NULL;length = 0;
}bool LinkQueue::getFront(datatype *item)
{if (isEmpty()){return false;}else{Node *p;p = front->next;*item = p->data;return true;}
}
void LinkQueue::enQueue(datatype item)
{Node *p = new Node;p->data = item;p->next = NULL;rear->next = p;rear = p;length++;
}
bool LinkQueue::deQueue(datatype *item)
{if (isEmpty()){return false;}else{Node *p = front->next;if (p->next == NULL)//队列中只有一个元素{rear = front;}front->next = p->next;*item = p->data;delete p;length--;return true;}
}
bool LinkQueue::isEmpty()
{if (front == rear){return true;}else{return false;}
}void LinkQueue::clearQueue()
{Node *p, *q;for (p = front->next; p != NULL; p = q){q = p->next;delete p;}front->next = NULL;length = 0;rear = front;
}
void LinkQueue::displayQueue()
{Node *p;for (p = front->next; p != NULL; p = p->next){printf("[%d,%d]->",(p->data).arrivalTime,(p->data).duration);}
}
int LinkQueue::queueLength()
{return length;
}LinkList::LinkList()
{head = new evNode;head->next = NULL;
}
LinkList::~LinkList()
{evNode *p, *q;for (p = head->next; p != NULL; p = q){q = p->next;delete p;}delete head;head = NULL;
}
bool LinkList::insertNode(evdatatype elem)//按顺序插入
{evNode *p = head->next; evNode *pre_p=head;//找到插入位置while (p){	if ((p->data).occurTime > elem.occurTime){break;}pre_p = p;p = p->next;}evNode *newNode = new evNode;newNode->data = elem;pre_p->next = newNode;newNode->next = p;return true;
}
bool LinkList::deleteNode(evdatatype *elem)//首部删除
{if (isEmpty()){return false;}else{evNode *p = head->next;head->next = p->next;*elem = p->data;delete p;return true;}
}
bool LinkList::isEmpty()
{if (head->next == NULL){return true;}else{return false;}
}void LinkList::displayNode()
{evNode *p;for (p = head->next; p != NULL; p = p->next){cout <<"[" <<(p->data).occurTime << "," << (p->data).nType <<"]->";}
}
int findMin(LinkQueue queueArr[4], int size)
{int flag = 0;//假设下标为0的队列人数最少for (int i = 1; i < size; i++){if (queueArr[i].queueLength() < queueArr[flag].queueLength()){flag = i;}}return flag;
}double simulation(LinkList &evList, LinkQueue queueArr[4], int size)
{srand((unsigned)time(NULL));//customerNum表示客户数量,totalTime表示总的客户服务时间int customerNum = 0, interTime, duration, totalTime = 0;Client item;EventStruct evTemp, evItem;//初始化事件链表, 第一个新客户到达evTemp.occurTime = 0;evTemp.nType = -1;evList.insertNode(evTemp);int cnt = 1;//事件链表非空则执行循环,说明还有事情没有处理完毕while (!evList.isEmpty()){printf("---------------第%d次循环----------------------------\n", cnt);cnt++;evList.deleteNode(&evItem);//删除事件链表中第一个节点,将数据拷贝到evItem中printf("删除事件链表中第一个结点存入evItem中:%d,%d\n", evItem.occurTime, evItem.nType);if (evItem.nType == -1)//判断事件类型,-1表示新客户到达{//生成两个随机数,interTime表示下一个客户间隔时间//duration表示当前客户接收服务的时间interTime = rand() % MAX_INTERTIME+1;duration = rand() % MAX_DURATION+1;customerNum++;//客户数量自增printf("是新客户到达事件,请输入durTime,interTime:%d\t%d\n", duration, interTime);if (interTime + evItem.occurTime < CLOSE_TIME)//客户在银行关门后到达,银行不提供服务{//做两件事情//1.处理新客户evTemp.occurTime = evItem.occurTime + interTime;//下一个客户到达时间evTemp.nType = -1;evList.insertNode(evTemp);//新客户加入事件链表printf("把下一位客户到达的事件插入事件表\n");printf("显示事件%d\t%d\n", evTemp.occurTime, evTemp.nType);}//2.处理当前用户,其余只做一件事处理当前用户int min_flag = findMin(queueArr, 4);item.arrivalTime = evItem.occurTime;//将当前客户的状态信息添加到人数最少的队列中item.duration = duration;queueArr[min_flag].enQueue(item);printf("新客户进入人数最少的队列:queue[%d] [%d,%d]\n", min_flag, item.arrivalTime, duration);printf("queue[%d]队列数组中的元素依次为\n", min_flag);queueArr[min_flag].displayQueue();printf("\n");//判断该客户是否为队列中的第一个元素//是,则加入事件链表if (queueArr[min_flag].queueLength() == 1){evTemp.occurTime = item.arrivalTime + item.duration;//计算当前客户离开时间evTemp.nType = min_flag;evList.insertNode(evTemp);printf("设定客户离开银行的事件,插入事件表\n");}printf("打印事件链表:\n");evList.displayNode();printf("\n");}else if (evItem.nType >= 0 && evItem.nType <= 3)//老客户离开{//1.删除ntype对应队列中的队首节点//获取客户所在窗口的编号int index = evItem.nType;printf("queue[%d]队列数组中的元素依次为\n", index);queueArr[index].displayQueue();printf("\n");//当前客户即将离开,从队列中删除,返回用户状态信息queueArr[index].deQueue(&item);printf("queue[%d]中第一个用户离开,用户信息为arrivlaTime=%d,duration=%d\n",index, item.arrivalTime, item.duration);totalTime += item.duration;if (queueArr[index].queueLength() > 0)//如果该对列中还有客户在排队,则下一个客户离开事件加入事件链表{queueArr[index].getFront(&item);evTemp.occurTime = item.duration + evItem.occurTime;//下一个客户离开时间=当前客户离开时间+下一个客户接受服务的时间evTemp.nType = index;evList.insertNode(evTemp);}printf("打印事件链表:\n");evList.displayNode();printf("\n");}}return totalTime * 1.0 / customerNum;
}

test.cpp

#include<iostream>
using namespace std;
#include "LinkQueue.h"
int main()
{LinkList evList;LinkQueue queueArr[4];int size = 4;double avgTime = 0;avgTime = simulation(evList, queueArr, size);cout << avgTime << endl;return 0;
}

运行结果

---------------第1次循环----------------------------
删除事件链表中第一个结点存入evItem中:0,-1
是新客户到达事件,请输入durTime,interTime:20     4
把下一位客户到达的事件插入事件表
显示事件4       -1
新客户进入人数最少的队列:queue[0] [0,20]
queue[0]队列数组中的元素依次为
[0,20]->
设定客户离开银行的事件,插入事件表
打印事件链表:
[4,-1]->[20,0]->
---------------第2次循环----------------------------
删除事件链表中第一个结点存入evItem中:4,-1
是新客户到达事件,请输入durTime,interTime:14     7
把下一位客户到达的事件插入事件表
显示事件11      -1
新客户进入人数最少的队列:queue[1] [4,14]
queue[1]队列数组中的元素依次为
[4,14]->
设定客户离开银行的事件,插入事件表
打印事件链表:
[11,-1]->[18,1]->[20,0]->
---------------第3次循环----------------------------
删除事件链表中第一个结点存入evItem中:11,-1
是新客户到达事件,请输入durTime,interTime:10     1
把下一位客户到达的事件插入事件表
显示事件12      -1
新客户进入人数最少的队列:queue[2] [11,10]
queue[2]队列数组中的元素依次为
[11,10]->
设定客户离开银行的事件,插入事件表
打印事件链表:
[12,-1]->[18,1]->[20,0]->[21,2]->
---------------第4次循环----------------------------
删除事件链表中第一个结点存入evItem中:12,-1
是新客户到达事件,请输入durTime,interTime:2      4
把下一位客户到达的事件插入事件表
显示事件16      -1
新客户进入人数最少的队列:queue[3] [12,2]
queue[3]队列数组中的元素依次为
[12,2]->
设定客户离开银行的事件,插入事件表
打印事件链表:
[14,3]->[16,-1]->[18,1]->[20,0]->[21,2]-> 
---------------第5次循环----------------------------
删除事件链表中第一个结点存入evItem中:14,3
queue[3]队列数组中的元素依次为
[12,2]->
queue[3]中第一个用户离开,用户信息为arrivlaTime=12,duration=2
打印事件链表:
[16,-1]->[18,1]->[20,0]->[21,2]->
---------------第6次循环----------------------------
删除事件链表中第一个结点存入evItem中:16,-1
是新客户到达事件,请输入durTime,interTime:12     7
把下一位客户到达的事件插入事件表
显示事件23      -1
新客户进入人数最少的队列:queue[3] [16,12]
queue[3]队列数组中的元素依次为
[16,12]->
设定客户离开银行的事件,插入事件表
打印事件链表:
[18,1]->[20,0]->[21,2]->[23,-1]->[28,3]->
---------------第7次循环----------------------------
删除事件链表中第一个结点存入evItem中:18,1
queue[1]队列数组中的元素依次为
[4,14]->
queue[1]中第一个用户离开,用户信息为arrivlaTime=4,duration=14
打印事件链表:
[20,0]->[21,2]->[23,-1]->[28,3]->
---------------第8次循环----------------------------
删除事件链表中第一个结点存入evItem中:20,0
queue[0]队列数组中的元素依次为
[0,20]->
queue[0]中第一个用户离开,用户信息为arrivlaTime=0,duration=20
打印事件链表:
[21,2]->[23,-1]->[28,3]->
---------------第9次循环----------------------------
删除事件链表中第一个结点存入evItem中:21,2
queue[2]队列数组中的元素依次为
[11,10]->
queue[2]中第一个用户离开,用户信息为arrivlaTime=11,duration=10
打印事件链表:
[23,-1]->[28,3]->
---------------第10次循环----------------------------
删除事件链表中第一个结点存入evItem中:23,-1
是新客户到达事件,请输入durTime,interTime:22     8
把下一位客户到达的事件插入事件表
显示事件31      -1
新客户进入人数最少的队列:queue[0] [23,22]
queue[0]队列数组中的元素依次为
[23,22]->
设定客户离开银行的事件,插入事件表
打印事件链表:
[28,3]->[31,-1]->[45,0]->
---------------第11次循环----------------------------
删除事件链表中第一个结点存入evItem中:28,3
queue[3]队列数组中的元素依次为
[16,12]->
queue[3]中第一个用户离开,用户信息为arrivlaTime=16,duration=12
打印事件链表:
[31,-1]->[45,0]->
---------------第12次循环----------------------------
删除事件链表中第一个结点存入evItem中:31,-1
是新客户到达事件,请输入durTime,interTime:6      10
新客户进入人数最少的队列:queue[1] [31,6]
queue[1]队列数组中的元素依次为
[31,6]->
设定客户离开银行的事件,插入事件表
打印事件链表:
[37,1]->[45,0]->
---------------第13次循环----------------------------
删除事件链表中第一个结点存入evItem中:37,1
queue[1]队列数组中的元素依次为
[31,6]->
queue[1]中第一个用户离开,用户信息为arrivlaTime=31,duration=6
打印事件链表:
[45,0]->
---------------第14次循环----------------------------
删除事件链表中第一个结点存入evItem中:45,0
queue[0]队列数组中的元素依次为
[23,22]->
queue[0]中第一个用户离开,用户信息为arrivlaTime=23,duration=22
打印事件链表:12.2857C:\Users\Administrator\source\repos\Project8\Debug\Project8.exe (进程 13000)已退出,返回代码为: 0。
若要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口...

参考链接

b站up主懒猫老师

image-20210603124506010

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/261454.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通讯中断 pc_S7程序RFID 与PC连接区别FB 65/UDT65

同样是使用使用FB65但RFID与PC的连接DB用法有一定的区别:首先说一下什么是FB65:通过TCP和ISO on TCP使用两个通信伙伴都调用FB 65 "TCON"来设置和建立通信连接。在这些参数中&#xff0c;您要指定哪个伙伴是主动通信传输点、哪个伙伴是被动通信传输点。设置并建立连接…

JavaScript 设计模式之构造函数模式

一、构造函数模式概念解读 1.构造函数模式概念文字解读 构造函数用于创建特定类型的对象——不仅声明了使用的对象&#xff0c;构造函数还可以接受参数以便第一次创建对象的时候设置对象的成员值。你可以自定义自己的构造函数&#xff0c;然后在里面声明自定义类型对象的属性或…

列表异步线程加载图片

手机客户端以列表形式展示数据是非常常见的一种方式。然而列表中要显示图片&#xff08;比如&#xff1a;头像&#xff09;就要采用异步线程加载的方式&#xff0c;这样做是为了防止加载图片数据的时候&#xff0c;花费时间过长&#xff0c;阻塞UI线程&#xff0c;从而达到保持…

matlab连续卷积动画实现(gui编程)

一.代码运行结果 二.代码 function varargout tianqi(varargin) % TIANQI MATLAB code for tianqi.fig % TIANQI, by itself, creates a new TIANQI or raises the existing % singleton*. % % H TIANQI returns the handle to a new TIANQI or the handle t…

Ubuntu GNOME 15.10升级16.4LTS

为什么80%的码农都做不了架构师&#xff1f;>>> 当Ubuntu GNOME官方已经发送16.4后&#xff0c;执行以下命令 sudo do-release-upgrade 显示没有新系统更新 在网上找到另一种方法是执行以下命令&#xff1a; sudo ppa-purge ppa:gnome3-team/gnome3-staging sudo p…

matplotlib plot 分组_小白学 Python 数据分析(16):Matplotlib(一)坐标系

人生苦短&#xff0c;我用 Python前文传送门&#xff1a;小白学 Python 数据分析(1)&#xff1a;数据分析基础小白学 Python 数据分析(2)&#xff1a;Pandas (一)概述小白学 Python 数据分析(3)&#xff1a;Pandas (二)数据结构 Series小白学 Python 数据分析(4)&#xff1a;Pa…

2016-04-29 二分查找的面试题

为什么80%的码农都做不了架构师&#xff1f;>>> 1.面试题 例如&#xff1a; ip计算后的值&#xff1d;53文本内容&#xff1a;1,100,北京 101,1000,上海 1001,3001,广州 ...求ip53对应的省份2.代码如下&#xff1a; #!/usr/bin/python # coding: utf8def ip_find(i…

gettype拿不到值_王者荣耀:被低估的强势打野,就是这位拿大锤子的阿姨!

王者峡谷的小伙伴你们好&#xff0c;今天就为你们推荐一下这位野区女霸主钟无艳&#xff0c;不仅高伤害而且操作简单&#xff01;版本更新在5月14日版本更新中&#xff0c;钟无艳的三个技能都被加强了&#xff0c;所有的蓝耗都被固定&#xff0c;不再随技能等级的成长值&#x…

【笔记】MATLAB中的图形(2)

三维作图 1、mesh(z)语句 mesh(z)语句可以给出矩阵z元素的三维消隐图&#xff0c;网络表面由z坐标点定义&#xff0c;与前面叙述的x-y平面的线格相同&#xff0c;图形由临近的点连接而成。它可用来显示用其他方式难以输出的包含大量数据的大型矩阵&#xff0c;也可以用来绘制z变…

Kindeditor放置两个调用readonly错误

开始 需要调用Kindeditor中的readonly的方法&#xff0c;但是一直提示edit is undefined 而editor.readonly(true)又只对第一个对象有效 所以只能换换形式&#xff0c;干脆将下面的kindeditor拿上来 虽然是满足自己这个需求&#xff0c;但是真正的原因解决办法&#xff0c;还是…

acl在内核里的位置_Linux 进程在内核眼中是什么样子的?

本篇算是进程管理的的揭幕篇&#xff0c;简单介绍一个进程在内核眼里的来龙去脉&#xff0c;为接下来的进程创建&#xff0c;进程调度&#xff0c;进程管理等篇章做好学习准备。从程序到进程再到内核啥是程序&#xff0c;啥是进程&#xff0c;一张图可以给我们解释&#xff1a;…

majikan

转载于:https://www.cnblogs.com/YOUEN/p/3179091.html

经典中的品味:第一章 C++的Hello,World!

“程序设计要通过编写程序的实践来学习”—Brian Kernighan 1.1 程序 何为程序?简单的说&#xff0c;就是为了使计算机能够做事&#xff0c;你需要在繁琐的细节中告诉它怎么做。对于怎么做的描述就是程序。编程是书写和测试怎么做的过程。维基百科上说&#xff0c;一个程序就像…

使用eclipse svn塔建(配置)时的一点点心得

有没有人遇到下面这种情况&#xff1f;&#xff1f;自己创建的SVN如下&#xff1a; 但网上别人搭建好的是这样子的&#xff1a; 就是为什么我的只有个主文件&#xff0c;而没有src、webroot、meta-inf、web-inf等子文件呢&#xff1f;&#xff1f; 这是我找了很多网上的资料&am…

实例构造器和类(引用类型)

构造器是允许将类型的实例初始化为良好状态的一种特殊方法。构造器方法在“方法定义元数据表”中始终教.ctor。创建一个引用类型的实例时&#xff0c;首先为实例的数据字段分配内存&#xff0c;然后初始化对象的附加字段&#xff08;类型对象指针呵呵同步块索引&#xff09;&am…

android 文件选择器_Android 开发 打开系统文件、图片、视频等 实现单选多选功能...

在网上搜下&#xff0c;如何实现图片的多选或者文件的多选&#xff0c;令人纳闷的是居然多是moudle、或第三方jar包&#xff0c;当然第三方的工程功能复杂或兼容性比较好&#xff0c;并没有说明Android系统是如何提供多选的。既然这么多图片选择器的工程、或者是文件选择器的工…

C语言错误: HEAP CORRUPTION DETECTED

程序源代码&#xff1a; //写文件两种方式(文本文件和二进制文件)#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h>//文本写文件 int writeWord(const char *path,const char *pword){int ERRO_MSG 0;if (path N…

您不能不知的ToString()方法

1.1.1 摘要 相信大家对ToString()方法再熟悉不过了&#xff0c;由于该方法是.NET程序中最常用的方法之一&#xff0c;我们除了可以直接调用ToString()方法之外&#xff0c;.NET中的某些方法也隐式调用ToString()方法&#xff08;WPF&#xff0c;Windows Form和Silverlight等&am…

微信转账一次显示两个_微信为啥分红包和转账两大功能?这4个区别你要知道,望相互转告...

众所周知&#xff0c;自从移动支付普及之后&#xff0c;支付宝、微信就已经成为人们手机中必备的APP&#xff0c;其中微信更是具备社交、支付等一系列功能&#xff0c;所以在国内吸引了超十一亿用户的使用&#xff01;当我们节假日、过年时&#xff0c;很多用户都喜欢给亲朋好友…

java 正则提取及替换字符串

2019独角兽企业重金招聘Python工程师标准>>> <% page import"java.util.regex.Pattern" %><% page import"java.util.regex.Matcher" %><% page import"java.util.List" %><% page import"java.util.Array…