通过一次迭代对负数,零和正整数数组排序


9

取一个包含负数,正数和零的整数数组。对其进行一次迭代分组并放置在适当的位置,以使所有负数都在前,然后是所有零,然后是所有正数。

例:

Input:  5, 3, 0, -6, 2, 0, 5
Output: -6, 0, 0, 3, 2, 5, 5

请注意,数字不需要完全排序:只需按符号排序即可。

因此,最终数组将如下所示: -, -, ..., -, -, 0, 0, ..., 0, 0, +, +, ..., +, +

规则

  • 您只能使用输入数组和恒定数量的附加内存(即,您不能再创建任何数组)
  • 您只能使用一个循环,该循环只能执行与数组长度相同的次数。您不得使用隐藏任何循环的内置函数。这包括内置的排序功能。
  • 结果应为我描述的格式

获胜者将是提交最短代码(以字节为单位)的代码,该代码会将初始数组更改为正确的格式(如上所述)。



@PeterTaylor Thx,现在我明白了任务是什么!
randomra

确切地说,此代码golf.stackexchange.com/questions/504/…除了使用1次迭代和1个数组限制。
Optimizer

不允许使用内置的排序功能,对吗?
KSFT 2015年

1
@KSFT调用sort(...)不太好,因为它可能会执行多个迭代。
尼卡比曹

Answers:


3

C,92

可能会减少至少10个字节;有很多表情要浪费。

第一个参数应指向数组的开头;第二个应该指向数组末尾。

*x;f(b,e)int*b,*e;{for(x=b;x<e;x++)*x>0&&--e-x?*x--^=*e^=*x^=*e:*x<0?b-x?*x^=*b=*x:0,b++:0;}

取消随机测试生成器的支持:

*x;
f(b,e)int*b,*e;{
    for(x=b;x<e;x++) {
        if(*x<0) {
            if(b == x)
                b++;
            else
                *b++ = *x, *x=0;
        } else if(*x>0 && x != --e) {
            *x^=*e^=*x^=*e;
            x--;
        }
    }
}

int main()
{
    int a[999];
    srand(time(0));
    int n = rand() % 50;
    int i;
    for(i = 0; i < n; i++) printf("%d ", a[i] = rand() % 9 - 4);
    f(a, a+n);
    puts("");
    for(i = 0; i < n; i++) printf("%d ", a[i]);
    return 0;
}

我在代码块中尝试过此方法,但它无法编译,有3个错误。你用什么编译?x *未定义,您在{之前创建了变量。
bacchusbeale 2015年

@bacchusbeale您可以在默认(C89)模式下使用gcc对其进行编译。CodeBlocks不是编译器,因此我无法确定您使用的是哪个编译器,但它可用于gcc。它可能不适用于所有编译器的原因是K&R样式的声明,该声明不符合ANSI标准。
feersum'2

1

斯塔塔242

完全遵循Wikipedia页面。谢谢@PeterTaylor

将输入作为与std输入和输出到std输出的空格分隔的数字集。

di _r(a)
token $a//converts to array (kind of)
loc i=0
loc j=0
loc q=wordcount($a)
loc n=`q'-1
while `j'<=`n' {
loc t=``j''
if `t'<0{
loc `j'=``i''
loc `i'=`t'
loc ++i
loc ++j
}
else if `t'>0{
loc `j'=``n''
loc `n'=`t'
loc --n
}
else
loc ++j
}
//used only to output
forv x=1/`q'{
di ``x'' _c
}

1

Python 2:116个字节

a=input();i=j=0;n=len(a)
while j<n:b=a[j];r,s=b<0,b>0;c=i*r+n*s-s+j*(b==0);a[c],a[j]=b,a[c];i+=r;n-=s;j+=b<1
print a

这是荷兰国旗伪代码的Python版本。

可能的112字节

不知道,是否允许这样做。它创建第二个大小为3的数组(不断增加的内存!)。

a=input();i=j=0;n=len(a)-1
while j<=n:b=a[j];k=(i,j,n)[cmp(b,0)+1];a[k],a[j]=b,a[k];i+=b<0;n-=b>0;j+=b<1
print a

1

约90

彼得·泰勒(Peter Taylor)对问题的评论,在维基百科文章中直接实现了该算法。

期望在a像其他C答案一样的数组中查找数据。npz是正数和负数和零的插入指针。np作为指向数据的第一个和最后一个元素的参数。

f(n,p){int t,z;for(z=n;p-z;z++)(t=a[z])?a[z]>0?a[z]=a[p],a[p--]=t:(a[z]=a[n],a[n++]=t):0;}

1

ECMAScript 157字节

从提示对话框中将数字作为空格分隔或逗号分隔的集合,并通过警报对话框返回结果。

for(v=prompt().split(/,?\s+/),s=function(j,n){t=v[j],v[j]=v[n],v[n]=t},i=j=0,n=v.length-1;j<=n;)
!(~~v[j]<0&&!s(i++,j++)||~~v[j]>0&&!s(j,n--))&&j++;alert(v);

0

PHP(146)

function f($s){for($i=0,$n=count($s)-1;$j++<=$n;)if($k=$s[$j]){$l=$k>0?n:i;$x=$s[$$l];$s[$$l]=$k;$s[$j]=$x;$k>0?$n--|$j--:$i++;}echo print_r($s);}

http://3v4l.org/ivRX5

PHP相对冗长的变量语法在这里有点痛苦...


0

雷博尔- 149 142 140

a: to-block input i: j: 1 n: length? a while[j <= n][case[a/:j < 0[swap at a ++ i at a ++ j]a/:j > 0[swap at a j at a -- n]on[++ j]]]print a

这是荷兰国旗维基百科伪代码的直接端口。下面是它看起来不实际的样子:

a: to-block input
i: j: 1
n: length? a

while [j <= n] [
    case [
        a/:j < 0 [swap at a ++ i at a ++ j]
        a/:j > 0 [swap at a j at a -- n]
        on       [++ j]
    ]
]

print a

用法示例:

rebol dutch-flag.reb <<< "5 3 0 -6 2 0 5"
-6 0 0 2 3 5 5

注意 Rebol数组(块)不使用逗号-[5 3 0 -6 2 0 5]

如果可以将其包装到一个函数中,该函数需要一个数组并对其进行修改,那么我们可以将其缩减为128个字符:

>> f: func[a][i: j: 1 n: length? a while[j <= n][case[a/:j < 0[swap at a ++ i at a ++ j]a/:j > 0[swap at a j at a -- n]on[++ j]]]n]

>> array: [5 3 0 -6 2 0 5]
== [5 3 0 -6 2 0 5]

>> print f array
-6 0 0 2 3 5 5

>> ;; and just to show that it as modified array

>> array
== [-6 0 0 2 3 5 5]

实际上,如果不需要返回数组(即只需修改),则可以再剃掉1个字符。


0

C ++

非解决方案:n计算添加到数组前面的负数。对于每个元素,如果在n处与元素交换为负,如果在n + 1处与元素交换为零,则与最后一个元素交换。

void p(int* k,int n)
{
for(int i=0;i<n;i++)
{
cout<<*(k+i)<<' ';
}
cout<<endl;
}

void s(int *x,int i,int j)
{
int t=*(x+j);
*(x+j)=*(x+i);
*(x+i)=t;
}
void f(int *x,int L)
{
int n=0;
int k;
for(int i=1;i<L;i++)
{
k=*(x+i);
if(k<0)
{
s(x,i,n);
n++;
}
else if(k==0)
{
s(x,i,n+1);
}
else if(k>0)
{
s(x,i,L-1);
}
}
}

int main()
{
int x[]={5,2,-1,0,-2,4,0,3};
f(x,8);
p(x,8);
return 0;
}

0

果酱-72 67

q~_,(:N;{_U=:B0>{U1$N=tNBtN(:N;}{B{U1$T=tTBtT):T;}{}?U):U;}?UN>!}gp

输入:[5 3 4 0 -6 2 0 5]
输出:[-6 0 0 4 2 3 5 5]

http://cjam.aditsu.net/上尝试

说明:

这是维基百科算法的另一种实现,使用Tfor iUfor j(均自动初始化为0)。

q~                    read and evaluate the array (let's call it "A")
_,(:N;                keep A on the stack and set N ← size of A - 1  
{                     do...  
    _U=:B             keep A on the stack and set B ← A[U] (also leaving B on the stack)  
    0>{               if B > 0
        U1$N=t        A[U] ← A[N]
        NBt           A[N] ← B
        N(:N;         N ← N - 1
    }{                else
        B{            if B ≠ 0
            U1$T=t    A[U] ← A[T]
            TBt       A[T] ← B
            T):T;     T ← T + 1
        }{            else (do nothing)
        }?            end if
        U):U;         U ← U + 1
    }?                end if
UN>!}g                ...while not (U > N)
p                     print representation of A
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.