乱序序列保序输出

题目:

http://blog.csdn.net/michael_kong_nju/article/details/44851495

这是一家互联网公司的笔试题,好像没有说保密协议,应该是可以公开的,我也来贡献一下自己的思路和代码。

分布式系统中的RPC请求经常出现乱序的情况。

写一个算法来将一个乱序的序列保序输出。例如,假设起始序号是1,对于(1, 2, 5, 8, 10, 4, 3, 6, 9, 7)这个序列,输出是:

1

2

3, 4, 5

6

7, 8, 9, 10

上述例子中,3到来的时候会发现4,5已经在了。因此将已经满足顺序的整个序列(3, 4, 5)输出为一行。

要求:

1. 写一个高效的算法完成上述功能,实现要尽可能的健壮、易于维护

2. 为该算法设计并实现单元测试

算法思路:

假设数组是a, index从0开始,数组长度为n,
value
表示1,2,3...n这么多的值.  set<int>st 用来保存当前提前出现的value.

1. 循环 index 从0 到 n-1,value从1到n,

如果当前的 index+1 和 value 是相同的例如 a[0] = 1 , 那么直接打印输出并换行。

2.  如果不同,那么肯定是index+1大于value的情况了,这种是属于乱序的。此时将出现的值 a[index] 放入 set 里面。例如在index = 2

的位置将5放入set,后面再将8,10,4放入set,index继续向后。但是value是不变的,即我要一直找到那个a[index] = value的那个值。

3.如果在后面的位置遍历的时候找到相同的了,即出现a[index]  = value 了。 此时肯定是index + 1 > value. 即在index位应该出现的是

index + 1 而不是这个很小的value.此时,打印这个value,并且在set里面循环查找是不是有value的下一个值出现,如果有那么直接+逗号,

同行输出,注意这里最大是找到index + 1,因为不可能出现比他还大的值。如果在找到index+1之前没有出现在set里面那么从步骤1开始

继续当前的index往后找,即在原数组中找。

算法大概就是这样,

下面是实现:

int RPC_seq(int a[], int n)
{
	if (n == 0 || a == NULL)
	{
		cout << "Error in input!" << endl;
		return -1;
	}

	int value = 1;
	set<int>st;
	for (int i = 0; i < n; i++)
	{
		if (a[i] == value && i + 1 == value)    //直接打印输出
			cout << value++ << endl;
		else if (a[i] == value)           //这个是在后面找到了value的值
		{
			cout << value++ << ",";
			while (value <= i + 1)
			{
				if (st.find(value) != st.end())              //依次输出value后面的值。
				{
					cout << value << ",";
					st.erase(value++);
				}
				else
				{
					cout << endl;
					break;
				}
			}

		}
		else
			st.insert(a[i]);
	}
	return 0;
}
int main(void)
{
	//int a[10] = { 1, 2, 5, 8, 10, 4, 3, 6, 9, 7 };
	int a[10] = { 1, 2, 8,5, 7, 4, 3, 10,6,9 };
	RPC_seq(a, 10);
}
时间: 2024-10-05 07:08:44

乱序序列保序输出的相关文章

2015-4-2的阿里巴巴笔试题:乱序的序列保序输出(bit数组实现hash)

分布式系统中的RPC请求经常出现乱序的情况.写一个算法来将一个乱序的序列保序输出.例如,假设起始序号是1,对于(1, 2, 5, 8, 10, 4, 3, 6, 9, 7)这个序列,输出是:123, 4, 567, 8, 9, 10 上述例子中,3到来的时候会发现4,5已经在了.因此将已经满足顺序的整个序列(3, 4, 5)输出为一行. 1 #include<stdio.h> 2 3 int main() 4 { 5 int num ; 6 while(scanf("%d"

阿里巴巴 2015 实习笔试题 分布式系统中的RPC请求经常出现乱序的情况 写一个算法来将一个乱序的序列保序输出

分布式系统中的RPC请求经常出现乱序的情况. 写一个算法来将一个乱序的序列保序输出.例如,假设起始序号是1,对于(1, 2, 5, 8, 10, 4, 3, 6, 9, 7)这个序列,输出是: 1 2 3, 4, 5 6 7, 8, 9, 10 上述例子中,3到来的时候会发现4,5已经在了.因此将已经满足顺序的整个序列(3, 4, 5)输出为一行. 要求: 1. 写一个高效的算法完成上述功能,实现要尽可能的健壮.易于维护 2. 为该算法设计并实现单元测试 貌似效率不是很高,有时间的时候改进下.

阿里巴巴面试题,rpc请求保序接收算法

分布式系统中的RPC请求经常出现乱序的情况. 写一个算法来将一个乱序的序列保序输出.例如,假设起始序号是1,对于(1, 2, 5, 8, 10, 4, 3, 6, 9, 7)这个序列,输出是: 1 2 3, 4, 5 6 7, 8, 9, 10 上述例子中,3到来的时候会发现4,5已经在了.因此将已经满足顺序的整个序列(3, 4, 5)输出为一行. 要求: 1. 写一个高效的算法完成上述功能,实现要尽可能的健壮.易于维护 2. 为该算法设计并实现单元测试 #include <iostream>

二叉树先序序列和中序序列求解树

这种题一般有二种形式,共同点是都已知中序序列.如果没有中序序列,是无法唯一确定一棵树的. <1>已知二叉树的前序序列和中序序列,求解树. 1.确定树的根节点.树根是当前树中所有元素在前序遍历中最先出现的元素. 2.求解树的子树.找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树.若根节点左边或右边为空,则该方向子树为空:若根节点 边和右边都为空,则根节点已经为叶子节点. 3.递归求解树.将左子树和右子树分别看成一棵二叉树,重复1.2.3步,直到所有的节点完成定

UVa 536 Tree Recovery(先序,中序求后序)

题意  给你二叉树的先序序列和中序序列  求它的后序序列 先序序列的第一个一定是根  中序序列根左边的都属于根的左子树  右边的都属于右子树  递归建树就行了 #include <bits/stdc++.h> using namespace std; typedef struct TNode { char data; TNode *lc, *rc; } node, *BTree; void build(BTree &t, string pre, string in) { t = new

根据先序、中序、后序遍历还原二叉树

遍历方式的转至二叉树的四种遍历方式 首先我们要知道三种遍历方式的规律: 先序遍历:跟在前,子树的根在后,左子树比右子树考前,且第一个就是根节点. 中序遍历:左子树在根左边,右子树在根右边,左边的部分是根节点的左子树的中序遍 历序列,右边部分是根节点右子树的中序遍历序列. 后序遍历:根在后,子树在根前且左子树比右子树靠前,且最后一个节点是根节点. 一.先序+中序 根据先序序列的第一个元素建立根节点 在中序序列中找到该元素,确定根节点的左右子树的中序序列 在先序序列中确定左右子树的先序序列 由左子树

2016阿里实习笔试:乱序保序输出

thinking: (1)每次选择输出的数字是当前序列中最小的,记该数字下标为 index,数字为a (2)检查index 之后的最小数为b (3)如果index之前有小于b且大于a的数字出现,说明这些数字是乱序的数字,要和a一行保序输出 code: int output_in_order(vector<int> &unordered_sequence) { int next_output = 1, got_output; priority_queue<int, vector&l

【c语言】将一个数的二进制序列逆序,然后输出逆序之后的二进制序,所对应的数

// 将一个数的二进制序列逆序,然后输出逆序之后的二进制序,所对应的数 #include <stdio.h> // 从原数拿出最低位,放到mid中,mid左移,原数右移 int reverse(int a) { int mid = 0; int bit; int n = 31; for (; n > 0; --n) { bit = a & 1; mid |= bit; mid <<= 1; a >>= 1; } return mid; } int main

算法进化历程之“根据二叉树的先序和中序序列输出后序序列”

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 前不久在看到一个作业"根据二叉树的先序和中序序列输出后序序列",当时我参考<数据结构与算法(C语言)习题集>上的做法,先根据先中序序列确定一颗二叉树,然后后序遍历二叉树输出后序序列. 函数采用了递归算法,利用函数传入的先序和中序序列的左右边界,确定要处理的序列段,生成相应的二叉树. 基本思路是,把该段先序序列的第一个元素作为当前二叉树的根结点,然后在中序序列找到根结点.根结点