C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
сортировка
seg_r
Отправлено: 02.12.2005, 10:28


Дежурный стрелочник

Группа: Участник
Сообщений: 74



есть строки

1/1
1/4
1/8
1/10

обычным способом получается:

1/1
1/10
1/4
1/8

а надо бы так:

1/1
1/4
1/8
1/10

хотелось бы идею того, как это лучше сделать...
спасибо.
Guest
Отправлено: 02.12.2005, 10:55


Не зарегистрирован







Сортировка внутри групп.
seg_r
Отправлено: 02.12.2005, 12:25


Дежурный стрелочник

Группа: Участник
Сообщений: 74



это типа так замучено ??? т.е. сначала отсортировать все что до "/" потом внутри каждой отсортированной группы сортировать все что осталось ... хм...

а более простого решения нет?
Guest
Отправлено: 02.12.2005, 13:09


Не зарегистрирован







Есть — выровнять группы по правому краю
Grigoriy
Отправлено: 02.12.2005, 16:27


Мастер участка

Группа: Участник
Сообщений: 381



Вот это весь код модуля, который я составил.
Функция qsortstrtype1(unsigned int, unsigned int, AnsiString*)
сортирует строки того вида, что описан в первом сообщении.
Функция int cmpstrtype1(AnsiString, AnsiString)
сравнивает две строки этого вида, и возвращает результат меньше 0, если вторая строка по виду считается больше первой.
void __fastcall TForm1::Button1Click(TObject *Sender)
служит для проверки всех остальных функций модуля.
В программе используется один строковый редактор класса TEdit и один редактор класса TMemo.
Если в одной или более строках будет написана абра-кадабра, то аварийной ошибки не будет.
CODE

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1sortstrtype1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
AnsiString masstr[1000];
AnsiString B,tmp;
int cmpstrtype1(AnsiString S1, AnsiString S2)
{
AnsiString TS1,TS2;
int k1,k2,r;
if (!S1.Length()||!S2.Length()) return (S1.Length()-S2.Length());
if (S1[S1.Length()]!='/')S1+="/";
if (S2[S2.Length()]!='/')S2+="/";
r=0;
do
{
k1=S1.Pos("/");
k2=S2.Pos("/");
TS1=S1.SubString(1,k1-1);
TS2=S2.SubString(1,k2-1);
S1.Delete(1,k1);
S2.Delete(1,k2);
}
while(!(r=TS1.ToIntDef(0)-TS2.ToIntDef(0))&&S1.Length()&&S2.Length());
return r;
};

void qsortstrtype1(unsigned int L, unsigned int R, AnsiString* S)
{
unsigned int i,j;
B=S[(L+R)>>1];
i=L+1;j=R+1;
while (i<=j)
{
while (cmpstrtype1(S[i-1],B)<0) i++;
while (cmpstrtype1(S[j-1],B)>0) j--;
if (i<=j){tmp=S[i-1];S[i-1]=S[j-1];S[j-1]=tmp;i++;j--;}};
if ((L+1)<j) qsortstrtype1(L,j-1,S);
if (i<(R+1)) qsortstrtype1(i-1,R,S);
};


//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
for (int i=0;i<Memo1->Lines->Count;i++)
{masstr[i]=Memo1->Lines->Strings[i];};
qsortstrtype1(0,Memo1->Lines->Count-1,masstr);
for (int i=0;i<Memo1->Lines->Count;i++)
{Memo1->Lines->Strings[i]=masstr[i];};
}

agisland
Отправлено: 05.12.2005, 04:27


Ученик-кочегар

Группа: Участник
Сообщений: 14



Тебе наверное надо перевести свои строки в тип double а потом отсортировать
AVC
Отправлено: 05.12.2005, 11:18


Ветеран

Группа: Модератор
Сообщений: 1583



Callback quick sort'а (лучше из STL) с моей точки зрения самое приемлемое решение. Та же сортировка внутри групп, но за один проход.

Вернуться в Вопросы программирования в C++Builder