是否有tcl的部分排序命令?

时间:2011-02-24 00:06:09

标签: sorting tcl

正如C ++的std::partial_sort所做的那样。 lsort不够强大。

1 个答案:

答案 0 :(得分:5)

没有内置等效于partial_sort。我认为你的选择要么是在Tcl手工实施,这可能会破坏你想要获得的效率;或者写一个实际公开partial_sort到解释器的扩展名。这实际上并不太难--Tcl扩展很容易编写。这里有一些我刚刚启动的代码,应该让你开始:

#include <algorithm>
#include "tcl.h"

using namespace std;

static int PartialSortCommand(ClientData dummy,
        Tcl_Interp *interp,
        int objc,
        Tcl_Obj *CONST objv[]);


EXTERN int
Partialsort_Init(Tcl_Interp *interp)
{
    if (Tcl_InitStubs(interp, "8.0", 0) == NULL) {
        return TCL_ERROR;
    }

    if (Tcl_PkgProvide(interp, "partialsort", "1.0") != TCL_OK) {
        return TCL_ERROR;
    }

    Tcl_CreateObjCommand(interp, "partialsort", PartialSortCommand,
            (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);

    return TCL_OK;
}

bool CompareObjs(Tcl_Obj *a, Tcl_Obj *b) {
    int left, right;
    Tcl_GetIntFromObj(0, a, &left);
    Tcl_GetIntFromObj(0, b, &right);
    return left < right;
}

int PartialSortCommand(
    ClientData dummy,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *CONST objv[])
{
    if (objc != 5) {
        Tcl_WrongNumArgs(interp, 1, objv, "list start middle end");
        return TCL_ERROR;
    }

    Tcl_Obj **objs;
    int count;

    if (Tcl_ListObjGetElements(interp, objv[1], &count, &objs) != TCL_OK) {
        return TCL_ERROR;
    }

    int start, middle, end;
    if (Tcl_GetIntFromObj(interp, objv[2], &start) != TCL_OK) {
        return TCL_ERROR;
    }

    if (Tcl_GetIntFromObj(interp, objv[3], &middle) != TCL_OK) {
        return TCL_ERROR;
    }

    if (Tcl_GetIntFromObj(interp, objv[4], &end) != TCL_OK) {
        return TCL_ERROR;
    }

    partial_sort(&objs[start], &objs[middle], &objs[end], CompareObjs);
    Tcl_SetObjResult(interp, Tcl_NewListObj(count, objs));
    return TCL_OK;
}

当然这只是粗略的。它只处理整数列表。它在错误检查方面没有太大作用。对于共享的Tcl_Obj结构,它有点骑士。但希望它会让你进入正确的目录。