Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - [решено] Пара вопросов по Блочной сортировке

Ответить
Настройки темы
C/C++ - [решено] Пара вопросов по Блочной сортировке

Аватара для Drongo

Будем жить, Маэстро...


Сообщения: 6694
Благодарности: 1393


Конфигурация

Профиль | Сайт | Отправить PM | Цитировать


Товарищи! Тут по заданию решил задачу "Блочная сортировка", вроде решил, но такой вопрос, мне кажется, что я не так её решил, как нужно. Не могли бы вы подсказать, насколько я неправильно решил, хотя код рабочий, но можно как-то улучшить конструкцию, например:
1. Хочу, чтобы массив перебирался и вычислялось число у которого чисел в разрядах наибольшее количество, пример: "7" = 1 разряд в числе, "243" - 3 раряда в числе, "23888" - 5 разрядов, "24" - 2 разряда, и т.д. Это нужно для вычисления проходов в цикле for, Чтобы в первом цикле for можно было подставлять вычисленное число, а не вручную, как сейчас "5", мне кажется нужна функция: которая принимает число и переводит его в строку, но я не знаю эту функцию, подскажете?!
Код: Выделить весь код
len = strlen(функция ЧислоВСтроку(ar[j]));
2. И ещё почему при размере массива в 20000 функция работает, а с размером уже больше 20 тысяч вылетает в ошибку?! Проверял только до 100000 и выставлял, число в разрядах "6". Что не так?!
Прочитал тему на форуме Последовательность чисел Подумал, а нельзя ли как-нибудь использовать исключающее "И" или "или"?! Для сортировки. Как решено в этой теме 5pliT-ом, если можно то как?!
В общем раскритикуйте мой код или укажате на слабые места, если можно с поправкой. Буду благодарен!
Код: Выделить весь код
// Блочная сортировка---------------------------------------------------------------------------
#include <iostream.h>
using std::cout;
using std::cin;
using std::endl;

#include <iomanip.h>
using std::setw;

#include <cstring>

#include <stdlib.h>
#include <ctime.h>
using std::time;

void bucketSort(int ara[], const int sze);

int main()
{
   const int size = 20000;
   int array[size] = {0};
   int z = 1;

   srand(time(0));

   cout<<" Inizialization array..."<<endl;
   for(int i = 0; i < size; i++)
      array[i] = rand() % size; // Генерация случайных чисел для заполнения массива первоначальными значениями

   for(int j = 0; j < size; j++)
      cout<<setw(8)<<array[j]; // Вывод НЕСОРТИРОВАННОГО массива

   cout<<"----------------------------------------------------------------------"<<endl<<endl<<endl;

   bucketSort(array, size); // Функция сортировки

   cin>>z;
   
   return 0;
}
//---------------------------------------------------------------------------
void bucketSort(int ar[], const int sz)
{
   const int Rasryad = 10;
   const int Position = 20000;
   int TempArray[Rasryad][Position] = {0};
   int /*lenght = 0,*/ temp, number = 1, Ras, counter = 0;;

//   for(int j = 0; j < sz; j++){
  //     temp = strlen((ar[j]));
    //   if(lenght < temp)
      //    lenght = temp;
     //}

   // Распределяющий проход
   for(int i = 0; i < 5; i++){ // Проход столько, сколько разряда у числа
       for(int j = 0; j < sz; j++){ // Проход столько, сколько чисел в массиве
           Ras = ar[j] / number % 10; // Вычисление позиции разряда
           TempArray[Ras][j] = ar[j]; // Расположение соответсвенно разряду
         }
       // Собирающий проход после каждого распределяющего
	   counter = 0;
       for(int a = 0; a < Rasryad; a++){
           for(int b = 0; b < Position; b++){
               if(TempArray[a][b] != 0){
                  ar[counter++] = TempArray[a][b];
                  TempArray[a][b] = 0;
                 }
             }
         }
       number *= 10;
     }

    for(int i = 0; i < sz; i++) // Вывод сортированного массива
      cout<<setw(8)<<ar[i];
}
//-------------------------------------------------------------------------

-------
Правильная постановка вопроса свидетельствует о некотором знакомстве с делом.
3нание бывает двух видов. Мы сами знаем предмет — или же знаем, где найти о нём сведения.
[Quick Killer 3.0 Final [OSZone.net]] | [Quick Killer 3.0 Final [SafeZone.cc]] | [Парсер логов Gmer] | [Парсер логов AVZ]

http://tools.oszone.net/Drongo/Userbar/SafeZone_cc.gif


Отправлено: 19:33, 03-01-2008

 

Аватара для 5pliT

Новый участник


Сообщения: 21
Благодарности: 9

Профиль | Отправить PM | Цитировать


Цитата Drongo:
1. Хочу, чтобы массив перебирался и вычислялось число у которого чисел в разрядах наибольшее количество, пример: "7" = 1 разряд в числе, "243" - 3 раряда в числе, "23888" - 5 разрядов, "24" - 2 разряда, и т.д. Это нужно для вычисления проходов в цикле for, Чтобы в первом цикле for можно было подставлять вычисленное число, а не вручную, как сейчас "5", мне кажется нужна функция: которая принимает число и переводит его в строку, но я не знаю эту функцию, подскажете?! »
Число в строку приобразует функция:
char * itoa ( int value, char * str, int base );
обычно её можно найти в stdlib.h.
Или можно написать самому примерно так:
Код: Выделить весь код
char* itoa(int val, int base) { 
	char buf[32] = {0}; 
	int i=30; 
	for(;val&&i;--i,val/=base) 
	buf[i]="0123456789abcdef"[val%base]; 
	return &buf[i+1]; 
}
Количество разрядов можно подсчитать ещё проще примерно так:
Код: Выделить весь код
int rzr(int nn) {
	int n=nn,x=0;
	while (n<>0) { 
		n/=10;
		x++;
	}
	return x;
}
Цитата Drongo:
2. И ещё почему при размере массива в 20000 функция работает, а с размером уже больше 20 тысяч вылетает в ошибку?! Проверял только до 100000 и выставлял, число в разрядах "6". Что не так?! »
Думаю дело в диапозонах значений стандартных типов. Попробуйте использовать не int, а long long например.

Цитата Drongo:
Прочитал тему на форуме Последовательность чисел Подумал, а нельзя ли как-нибудь использовать исключающее "И" или "или"?! Для сортировки. Как решено в этой теме 5pliT-ом, если можно то как?! »
Исключающее ИЛИ можно использовать для обмена значений. Я не думаю что алгоритм блочной сортировки не меняет элементы массива местами, поэтому тот код также подойдёт.
Это сообщение посчитали полезным следующие участники:

Отправлено: 21:19, 04-01-2008 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Аватара для Drongo

Будем жить, Маэстро...


Сообщения: 6694
Благодарности: 1393

Профиль | Сайт | Отправить PM | Цитировать


Цитата 5pliT:
использовать не int, а long long например. »
Возможно, попробую - доложу о результатах! Функцию itoa знаю, но лишь визуально, меня смущал сам прототип! Попробую!
Цитата 5pliT:
Количество разрядов можно подсчитать ещё проще »
Просто огромнейшее спасибо!!!

-------
Правильная постановка вопроса свидетельствует о некотором знакомстве с делом.
3нание бывает двух видов. Мы сами знаем предмет — или же знаем, где найти о нём сведения.
[Quick Killer 3.0 Final [OSZone.net]] | [Quick Killer 3.0 Final [SafeZone.cc]] | [Парсер логов Gmer] | [Парсер логов AVZ]

http://tools.oszone.net/Drongo/Userbar/SafeZone_cc.gif


Отправлено: 21:26, 04-01-2008 | #3

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Drongo, отсортируйте массив: 123, 456, 7890 Мне кажется в этом месте:
Код: Выделить весь код
ar[counter++] = TempArray[a][b];
counter превысит 3, если я правильно понял, конечно. Задали массив 3 числа, а после сортировки получили динее...
Это сообщение посчитали полезным следующие участники:

Отправлено: 22:11, 04-01-2008 | #4


Аватара для Drongo

Будем жить, Маэстро...


Сообщения: 6694
Благодарности: 1393

Профиль | Сайт | Отправить PM | Цитировать


pva, Спасибо за ответ и помощь, но
Цитата pva:
Код: Выделить весь код
ar[counter++] = TempArray[a][b];
»
я не думаю, поскольку индексирование начинается с нуля "0 1 2 3 4 5 6 7 8 9", и потому счётчик counter++ лишь всегда будет равен переменной sz, если sz = 20000, то и counter после собирающего прохода тоже будет равен 20000, поскольку если элемент в массиве TempArray[a][b] не всегда расположен последовательно, то идёт проверка, если n-й элемент TempArray, не равен нулю, то присвоить массиву ar[] первое значение, и в итоге всё будет правильно, ведь сортируемых чисел только 20000, следовательно, правильных условий тоже будет 20000, сегодня проверял, но всё равно ошибка при значении размера массивов больше чем 20000 то "ошибается", вот тут:
Код: Выделить весь код
TempArray[Ras][j] = ar[j]; // Расположение соответсвенно разряду
Почему?! Незнаю, иной раз сортирует 14 элементов, иной раз 2, иной раз 7, почему так, хоть убейте, не знаю?!
----------------------------------------------------------------------
Привет 5pliT, тут кажись ошибка
Цитата 5pliT:
while (n<>0) { »
может ты имеешь ввиду:
Код: Выделить весь код
while(n < 0 || n > 0)
или
Код: Выделить весь код
while(n < 0 && n > 0)
А по поводу
Цитата 5pliT:
Попробуйте использовать не int, а long long например »
разницы то нет, в типе int переменная хранится в 4-х байтах, этого хватит даже больше, чем на миллион если поставлю, кроме того, пробовал без сортировки используя только несортированный массив выводить из функции bucketSort - так функция принимает и выводит значения, вот если бы была ошибка алгоритма, то сортировки бы не было, но тем не менее при размере массива в 20000 всё работает, а больше ни в какую, причём почему-то несколько значений даже "пробуют" сортироваться, вот если не будет трудно, то попробуй на своём компиляторе скопировать мой код и попробовать изменить всего два значения, я их выделил жирным шрифтом:
Код: Выделить весь код
int main()
{
 const int size = 20000;
 int array[size] = {0};
....
и тут:
Код: Выделить весь код
void bucketSort(int ar[], const int sz)
{
 const int Rasryad = 10; 
 const int Position = 20000;
 int TempArray[Rasryad][Position] = {0};
....
Разряды не трогаем, поскольку в 50000 и в 20000 по 5 разрядов в числе, попробуй пожалуйста, посмотри что за ошибка?! Проблема явно не в типе переменной, стопроцентно!

-------
Правильная постановка вопроса свидетельствует о некотором знакомстве с делом.
3нание бывает двух видов. Мы сами знаем предмет — или же знаем, где найти о нём сведения.
[Quick Killer 3.0 Final [OSZone.net]] | [Quick Killer 3.0 Final [SafeZone.cc]] | [Парсер логов Gmer] | [Парсер логов AVZ]

http://tools.oszone.net/Drongo/Userbar/SafeZone_cc.gif


Последний раз редактировалось Drongo, 05-01-2008 в 20:18. Причина: Добавлены поправки и комментарии...


Отправлено: 19:31, 05-01-2008 | #5


Аватара для 5pliT

Новый участник


Сообщения: 21
Благодарности: 9

Профиль | Отправить PM | Цитировать


Цитата Drongo:
Привет 5pliT, тут кажись ошибка
Цитата 5pliT:while (n<>0) { » »
Ой, прошу прощения. В голове языки путаются <> - это знак "не равно" в паскале. А в си это так: !=

Где у вас ошибка я не знаю, это отлавливать надо. Но думаю, что или в этой строчке:
TempArray[Ras][j] = ar[j];
или в этой:
ar[counter++] = TempArray[a][b];
Это сообщение посчитали полезным следующие участники:

Отправлено: 12:02, 06-01-2008 | #6


Аватара для Drongo

Будем жить, Маэстро...


Сообщения: 6694
Благодарности: 1393

Профиль | Сайт | Отправить PM | Цитировать


Цитата 5pliT:
А в си это так: != »
Спасибо я уже догадался! )))
Буду разбираться...

-------
Правильная постановка вопроса свидетельствует о некотором знакомстве с делом.
3нание бывает двух видов. Мы сами знаем предмет — или же знаем, где найти о нём сведения.
[Quick Killer 3.0 Final [OSZone.net]] | [Quick Killer 3.0 Final [SafeZone.cc]] | [Парсер логов Gmer] | [Парсер логов AVZ]

http://tools.oszone.net/Drongo/Userbar/SafeZone_cc.gif


Отправлено: 21:19, 06-01-2008 | #7

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Drongo, с алгоритмом похоже всё в порядке. Интересно, на каком компиляторе вы собирали и отлаживали? у меня сразу при входе в bucketSort вышла ошибка stack overflow. Варианта решения 2: сказать компилятору увеличить стек или использовать динамическую память. Вот в таком виде всё заработало:
Код: Выделить весь код
void bucketSort(int ar[], const int sz)
{
   const int Rasryad = 10;
   const int Position = 100000;

   vector<int> mem_TempArray(Position*Rasryad);
   int* TempArray[Rasryad];
   
   for(unsigned n=0; n<Rasryad; ++n) TempArray[n] = &mem_TempArray[Position*n];
   
   int /*lenght = 0, temp,*/ number = 1, Ras, counter = 0;;

   // Распределяющий проход
   for(int i = 0; i < 5; i++){ // Проход столько, сколько разряда у числа
       for(int j = 0; j < sz; j++){ // Проход столько, сколько чисел в массиве
           Ras = ar[j] / number % 10; // Вычисление позиции разряда
           TempArray[Ras][j] = ar[j]; // Расположение соответсвенно разряду
         }
       // Собирающий проход после каждого распределяющего
	   counter = 0;
       for(int a = 0; a < Rasryad; a++){
           for(int b = 0; b < Position; b++){
               if(TempArray[a][b] != 0){
                  ar[counter++] = TempArray[a][b];
                  TempArray[a][b] = 0;
                 }
             }
         }
       number *= 10;
     }

    for(int i = 0; i < sz; i++) // Вывод сортированного массива
      cout<<setw(8)<<ar[i];
}
//-------------------------------------------------------------------------
Это сообщение посчитали полезным следующие участники:

Отправлено: 13:32, 07-01-2008 | #8


Аватара для Drongo

Будем жить, Маэстро...


Сообщения: 6694
Благодарности: 1393

Профиль | Сайт | Отправить PM | Цитировать


Цитата pva:
Интересно, на каком компиляторе вы собирали и отлаживали? »
Borland C++ Builder
Цитата pva:
vector<int> mem_TempArray(Position*Rasryad); »
Цитата pva:
стек »
Этого я не изучал ещё....
Цитата pva:
динамическую память. »
- а вот это через оператор new Но похоже не то... А Вам огромное спасибо, за подсказку, а отчего такая ошибка получается?! Подскажите?! Это мне интересно очень!!! Насколько я знаю, vector контейнерный класс, да?!

-------
Правильная постановка вопроса свидетельствует о некотором знакомстве с делом.
3нание бывает двух видов. Мы сами знаем предмет — или же знаем, где найти о нём сведения.
[Quick Killer 3.0 Final [OSZone.net]] | [Quick Killer 3.0 Final [SafeZone.cc]] | [Парсер логов Gmer] | [Парсер логов AVZ]

http://tools.oszone.net/Drongo/Userbar/SafeZone_cc.gif


Отправлено: 20:09, 07-01-2008 | #9

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Начиная ещё с первых компьютеров разработали хитрую систему для передачи данных между блоками программы и для выделения памяти под собственные нужды блоков. ПРичём надо было сделать так, чтобы
Код: Выделить весь код
// каждый вызов func1 должен иметь собственную память для x
void func1(int z)
{
   int x = z;
   ...

   if (0<x) func1(x-1);
}
Делается это просто. Есть участок памяти, называемый "стек". Он и действует по принципу "последний зашёл, первый вышел". Есть специальный регистр процессора, содержит адрес дна стека (допустим SP). При входе в функцию ей даётся память от SP-n до SP, где n - количество байт, требуемых для функции и SP уменьшается на n. При возврате из функции SP обратно увеличивается на n.
Код: Выделить весь код
// древний компьютер (карта памяти в килобайтах):
// R - ПЗУ, P - код программы, S - стек (задом-наперёд), пробелы - свободная память
// 00k RRRRRRRR 16k PPP      SSS 32k
// свободная память постоянно уменьшается с ростом стека
сейчас сохранился тот же подход, с отличием, что страницы памяти стека могут и не быть загружены в физическую память и лежат в произвольном порядке. И ещё есть искусственное ограничение на размер стека. У меня в настройках проекта стояла цифра 1МБ. Более подробно о стеке можно прочитать в википедии.

template<typename T> class vector {...} - это шаблон C++ контейнера с упорядоченным расположением элементов в свободной памяти. Контейнер - не в том смысле, в каком употребляется в гуишных библиотеках, а для хранения одинаковых структур в памяти. В угловых скобках пишется класс, для которого (основные ограничения):
1. есть явный конструктор по умолчанию explicit T() и конструктор копирования T(const T&)
2. нет побочных эффектов при копировании
3. нет чистых вируальных функций
при раскрытии шаблона создаётся новый класс, который имеет такое хитрое имя vector<T>.

можно сделать через оператор new:
Код: Выделить весь код
int* mem_TempArray = new int[Position*Rasryad];
...
delete[] mem_TempArray;
но в случае исключения память освобождена не будет (а вектор всегда освобождает за собой память)
Это сообщение посчитали полезным следующие участники:

Отправлено: 16:50, 08-01-2008 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - [решено] Пара вопросов по Блочной сортировке

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
[решено] Пара вопросов по видеокартам в плане железа и OEM Windows... Gold Dragon Хочу все знать 22 09-01-2010 19:10
[решено] Gigabyte GA-MA78LM-S2 пара вопросов по камню и памяти. QuartZz Материнские платы и память 2 04-11-2009 00:04
[решено] Пара вопросов про GPO и SRP. PoliceMan Microsoft Windows NT/2000/2003 1 29-10-2009 14:00
[решено] Пара вопросов о сети :) Hattori_Hanzo Хочу все знать 4 01-06-2009 14:04
[решено] пара вопросов о замедлении видеокарты. 12341234 Разгон, охлаждение и моддинг 5 09-07-2008 20:38




 
Переход