tcl 有部分排序命令吗?

发布于 2024-10-18 23:09:06 字数 65 浏览 0 评论 0原文

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

As C++'s std::partial_sort do. lsort is not powerful enough.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

那请放手 2024-10-25 23:09:06

没有与 partial_sort 等效的内置函数。我认为您的选择是要么在 Tcl 中手动实现它,这可能会破坏您想要获得的效率;要么在 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 结构来说,它有点漫不经心。但希望它能让您进入正确的目录。

There is no built-in equivalent to partial_sort. I think your choices are either to implement it by hand in Tcl, which would probably undermine whatever efficiency you sought to gain; or write an extension that actually exposes partial_sort to the interpreter. That wouldn't be too difficult actually -- Tcl extensions are pretty easy to write. Here's a bit of code I just whipped up that should get you started:

#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;
}

Of course this is just a rough cut. It only handles lists of integers. It doesn't do much in the way of error checking. It's a bit cavalier with respect to shared Tcl_Obj structures. But hopefully it will get you going in the right directory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文