Что такое хороший способ *временно* сортировка вектора?

У меня есть станд.:: вектор, который я должен отсортировать по выбранным алгоритмам для определенных операций, но поддержать его исходное состояние (например, объекты, заказанные тем, когда они вводились), остальная часть времени.

Очевидно, я могу использовать станд.:: копия для создания временного вектора и вида, что, но я задаюсь вопросом, существует ли лучший путь, возможно путем добавления метки времени к вводимым объектам.

Аплодисменты

11
задан deworde 22 February 2010 в 17:27
поделиться

5 ответов

Я был бы осторожен с любым фрагментом кода, написанным, чтобы «доказать», что вы с большей вероятностью удвоите свои деньги на крапах (или любой другой случайной игре), прежде чем вы разоритесь. Лас-Вегас - разросшийся город в пустыне Невада, как свидетельство двух вещей:

  1. В конце концов, дом всегда побеждает
  2. Люди плохи в математике

Нет никакой игры, которую казино поставило бы на свой этаж, который не использовал бы оба правила. Если твой код не согласен с Вегасом, я положу свои деньги на Вегас.

Обновление:

Вот некоторые C++, которые я написал на основе вашего оригинального кода. Первоначальная проблема, которую вы опубликовали, была, если вы могли удвоить свои деньги до того, как вы разорились чаще, чем нет.

#include <iostream>

int die_roll()
{
    return std::rand() % 6 + 1;
}

int win_count_g(0);
int loss_count_g(0);

// return true when double our money.
// return false when we can't bet anymore.
bool test_loop(int cash)
{
    static const int bet_k(5);

    int goal(cash * 2);
    int button(0);

    while (true)
    {
        if (cash >= goal)
            return true;
        else if (cash < bet_k)
            return false;

        int roll(die_roll() + die_roll());
        int odds(0); // additional odds bet

        if (button == 0)
        {
            if (roll == 7 || roll == 11)
            {
                ++win_count_g;
                cash += bet_k;
            }
            else if (roll == 2 || roll == 3 || roll == 12)
            {
                ++loss_count_g;
                cash -= bet_k;
            }
            else
            {
                button = roll;

                if (roll == 4 || roll == 10)
                {
                    odds = std::min(cash - bet_k, bet_k * 3);
                }
                else if (roll == 5 || roll == 9)
                {
                    odds = std::min(cash - bet_k, bet_k * 4);
                }
                else // if (roll == 6 || roll == 8)
                {
                    odds = std::min(cash - bet_k, bet_k * 5);
                }
            }
        }
        else
        {
            if (roll == 7)
            {
                ++loss_count_g;
                button = 0;
                cash -= bet_k + odds;
            }
            else if (roll == button)
            {
                ++win_count_g;
                button = 0;
                cash += bet_k;

                if (roll == 4 || roll == 10)
                {
                    cash += odds * 2;
                }
                else if (roll == 5 || roll == 9)
                {
                    cash += odds * 3 / 2;
                }
                else // if (roll == 6 || roll == 8)
                {
                    cash += odds * 6 / 5;
                }
            }
        }
    }
}

void test(int cash)
{
    win_count_g = 0;
    loss_count_g = 0;

    int doubled(0);
    int broke(0);

    for (int i(0); i < 10000; ++i)
        if (test_loop(cash))
            ++doubled;
        else
            ++broke;

    float win_percentage(static_cast<float>(doubled) / (doubled + broke) * 100.0);

    std::cout << "starting cash: $" << cash
              << "; doubled: " << doubled
              << "; broke: " << broke
              << " (" << win_percentage << "% win)"
              << "; loop wins: " << win_count_g
              << "; loop losses: " << loss_count_g
              << std::endl;
}

int main ()
{
    static const int cash_set_k[] =
    {
        5,
        10,
        20,
        50,
        100,
        200,
        400,
        800,
        1000
    };
    static const int cash_set_size_k(sizeof(cash_set_k) / sizeof(cash_set_k[0]));

    std::for_each(&cash_set_k[0], &cash_set_k[cash_set_size_k], &test);

    return 0;
}

Результаты:

starting cash: $5; doubled: 4944; broke: 5056 (49.44% win); loop wins: 4944; loop losses: 5056
starting cash: $10; doubled: 4862; broke: 5138 (48.62% win); loop wins: 19706; loop losses: 20258
starting cash: $20; doubled: 4755; broke: 5245 (47.55% win); loop wins: 78360; loop losses: 80320
starting cash: $50; doubled: 4345; broke: 5655 (43.45% win); loop wins: 489406; loop losses: 502506
starting cash: $100; doubled: 3553; broke: 6447 (35.53% win); loop wins: 1914393; loop losses: 1972273
starting cash: $200; doubled: 2468; broke: 7532 (24.68% win); loop wins: 7172464; loop losses: 7375024
starting cash: $400; doubled: 861; broke: 9139 (8.61% win); loop wins: 22615369; loop losses: 23277609
starting cash: $800; doubled: 112; broke: 9888 (1.12% win); loop wins: 54556881; loop losses: 56121041
starting cash: $1000; doubled: 31; broke: 9969 (0.31% win); loop wins: 69308617; loop losses: 71296217
-121--3113789-

Java не поддерживает свойства C #. Вам нужны средства получения и установки, но будьте осторожны в том, что вы не случайно предоставите пользователю доступ к инкапсулированным данным, вернув ссылку на объект вместо ссылки на его копию.

-121--1742769-

Можно создать вектор std::, содержащий все индексы первого вектора. Затем можно отсортировать вектор индекса по своему усмотрению. Это должно быть быстро и самое главное, не значит, что вам придется копировать первый вектор (что, вероятно, дороже!).

19
ответ дан 3 December 2019 в 04:13
поделиться

Если вас не смущает немного Boost, вы можете использовать библиотеку MultiIndex. Смотрите этот мой ответ, где вы найдете несколько примеров кода.

По сути, она позволяет вам хранить несколько "представлений" одних и тех же данных, каждое из которых имеет свой порядок. В вашем случае вы сможете хранить представление "последовательность", где данные расположены в порядке вставки (как вектор) и представление "сортировка", в котором данные отсортированы по какому-либо критерию (как карта).

4
ответ дан 3 December 2019 в 04:13
поделиться

Какой бы элемент вы ни сортируете, вы можете заключить его в структуру с несколькими полями сортировки.

struct someThing
{
    int sortOrder1;
    int sortOrder2;
    ...
    int sortOrderN;
    //payload data object here
} //note: this code may have some sytax errors (I haven't actually tried compiling this ;), but hope the idea is clear

(или, может быть, добавить порядки сортировки к самой базовой структуре?)

Затем, когда вам нужно, вы можете вычислить различные порядки сортировки и изменить порядок сортировки в зависимости от того, какой порядок сортировки вам нужен.

0
ответ дан 3 December 2019 в 04:13
поделиться

Я предлагаю хранить интеллектуальные указатели на исходные данные в каждом векторе . std :: vector позволяет вам предоставлять различные методы сортировки. Кроме того, с помощью интеллектуальных указателей они будут автоматически уничтожены при удалении всех ссылок на элемент.

0
ответ дан 3 December 2019 в 04:13
поделиться

Любой заданный вектор будет отсортирован не более чем одним способом в любой момент.

Есть две альтернативы:

Скопировать во временный вектор и отсортировать его по желанию. Если вектор не очень большой и у вас ограниченное пространство, это почти наверняка лучший способ. Даже если вас беспокоит производительность, стоимость создания копии будет меньше, чем стоимость сортировки, а если стоимость копирования значительна, сортировка будет намного медленнее, чем копирование.

В качестве альтернативы вы могли бы сохранить некоторый способ (отметку времени, о которой вы упомянули?), Чтобы иметь возможность отсортировать вектор обратно в исходный порядок. Это будет медленно, так как вы захотите сделать это только в том случае, если вектор был очень большим, но если вы не можете создать временный вектор, это единственный способ сделать это.

2
ответ дан 3 December 2019 в 04:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: