Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 10 из 10
  1. #1
    Аватар для m1n1vv
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Сообщений
    541
    Репутация:
    78 ±

    Упорядочить массив

    Как переставить нули в конец массива? Для этого нужен двойной цикл?

    Сделал так, но сомневаюсь, что правильно
    PHP код:
    main() {

         const
              
    size 5;

         static
            
    m[size] = {08031};
        
         for (new 
    0sizei++)
         {
            if (
    m[i] == 0)
            {
                for (new 
    isizej++)
                {
                    if (
    m[j] != 0)
                    {
                        
    m[i] = m[j];
                        
    m[j] = 0;
                        break;
                    }
                }
            }
            
    printf("%i"m[i]);
        }

    Последний раз редактировалось m1n1vv; 04.02.2019 в 19:42.

  2. #2
    Аватар для x86
    Пользователь

    Статус
    Оффлайн
    Регистрация
    26.01.2019
    Сообщений
    41
    Репутация:
    6 ±
    1. new arr[] = {1,0,6,2,1,0,0,1,1,2};
    2. new cnt = 0, i = 0, c;
    3. while (i<sizeof(arr)) {
    4. c = arr[i++];
    5. if (c == 0)
    6. continue;
    7. arr[cnt++] = c;
    8. }
    9. while (cnt < n) {
    10. arr[cnt++] = 0;
    11. }

  3. #3
    Аватар для Seviel
    Пользователь

    Статус
    Оффлайн
    Регистрация
    23.12.2016
    Адрес
    Казахстан
    Сообщений
    148
    Репутация:
    26 ±
    Возможно поможет алгоритмы сортировки

  4. #4
    Аватар для x86
    Пользователь

    Статус
    Оффлайн
    Регистрация
    26.01.2019
    Сообщений
    41
    Репутация:
    6 ±
    Цитата Сообщение от Seviel Посмотреть сообщение
    Возможно поможет алгоритмы сортировки
    Действительно, можно сделать сортировку по убыванию. Однако на сортировку уходит достаточно приличное время, чем на код, который я предоставил выше.

  5. Пользователь сказал cпасибо:
    Seviel (04.02.2019)
  6. #5
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2590 ±
    Цитата Сообщение от x86 Посмотреть сообщение
    1. new arr[] = {1,0,6,2,1,0,0,1,1,2};
    2. new cnt = 0, i = 0, c;
    3. while (i<sizeof(arr)) {
    4. c = arr[i++];
    5. if (c == 0)
    6. continue;
    7. arr[cnt++] = c;
    8. }
    9. while (cnt < n) {
    10. arr[cnt++] = 0;
    11. }
    Код в целом оптимальный, но первый цикл можно было скомпоновать чуть удачнее:
    1. do {
    2. if ((c = arr[i++]) != 0)
    3. arr[cnt++] = c;
    4. } while (++i < sizeof(arr));

    Во-первых, do-while подходит больше, т.к. размер массива не может быть меньше 1. Бонусом вместо 3 джампов (1-й в самом начале цикла, после проверки условия выхода, 2-й в виде continue и 3-й в конце тела цикла while) получаем всего 2 (1-й в виде if и 2-й после проверки условия выхода из do-while).
    Во-вторых, присваивание в переменную 'c' перемещено в выражение внутри if, чтобы вместо 2 обращений к 'c' (запись в 'c', затем оттуда же чтение) было всего 1 (сначала запись значения в 'c', а затем "повторное использование" того же значения в проверке на равенство нулю, вместо того чтобы заново считывать его из 'c').
    (На самом деле даже это не самый удачный вариант цикла, просто те 2 оптимизационных приёма было проще всего объяснить.)
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  7. #6
    Аватар для m1n1vv
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.09.2015
    Сообщений
    541
    Репутация:
    78 ±
    Делаю, чтобы из диалогового окна пропадал выбранный вариант. Для этой задачи этого может хватить. Игрок не может сразу выбрать 2 пункта.
    PHP код:
    main()
    {
        const
            
    size 5;
            
        new
            
    m[size] = {18203},
            
    index_i;

        for (new 
    0sizei++)
        {
            if (
    m[i] == 0)
            {
                
    index_i == size 1;
                
    m[i] = m[i+index_i];
                
    m[i+index_i] = 0;
            }

            
    printf("%i"m[i]);
        }

    Последний раз редактировалось m1n1vv; 05.02.2019 в 14:38.

  8. #7
    Аватар для x86
    Пользователь

    Статус
    Оффлайн
    Регистрация
    26.01.2019
    Сообщений
    41
    Репутация:
    6 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Код в целом оптимальный, но первый цикл можно было скомпоновать чуть удачнее:
    1. do {
    2. if ((c = arr[i++]) != 0)
    3. arr[cnt++] = c;
    4. } while (++i < sizeof(arr));

    Во-первых, do-while подходит больше, т.к. размер массива не может быть меньше 1. Бонусом вместо 3 джампов (1-й в самом начале цикла, после проверки условия выхода, 2-й в виде continue и 3-й в конце тела цикла while) получаем всего 2 (1-й в виде if и 2-й после проверки условия выхода из do-while).
    Во-вторых, присваивание в переменную 'c' перемещено в выражение внутри if, чтобы вместо 2 обращений к 'c' (запись в 'c', затем оттуда же чтение) было всего 1 (сначала запись значения в 'c', а затем "повторное использование" того же значения в проверке на равенство нулю, вместо того чтобы заново считывать его из 'c').
    (На самом деле даже это не самый удачный вариант цикла, просто те 2 оптимизационных приёма было проще всего объяснить.)
    Можно было вообще вот так сделать:
    1. while ((i < sizeof(arr)) && (c = arr[i++]))
    2. arr[cnt++] = c;


    Запихивать операцию присваивания в условый оператор - не лучшая затея. А вообще плохо, что компилятор глуп на такие оптимизации.
    Последний раз редактировалось x86; 05.02.2019 в 16:17.

  9. #8
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2590 ±
    Цитата Сообщение от x86 Посмотреть сообщение
    А вообще плохо, что компилятор глуп на такие оптимизации.
    Это простой компилятор для простого скриптового языка, а не какой-то там "комбайн" на основе LLVM. Абсолютно ничего необычного.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  10. #9
    Аватар для x86
    Пользователь

    Статус
    Оффлайн
    Регистрация
    26.01.2019
    Сообщений
    41
    Репутация:
    6 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Это простой компилятор для простого скриптового языка, а не какой-то там "комбайн" на основе LLVM. Абсолютно ничего необычного.
    И без LLVM компиляторы пишутся. Причем такая конструкция проста для простого компилятора для простого скриптового языка. В нем же поддерживаются шаблоны инструкций для оптимизации.

  11. #10
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2590 ±
    Цитата Сообщение от m1n1vv Посмотреть сообщение
    Делаю, чтобы из диалогового окна пропадал выбранный вариант. Для этой задачи этого может хватить. Игрок не может сразу выбрать 2 пункта.
    PHP код:
    main()
    {
        const
            
    size 5;
            
        new
            
    m[size] = {18203},
            
    index_i;

        for (new 
    0sizei++)
        {
            if (
    m[i] == 0)
            {
                
    index_i == size 1;
                
    m[i] = m[i+index_i];
                
    m[i+index_i] = 0;
            }

            
    printf("%i"m[i]);
        }

    Так а зачем нужно тратить время на перестановку элементов, когда можно одним циклом найти ноль, а другим просто скопировать последующие элементы на место предыдущего и обнулить последний элемент?
    1. main()
    2. {
    3. static arr[] = {1, 8, 2, 0, 3};
    4. new i = 0;
    5.  
    6. do {
    7. if (arr[i] == 0)
    8. {
    9. do {
    10. arr[i] = arr[++i];
    11. } while (i < sizeof(arr) - 1);
    12. arr[sizeof(arr) - 1] = 0;
    13. break;
    14. }
    15. } while (++i < sizeof(arr) - 1);
    16. }


    Цитата Сообщение от x86 Посмотреть сообщение
    И без LLVM компиляторы пишутся. Причем такая конструкция проста для простого компилятора для простого скриптового языка. В нем же поддерживаются шаблоны инструкций для оптимизации.
    Новые оптимизации никто не добавит - боятся сломать хаки в чьём-нибудь инклуде. Собственно, слова про "ничего необычного" были про сам компилятор, про развиваемый сообществом SA-MP форк разговор отдельный.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •