Форум — Ответы     (  К темам )
 ?  Дмитрий: Сортировка двух массивов. Такого еще не было ;) (13-12-2002 13:00:10) http://www.cbuilder.ru
У меня есть два массива: aa[100] и e[100]

Каждому элементу массива aa[i] соответствует элемент массива e[i].
Например, aa[0]="Кошка", e[i]=2. Т.е. затем я считываю информацию,
и у меня получается 2 кошки.

Мне надо отсортировать массив с числами, т.е. e[i], но так, чтобы ему
соответсвовали значения первого массива с животными.

Пример:
массив aa[100]={Кошка, Собака, Мышь};
массив e[100]={2,5,1};

Т.е. у меня 2 кошки, 5 собак и одна мышь.

Если я просто отсортирую массив e[100], у меня получится так:
массив aa[100]={Кошка, Собака, Мышь};
массив e[100]={1,2,5};

Т.е. одна кошка, 2 собаки и 5 мышей. Но это не правильно.

Подскажите, пожалуйста, как отсортировать массивы, чтобы соответствие сохранилось?
Может, с помощью многомерных массивов?

Буду очень благодарен, если напишите работающее решение (например, с помощью qsort).
Заранее спасибо!
 Skolotovich (13-12-2002 13:59:03)
По моему вы пытаетесь "придумать велосипед"

в стандартной поставке C++Builder есть замечательные классы
базирующиеся на TStrings (напр TStringList)
в которых есть все то, что вы хотите сделать руками
а если надо алгоритм -- см. исходники
 Fred (13-12-2002 14:20:10)
Дмитрий, а Вы сами пробовали решить эту задачку ? Если пробовали и не получилось, объясните в чем проблема. Или Вы контрольные для школьных друзей "на шару" решаете ?

"Буду очень благодарен, если напишите работающее решение (например, с помощью qsort)."

Здорово!!! А как на счет ключей от квартиры ? :))
 Вася (13-12-2002 14:51:40)
Ты наверное пошутил, это не реально, такие сложные задачи, не решабельны.

И еще, каждый элемент в массиве имеет свой номер a[4] т.е. a[0], a[1], a[2] ...

А про велосипед — это правильно.
 Дмитрий (13-12-2002 20:32:33) http://www.cbuilder.ru
<B>2Skolotovich:</B> TStringList сортирует ужасно коряво:
1
10
11
2
3

и т.д.

<B>2Fred:</B> "Если пробовали и не получилось, объясните в чем проблема."

Я объяснил, в чем проблема. Мне надо отсортировать два массива таким образом, чтобы первый был отсортирован по числам 12345, а второй не терял соответсвие первому.

Т.е. у меня e[5] соответсвует aa[5]. При сортировке массива чисел (т.е. e[i]), e[5] может стать e[1], но при этом мне надо, чтобы связь с aa[i] сохранилась. Т.е., чтобы aa[5] стал aa[1], как и e[5] стал e[1]. Надеюсь, понятно?

"Или Вы контрольные для школьных друзей "на шару" решаете ?"

Делать мне больше нечего, решаю задачки ;)

"Здорово!!! А как на счет ключей от квартиры ? :)) "

Давай.

<B>Вася:</B>

"Ты наверное пошутил, это не реально, такие сложные задачи, не решабельны."

С чего ты взял?

"И еще, каждый элемент в массиве имеет свой номер a[4] т.е. a[0], a[1], a[2] ..."

Гениально! ;) Так вот мне и надо, чтоюы связь между элементами двх массивов при сортировке не терялась.

"А про велосипед — это правильно."

По-твоему, есть готовое решение? Какое? TStringList В КОРНЕ НЕ ПОДХОДИТ, т.к. это ламоватое подобие сортировки по первым цифрам. Мне надо нормальную сортировку.

--

<FONT color=blue>Извините, но что-то флейм какой-то получается. Реальные-то советы никто не даст? Я вроде все понятно объяснил.</FONT> Комменты — на dmitri@cbuilder.ru

Кто-нибудь действитльно способен помочь, кроме негативных высказываний? Владимир, что Вы скажете?
 Fred (14-12-2002 06:28:16)
Если цифры в TSringList вставлять в формате "%02i", а в Вашем случае этого вполне достаточно, то результат сортировки в приведенном Вами примере, будет выглядеть как:
01
02
03
10
11
Что, собственно, и требуется.

Если Вы хотите решить в явном виде через qsort(), то создайте массив структур struct D { int e, char* aa } d[100]; вставтьте в него значения из исходных массивов и сортируйте сколько угодно. В хэлпе функции qsort() есть даже пример. Туда нужно лишь несколько строк кода добавить и получится решение вашей задачи. Во всяком случае это будет гораздо короче ваших длинных постингов :) Да и быстрее, наверно :)
 Владимир (14-12-2002 19:36:55)
Согласен. Удобнее и правильнее через struct или class
struct D { int e, char* aa } d[100]; или
struct D { int e, AnsiString aa } d[100];
Разумеется, если речь идет о практическом применении в программе,
а не о каком-либо учебном примере на сортировку массивов.
 Devnvd (15-12-2002 11:43:07)
Не надо вообще менять исходные массивы на этапе сортировки!!!

>У меня есть два массива: aa[100] и e[100]

>Каждому элементу массива aa[i] соответствует элемент массива e[i].
>Например, aa[0]="Кошка", e[i]=2. Т.е. затем я считываю информацию,
>и у меня получается 2 кошки.


Вы просто создайте массив целых чисел Index[100]
в котором лежат числа от 0 до 99:
Index[0]=0;
Index[1]=1;
Index[2]=2;
...
Index[99]=99;

Затем вы расписываете вспомогательную функцию сортировки для qsort'а.
Так сортировать мы будем массив Index, то во входных значениях будут просто числа из этого массива.
int sort_function( const void *a, const void *b)
{
int i=*(int *)a; //это просто индекс
int j=*(int *)b; //это просто индекс
// И сравниваем строчки aa[i] и aa[j] если необходимо сортировать по имени
// return( strcmp(aa[i],aa[j]) );
// или если надо сортировать по количеству
return int(e[i]-e[j]);
}
Вызываем сортировку:
qsort((void *)Index, 100, sizeof(Index[0]), sort_function);

В итоге код будет выглядеть так:

char *aa[100]={"Кошка", "Собака", "Мышь"};
int e[100]={2,5,1};
int Index[100]; //Вспомогательный массив можно его создавать динамически

int sort_function( const void *a, const void *b)
{
int i=*(int *)a; //это просто индекс
int j=*(int *)b; //это просто индекс
// И сравниваем строчки aa[i] и aa[j] если необходимо сортировать по имени
// return( strcmp(aa[i],aa[j]) );
// или если надо сортировать по количеству
return int(e[i]-e[j]);
}
//------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//--------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
//Выводим исходные массивы
ListBox1->Clear();
for(int i=0; i < 3; i++)
{
Index[i]=i;
ListBox1->Items->Add(AnsiString(aa[i])+":"+IntToStr(e[i]));
}
qsort((void *)Index, 3, sizeof(Index[0]), sort_function);

//Выводим исходные массивы но в упорядоченном виде
ListBox2->Clear();
for(int i=0; i < 3; i++)
{
int j=Index[i];
ListBox2->Items->Add(AnsiString(aa[j])+":"+IntToStr(e[j]));
}
}
 AndreyAGSoft (16-12-2002 13:22:55) http://andreyagsoft@andreyagsoft.narod.ru/
Используй в первом массиве указатели на другой МАссив.
Подробнее e-mail