假設有這樣一個隊列(該行僅僅是爲了清楚,他們並不代表什麼):算法名稱編號排序升序組
[1,1,1,
2,2,2,
3,3,
4,
5]
我想把它整理成這樣:
[1,2,3,4,5,
1,2,3,
1,2]
有沒有一種算法可以解決這個問題,如果是的話,它是如何被調用的?
假設有這樣一個隊列(該行僅僅是爲了清楚,他們並不代表什麼):算法名稱編號排序升序組
[1,1,1,
2,2,2,
3,3,
4,
5]
我想把它整理成這樣:
[1,2,3,4,5,
1,2,3,
1,2]
有沒有一種算法可以解決這個問題,如果是的話,它是如何被調用的?
沒有必要採取計數levis501s方法描述occurances雖然它很可能是認爲他的代碼更簡潔或更合適的Python環境的方法。
你可以通過重複一個循環來解決這個問題,直到所有的原始元素都被排序爲止,並且在那個循環中遍歷列表來查找大於最後找到的數字的最小數字,並將它彈出到結果堆棧上進行迭代然後在沒有更大的數字時終止內部循環。
如果你想命名的算法是使用它可能是一個直方圖某種變體或者一個桶排序變種..如果你挖成並行排序算法可能會找到的東西,更貼切地描述您的問題。
這裏是一個Perl實現:
my @a=reverse(qw/ 1 1 1 2 2 2 3 3 4 5/); ## reverse order allows us to trim the array without messing up indexes
print qq{Source array = } . join(',',@a) . "\n";
my @bucket =();
while ($#a >= 0)
{
my @bucket =(); ## start a new bucket
for (my $i=$#a; $i>=0; $i--)
{
if ($#bucket==-1 && $a[$i]>0 || $bucket[$#bucket] < $a[$i])
{
push @bucket, $a[$i];
splice @a, $i, 1; ## remove the element from the source data
}
}
print join(',',@bucket) . "\n"; ## display the constructed bucket list
}
或使用類似的方法在Perl
my @a = (1,1,1,2,2,2,3,3,4,5);
my $hist = {};
foreach my $i (@a)
{
$hist->{$i}++;
}
while (scalar(%$hist)> 0)
{
foreach my $el (sort keys %$hist)
{
$hist->{$el}--;
print qq{ $el };
delete $hist->{$el} if $hist->{$el}<1;
}
print "\n";
}
我認爲這是我可能會得到的最接近的答案。這不是一個家庭作業,它是一個生產應用程序,但我雖然解釋細節可能不相關。我會接受這是正確的(即該算法不存在)。 – Sergey
已經更新了幾個實現 - 如果你有不同的語言偏好讓我知道,我會有一個裂縫 –
如果您是使用Python,檢查出Counter類變爲列表變成一種直方圖。
from collections import Counter
l = [1,1,1,
2,2,2,
3,3,
4,
5]
c = Counter(l)
result = []
for i in range(max(c.values())):
result += [k for k,v in c.items() if v > i]
print(result)
基本上,您可以計算每個數據項的出現次數,並通過連接出現次數增加的列表來構建結果。不過,我從來沒有聽說過這個名字。 「直方圖」是我知道的最接近的,儘管不是確切的。 – levis501
這個答案是基於levis501s再次levis501,但這似乎更簡單(或者至少不同) 。與他的回答一樣,這使用python,儘管類似的功能可以在其他高級語言中實現而不需要太多的努力。
from collections import Counter
c = Counter([1, 1, 1, 2, 2, 2, 3, 3, 4, 5])
while c:
run = list(c)
run.sort()
for e in run:
print(e)
c[e] -= 1
if c[e] == 0:
del c[e]
如果你有像'1,1,3,3'這樣的輸入怎麼辦? –
@ DanielA.White這不是一種算法。然後 –
@ LasseV.Karlsen結果應該是[1,3,1,3] – Sergey