如何重新排列数组中的数据,使两个相似的项目不相邻?
Posted
技术标签:
【中文标题】如何重新排列数组中的数据,使两个相似的项目不相邻?【英文标题】:How to rearrange data in array so that two similar items are not next to each other? 【发布时间】:2010-11-11 17:18:11 【问题描述】:只想重新排列数组中的数据,以便相似的项目不在每个旁边。数据不应从数组中删除,如果无法重新排列,则可以将其放在数组的末尾。但是保持原来的顺序是必要的。
例子
1 1 2 => 1 2 1
1 1 1 2 3 => 1 2 1 3 1
1 1 2 1 3 3 5 1 => 1 2 1 3 1 3 5 1
1 1 1 1 1 1 2 => 1 2 1 1 1 1 1
8 2 1 3 7 2 5 => rearrange not needed
8 2 2 2 7 2 5 2 => 8 2 7 2 5 2 2 // keep the original order
编辑: 添加示例以显示需要保持原始顺序
【问题讨论】:
您想重新排列它们,但保持顺序....? @Mark - 两者是互斥的..您要么保留订单,要么更改订单...您能澄清一下您的意思吗? 而不是标记任何您认为可以并且应该使用算法标记的编程语言 这听起来确实像一个家庭作业问题——如果是,你可能会在问题中提到它——它将帮助人们正确回答。 @Armen 提到语言不是任何编程语言,它们具有相似的语法。这就是我提到它们的原因。 【参考方案1】:-
对数组进行排序
将小的偶数索引处的元素与其较高的对映对应物交换:
for ( i=0; i < arr.length/2; i+=2 )
arr.swap(i,arr.length-1-i);
编辑:好的,我们应该重新定义对映体。也许这个更好:混合第一个和第三个四分位数(在插图中表示为 x、y),并混合第二个和第三个四分位数(表示为 u、v、w)。让对方平行上升。
25% 50% 75%
| | |
-----[----[----[----
11122334455667788999
x y u v w x y u v w <-- u, v, w, x, y indicate swap positions
16172839495161738495
【讨论】:
我喜欢这个答案。它很简单,并且似乎具有良好的时间复杂度(不比排序算法更差的常数因子) 我喜欢这个答案,尽管它让我担心潜在的运行时间,因为与目标条件差异最小的列表将导致该算法的最大运行时间(由于排序) .即,与目标标准匹配的列表然后添加了一个元素可能会导致大量运行时执行(即,该算法不知道输入满足完成标准的程度)。也就是说,如果这不是预期的情况,那么这个算法看起来效果很好。 排序 -->1 1 1 1 1 1 2
;交换(0, 6) --> 2 1 1 1 1 1 1
【参考方案2】:
嗯。冒泡排序出现在我的脑海中,但要进行三元素比较;也就是说,如果item[x]
和item[x + 1]
相同而item[x + 2]
不同,则交换item[x + 1]
和item[x + 2]
。重复遍历列表,直到没有交换发生。执行顺序当然很糟糕,但这应该可以满足您的需求。
【讨论】:
好的,反对票是怎么回事?这种方法是否存在问题(除了公认的运行时间顺序)? 我没有投反对票,但这甚至不能保证会终止。 @wnoise:甚至不是pcode,只是对算法的简单描述;获得适当的终止条件在某种程度上被认为是读者的练习。【参考方案3】:在我掌握了你想要的东西之后,这是一个可能的解决方案
对数组进行分区
[1,1,1,8,8,8,2,3,3,4,1,1,1,2,2] -> [[3,1],[3,8],[1,2],[2,3],[1,4],[3,1],[2,2]]
(读取 3 次 1、3 次 8 等)
对于每个分区条目i
和p[i][0] >1
(times >1):
选择一个“有效”的职位j
(所以p[j][1] != p[i][1] && p[j+1][1] != p[i][1]
)
递减p[i][0]
元素并将[p[i][1],1]
插入分区中的位置j
如果没有这样的位置,也可以省略。
这应该具有线性时间复杂度(为每个数字保留有效位置)。
【讨论】:
【参考方案4】:将您的数组填充到类 var 中,然后您可以在其上运行自定义排序方法而无需更改它。恭喜,您刚刚创建了一个新的 nosql 数据库。
让大家害怕的是失去原来的秩序。
这就是为什么哈希中的键被称为“索引”的原因,想想看。
class Dingleberry
private $shiz= array();
function __construct(array $a) $this->shiz = $a;
##### PUBLIC
public function unmolested() return $this->shiz;
/* @see http://www.php.net/manual/en/ref.array.php */
public function sort($type)
switch ($type)
case 'key_reverse': return krsort($this->shiz); break;
# Check all the php built in array sorting methods to
# make sure there is not already one you want
# then build this out with your own
【讨论】:
【参考方案5】:假设一个数组包含 0 到 9 之间的数字: 类似于桶排序的一种方式
int B[10];//buckets
diff=0;//how many different digits appeared
for(i=0;i<A.length;i++)
x=A[i];
if(B[x]==0)
diff++;
B[x]++;
//loaded
while(diff>=0)//now to place back to array makes an interleaving
for(digit=0;digit<10;digit++)
if(B[digit]<>0)
A[B[digit]+diff]=digit;
B[digit]--;
diff--;
【讨论】:
【参考方案6】:获取整个数组并扫描重复项。当您遇到受骗者时,请记住他们在哪里。所以对于像 2 1 2 2* 3 3* 3* 4 4* 2 2* 5 这样的东西。应该记住带星星的。
现在看看“记住”的东西,你有 2 个 2、2 个 3 和一个 4
现在我将这些 LISTS 从数量最多的第一个(2 和 3)到最少的(4)进行排序
现在只取不重复当前“Front”的最多数量的(因为有 2 个重复,所以应该是 3 个)并将其移到前面,然后将其从列表中删除。
重复直到列表为空。第二次通过您的列表将以“3”开头,您将有 2 个 2、一个 3 和一个 4,因此您将其中一个 2 放在前面...
如果还有剩余(只能是一个数字),把它放在最后..
完成,蛋糕。
【讨论】:
【参考方案7】:在 javascript 中,我可能会这样做:
var arr = [ 1, 1, 1, 2, 3 ];
var i = 0, len = arr.length;
while (i < len - 1)
if (arr[i] == arr[i+1])
//index is equal to it's partner.
if (arr[i+2] && arr[i] == arr[i+2])
// 3 equal values in a row, swapping won't help. Need to recheck this index in this case.
var tmp = arr[i];
arr.splice( i, 1 );
arr.push( tmp );
else
// Swap the next and 2nd next index.
var tmp = arr[i+1];
arr[i+1] = arr[i+2];
arr[i+2] = tmp;
i++;
else
// this index is fine, move on.
i++;
这是一个简单的例子,编码风格可能会被清理很多
【讨论】:
它有时会无限期挂起,不要用这个!以上是关于如何重新排列数组中的数据,使两个相似的项目不相邻?的主要内容,如果未能解决你的问题,请参考以下文章