Есть ли частичная команда сортировки для tcl? - PullRequest
2 голосов
/ 24 февраля 2011

Как и в C ++ std::partial_sort. lsort недостаточно силен.

1 Ответ

5 голосов
/ 24 февраля 2011

Нет встроенного эквивалента 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. Но, надеюсь, вы попадете в правильный каталог.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...