Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Оценка алгоритма сортировки, Счёт кол-ва перестановок и сравнений 
:(
    Опции темы
Yanis
Дата 16.5.2005, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 1
Всего: 111



Вот тут я написал сортировку (quick sort). Нужно подсчитать кол-во перестановок и сранений (для набора чисел "87950433"):
Код

#include <iostream.h>
#include <conio.h>

int a[8];

int c = 0; /* кол-во сравнений */
int e = 0; /* кол-во перестановок */

/* нахождение опорного элемента */
int findpivot(int i, int j)
{
  int k;

  for (k = i + 1; k <= j; k++)
  {
    if (a[k] > a[i])
    {
      c++;
      return k;
    }
    else
    {
      if (a[k] < a[i])
      {
        c++;
        return i;
      }
    }
  }
  
  return -1;
}; /* findpivot */

/* сортировка участка массива от i до j */
int partition(int i, int j, int w)
{
  int l = i;
  int r = j;

  do {
    // swap elements
    int t = a[l]; a[l] = a[r]; a[r] = t;
    e++;
    
    while (a[l] < w) l++;
    while (a[r] >= w) r--;
    
  } while (l < r);

  return l;
}; /* partiton */

/* собственно сортировка */
void quick_sort(int i, int j)
{
  int ind = findpivot(i, j);

  if (ind != -1)
  {
    int piv = a[ind];
    int k = partition(i, j, piv);

    quick_sort(i, k-1);
    quick_sort(k, j);
  }
};

int main(int argc, char* argv[])
{
  for (int i = 0; i <= 7; i++) cin >> a[i];
  quick_sort(0, 7); 
  for (int i = 0; i <= 7; i++) cout << a[i] << " ";
  cout << endl << endl;

  cout << "Kol-vo sravneniy: " << c << endl;
  cout << "Kol-vo perestanovok: " << e << endl;
  getch();

  return 0;
}

Если кто может посоветовать правильно ли я считаю или нет, то буду очень рад.


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
kometa_triatlon
Дата 16.5.2005, 22:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 384
Регистрация: 7.1.2005
Где: Киев

Репутация: 2
Всего: 6



Этот кусок
Код

for (k = i + 1; k <= j; k++)    
  {    
    c++;
    if (a[k] > a[i])    
    {        
     c++; 
      return k;    
    }    
    else    
    {    
      if (a[k] < a[i])    
      {    
        c++;    
        return i;    
      }    
    }


я бы заменил так:
Код

for (k = i + 1; k <= j; k++){
c++;
return a[k] > a[i]?k:i;
}

Зачем запихивать инкремент с в условие? Все равно сравнение будет, хотя это только с точки зрения объема кода...

А это:
Код

// swap elements    
    int t = a[l]; a[l] = a[r]; a[r] = t;

лучше записать так:
Код

a[l]^=a[r]^=a[l]^=a[r];

Лишняя переменная там не нужна.


--------------------
Всё очень просто: сказки обман,
Солнечный остров скрылся в туман,
Замков воздушных не носит земля,
Кто-то ошибся, ты или я.

--------------
Программирование - самое большое удовольствие, которое вы можете получить, будучи одетым.
PM MAIL ICQ   Вверх
Yanis
Дата 16.5.2005, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 1
Всего: 111



Цитата(kometa_triatlon @ 16.5.2005, 22:36)
лучше записать так:
a[l]^=a[r]^=a[l]^=a[r];

Мне эта запись очень непонятна. Сам бы я до такого не додумался. Может объяснишь в чём тут суть? Операторы работают слева направо?

Код

for (k = i + 1; k <= j; k++){
c++;
return a[k] > a[i]?k:i;
}

Так не пойдёт. Должно срабатывать только если число строго меньше или строго больше. Этот код срабатывает (возвращает i) даже если числа равны.


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
kometa_triatlon
Дата 17.5.2005, 01:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 384
Регистрация: 7.1.2005
Где: Киев

Репутация: 2
Всего: 6



Насчет записи - забей, она мне сама непонятна smile Нам ее препод дал, чтобы мы делали перестановки так. Довольно красиво, правда?

Цитата
Так не пойдёт. Должно срабатывать только если число строго меньше или строго больше. Этот код срабатывает (возвращает i) даже если числа равны.

С чего ты взял?
Извини меня, чтобы узнать, равны числа или нет, их нужно сравнить. Или у тебя есть сравнения двух сортов?


--------------------
Всё очень просто: сказки обман,
Солнечный остров скрылся в туман,
Замков воздушных не носит земля,
Кто-то ошибся, ты или я.

--------------
Программирование - самое большое удовольствие, которое вы можете получить, будучи одетым.
PM MAIL ICQ   Вверх
Yanis
Дата 17.5.2005, 08:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 1
Всего: 111



Цитата(kometa_triatlon @ 17.5.2005, 01:24)
С чего ты взял?
Извини меня, чтобы узнать, равны числа или нет, их нужно сравнить. Или у тебя есть сравнения двух сортов?

Конечно, может я и ошибаюсь, но запись:
Код

return a[k] > a[i]?k:i;

возвращает k, если a[k] больше чем a[i], иначе возвращается i. Если чило a[k] == a[i], то это и есть тот случай - иначе (else). Или я не прав!?


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
Alastis
Дата 17.5.2005, 08:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 15.11.2004
Где: Казахстан, Астана

Репутация: 4
Всего: 10



Цитата(Yanis @ 17.5.2005, 08:06)
Конечно, может я и ошибаюсь, но запись:
Код

return a[k] > a[i]?k:i;

возвращает k, если a[k] больше чем a[i], иначе возвращается i. Если чило a[k] == a[i], то это и есть тот случай - иначе (else). Или я не прав!?

ты не ошибаешься, все именно такsmile


--------------------
Прости, что я говорю, когда ты меня перебиваешь.
PM MAIL WWW ICQ   Вверх
Yanis
Дата 17.5.2005, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 1
Всего: 111



Значит ни у кого этот код и решение моей задачи не вызывает нареканий? Тогда буду доделывать дальше. Всем спасибо.


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
Void
Дата 17.5.2005, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



Цитата(kometa_triatlon @ 17.5.2005, 00:36)
лучше записать так:
лучше записать так:
Код
a[l]^=a[r]^=a[l]^=a[r];

Насчет записи - забей, она мне сама непонятна smile Нам ее препод дал, чтобы мы делали перестановки так. Довольно красиво, правда?

Три последовательных XOR над целыми числами эквивалентны их обмену. Но это некошерно и фактически является undefined behaviour. Читать обсуждение здесь: http://rsdn.ru/Forum/Message.aspx?mid=439731&only=1
Преподу расскажи обязательно smile

Насчет красоты, по-моему, запись
Код
std::swap(a[l], a[r]);

рулит smile И, скорее всего, быстрее будет. И сработает для любых типов, а не только целочисленных.

Это сообщение отредактировал(а) Void - 17.5.2005, 19:31


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Yanis
Дата 17.5.2005, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 1
Всего: 111



To Void
Спасибо. Про undefined behaviour ничего не понял, потому что не умею пользоваться ихним форумом ;) Но из названия я вижу, что это типа "не объявленное поведение" или скорее "не предсказуемое поведение".


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
Yanis
  Дата 17.5.2005, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 1
Всего: 111



To Void
Спасибо. Про undefined behaviour ничего не понял, потому что не умею пользоваться ихним форумом ;) Но из названия я вижу, что это типа "не объявленное поведение" или скорее "не предсказуемое поведение".

Это сообщение отредактировал(а) Yanis - 17.5.2005, 21:49


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
kometa_triatlon
Дата 18.5.2005, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 384
Регистрация: 7.1.2005
Где: Киев

Репутация: 2
Всего: 6



Void
Как вызов функции может сработать быстрее? А насчет undefined, то у меня такого никогда не было. Если с его компилятором работает нормально, так почему бы и нет?

Цитата
возвращает k, если a[k] больше чем a[i], иначе возвращается i. Если чило a[k] == a[i], то это и есть тот случай - иначе (else). Или я не прав!?

Вот елки... Действительно smile
Просто я подумал, что это как обычно поиск максимального элемента, вот и сработал рефлекс smile
Ну если продолжать тему, то правильно будет так:
Код

a[k] > a[i]?k:(a[i]>a[k]?i:(-1));


И насчет количества сравнений: допустим два числа равны, проверяется первое условие (происходит сравнение), не срабатывает, потом второе (опять сравнение), опять не срабатывает. В итоге прошло два сравнения, а их счетчик не увеличился...




--------------------
Всё очень просто: сказки обман,
Солнечный остров скрылся в туман,
Замков воздушных не носит земля,
Кто-то ошибся, ты или я.

--------------
Программирование - самое большое удовольствие, которое вы можете получить, будучи одетым.
PM MAIL ICQ   Вверх
Void
Дата 18.5.2005, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



Цитата(kometa_triatlon @ 18.5.2005, 02:32)
Как вызов функции может сработать быстрее?

Есть такое понятие, как inline-подстановка. И для такой простой функции, как std::swap она выполняется практически всегда. По ссылке все-таки стоит сходить - там приводили asm-листинги, во что скомплировался тот и другой вариант. Как и следовало ожидать, компилятор оказался умнее. Преждевременная оптимизация - корень всех бед smile (с) Кнут, кажется.
Цитата(kometa_triatlon @ 18.5.2005, 02:32)
А насчет undefined, то у меня такого никогда не было. Если с его компилятором работает нормально, так почему бы и нет?

Ну что мы теперь, на конкретный компилятор будем завязываться? Зачем? Это действительно отработает как надо на большинстве компиляторов для целочисленных типов - но завтра понадобится сортировка для double или сложных объектов - что делать будем?



--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
kometa_triatlon
Дата 18.5.2005, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 384
Регистрация: 7.1.2005
Где: Киев

Репутация: 2
Всего: 6



Void
Ну насчет inline я не знал smile Тогда конечно да.

А насчет компилятора - это я к тому, что в данном случае ( для этого типа, на этом компиляторе ) можно спокойно использовать. Сомневаюсь, что это именно такой:
Цитата
у что мы теперь, на конкретный компилятор будем завязываться? Зачем? Это действительно отработает как надо на большинстве компиляторов для целочисленных типов - но завтра понадобится сортировка для double или сложных объектов - что делать будем?

случай


--------------------
Всё очень просто: сказки обман,
Солнечный остров скрылся в туман,
Замков воздушных не носит земля,
Кто-то ошибся, ты или я.

--------------
Программирование - самое большое удовольствие, которое вы можете получить, будучи одетым.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0637 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.