Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.145.184.117] |
|
Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Добрый день!
Нужны советы или подсказки или литература,откуда можно взять сортирвку по алфавиту и по возрастающей цене. Просто то,что я находил сам,всё через массивы,а мне через указатели(у меня список) Это нужно для программы(базы-данных),там всё через указатели и без классов.Программу я выкладывал в другом посте. Выкладываю что где объявил и сами процедуры сортировки.Преподаватель сказал, что нужно или желательнее сортировку пузырьком применять. Код: const n_items = 7; l_name = 30; type tname = string[l_name]; pTovar = ^Tovar; Tovar = record name: tname; kolvo: integer; cena: real; next: pTovar; prev: pTovar; end; var DefaultMode, ActiveColor, InactiveColor: word; key: char; item: word; prev: word; beg: pTovar; fin: pTovar; p: pTovar; name: tname; tovr: Tovar; Сортировка 1-ключ-буква-По Алфавиту.То есть имя Товара нужно отсортировать по алфавитному порядку. Код: procedure Sortkey1(p:pTovar; const tovr:tname); var tmp,tmps:pTovar; begin New(tmp); while p<>nil do begin tmp:=p^.next; while tmp<>nil do begin if tmp^.name<p^.name then begin tmps:=tmp^.name; tmp^.name:=p^.name; p^.name:=tmps end; tmp:=tmp^.next end; p:=p^.next end end; ругается на name несоотвествие типа. Сортировка 2-ключ цифра-по цене по возрастающей Код: procedure Sortkey2(cena:pTovar); var tmp,beg,fin,p:pTovar; begin rab:=nach; while p<>nil do begin tovr:=p^.next; while tmp<>nil do begin if tmp^.cena<p^.cena then begin beg:=nil; fin:=nil; if p<>nil then while beg^.next<>p do beg:=beg^.next; fin:=tmp^.next; if p^.next=tmp then begin tmp^.next:=p; p^.next:=fin end else begin tmp^.next:=p^.next; p^.next:=fin; end; if beg<>p then beg^.next:=p; if p<>nil then pered^.next:=tmp else fin:=tmp; tmp:=p; p:=beg; end; tmp:=tmp^.next; end; p:=p^.next; end; end; |
Сообщ.
#2
,
|
|
|
Цитата The_Beginner @ Ну в Си есть strcmp, а в Паскале наверное что-то подобное. Её используйте для сравнения строк:ругается на name несоотвествие типа. if( strcmp( tmp^.name, p^.name)<0 ) then |
Сообщ.
#3
,
|
|
|
для 1 листинга
Цитата The_Beginner @ ругается на name несоотвествие типа. tmp,tmps:pTovar; ................ tmps:=tmp^.name; <---- tmps (тип pTovar) := tmp^.name (тип tname) |
Сообщ.
#4
,
|
|
|
Не помогает)Выложу код своей программы лучше..У меня вопрос еще куда вставить массив,я так подумал создам Массив(где будет запись Товар) и по ней сортировать или как можно сделать?
В данный момент меня интересует сортировка,программа пока не работает,просто посмотрите Процедуры SortByCena,SortByName. правильно ли я описываю их в своей программе,всё-таки у меня линейный список,указатели и прочее. const n_items = 7; l_name = 30; MaxCount=1000; type tname = string[l_name]; pTovar = ^Tovar; Tovar = record name: tname; kolvo: integer; cena: real; next: pTovar; prev: pTovar; end; Massive_of_Tovar:array [1..MaxCount] of Tovar; var DefaultMode,ActiveColor,InactiveColor:word; key:char; item:word; prev:word; beg:pTovar; ovar; fin: pTovar; p: pTovar; name: str_name; tovr: Tovar; MasZap:Massive_of_Tovar; procedure Add(var beg, fin: pTovar; const tovr: Tovar); forward; procedure Clear; forward; procedure Del(var beg, fin, p: pTovar); forward; procedure DlgWindow; forward; procedure DrawItem(item, color: word); forward; procedure Edit(beg: pTovar; const tovr: Tovar); forward; procedure Error(message: string); forward; function Find(p: pTovar; const tovr:str_name): pTovar; forward; procedure Info(const tovr: Tovar); forward; procedure InitMenu(ActvieColor, InactiveColor: word); forward; procedure Message(message: string); forward; procedure Query(var tovr: Tovar); forward; procedure QueryName(var name: str_name); forward; procedure ReadFile(var beg, fin: pTovar); forward; procedure Select(beg: pTovar); forward; procedure SortByName(var Mas : Massive_of_Tovar; MaxCount : integer); procedure SortByCena(var Mas : Massive_of_Tovar; MaxCount : integer); procedure ShowBase(beg: pTovar); forward; procedure Add(var beg, fin: pTovar; const tovr: Tovar); var p: pTovar; begin new(p); p^ := tovr; p^.next := nil; p^.prev := fin; if beg = nil then beg := p else fin^.next := p; fin := p; end; procedure Clear; begin window(1, 3, 80, 25); TextColor(White); Clrscr; end; procedure Del(var beg, fin, p: pTovar); begin if (p = beg) and (p = fin) then begin beg := nil; fin := nil; end else if p = beg then begin beg := beg^.next; beg^.prev := nil end else if p = fin then begin fin := fin^.prev; fin^.next := nil; end else begin p^.prev^.next := p^.next; p^.next^.prev := p^.prev; end; dispose(p); end; procedure DlgWindow; begin window(10, 6, 70, 12); TextColor(Green); TextBackground(LightGray); clrscr; end; procedure DrawItem(item, color: word); const d = 12; items: array[1..n_items] of string[d] = ('Vivod bazi dannix', 'Dobavlenie', 'Izmenenie', 'Udalenie', 'Poisk', 'Sort1','Sort2','Spxranit', 'Vixod'); pos: array[1..n_items] of integer = (1 , d + 2, 2 * d + 3, 3 * d + 3, 4 * d + 3, 5 * d + 0, 6 * d - 6 + 3, 6 * d + 0, 7 - 7); begin window(1, 1, 80, 2); TextBackGround(LightGray); TextColor(Color); gotoXY(pos[item], 1); write(items[item]); end; procedure edit(beg: pTovar; const tovr: Tovar); var p: pTovar; begin p := Find(beg, tovr.name); if p <> nil then begin p^.kolvo := tovr.kolvo; p^.cena := tovr.cena; end; end; procedure error(message: string); begin window(1, 1, 80, 25); TextColor(Red); clrscr; gotoXY(35, 12); write(message); repeat until keypressed; TextMode(DefaultMode); halt; end; function Find(p: pTovar; const tovr:str_name): pTovar; begin while p <> nil do begin if tovr=p^.name then begin Find := p; exit; end; p := p^.next; end; Message('Tovar ne naiden'); Find := nil; end; procedure Info(const tovr: Tovar); begin DlgWindow; with tovr do begin gotoXY(2, 2); writeln('Nazvanie tovara:', name); gotoXY(2, 4); writeln('Kolichestvo tovara:', kolvo);; gotoXY(2, 6); writeln('Cena tovara:', cena:5:2); end; readln; end; procedure InitMenu(ActvieColor, InactiveColor: word); var item: word; begin window(1, 1, 80, 2); TextBackGround(lightGray); clrscr; DrawItem(1, ActiveColor); for item := 2 to n_items do DrawItem(item, InactiveColor); gotoXY(1, 2); TextColor(InactiveColor); write('----------------------------------------------------------------------'); gotoXY(1, 1); end; procedure Message(message: string); begin DlgWindow; gotoXY(2, 4); write(message); readln; end; procedure Query(var tovr: Tovar); var s: string; err: integer; i, len: integer; begin DlgWindow; with tovr do begin repeat gotoXY(2, 2); write('Nazvanie Tovara: '); clreol; readln(name); len := length(name); for i := len + 1 to l_name do name := name + ' '; until len <> 0; repeat gotoXY(2, 4); write('Kolichestvo tovara: '); clreol; readln(s); val(s, kolvo, err); until(err = 0) and (kolvo > 0); repeat gotoXY(2, 6); write('Cena tovara: '); clreol; readln(s); val(s, cena, err); until(err = 0) and (cena > 0); end; end; procedure QueryName(var name: str_name); var i, len: integer; begin DlgWindow; gotoXY(2, 2); write('Nazvanie tovara: '); clreol; readln(name); len := length(name); for i := len + 1 to l_name do name := name + ' '; end; procedure ReadFile(var beg, fin: pTovar); var f: text; tovr: Tovar; begin {$I-} assign(f, 'bazatovarov.txt'); rewrite(f); reset(f); if (IOResult <> 0) then Error('Fail bazatovarov.txt ne naiden'); {$I+} while not eof(f) do begin with tovr do readln(f, name, kolvo, cena); Add(beg, fin, tovr); end; close(f); end; procedure Select(beg: pTovar); procedure SortByName(var Mas : Massive_of_Tovar; MaxCount : integer); var i, j : integer; msX : Tovar; begin for i:=1 to MaxCount-1 do for j:=i+1 to MaxCount do if Mas[i].name > Mas[j].name then begin msX:=Mas[i]; Mas[i]:=Mas[j]; Mas[j]:=msX end; end; procedure SortByCena(var Mas : Massive_of_Tovar; MaxCount : integer); var i, j : integer; msX : Tovar; begin for i:=1 to MaxCount-1 do for j:=i+1 to MaxCount do if Mas[i].cena > Mas[j].cena then begin msX:=Mas[i]; Mas[i]:=Mas[j]; Mas[j]:=msX end; end; procedure ShowBase(beg: pTovar); const step = 18; procedure ShowPage(var p: pTovar); var i: integer; begin clrscr; gotoXY(1, 1); writeln('Nazvanie tovara Kolichestvo Tovara Cena Tovara'); i := 0; while p <> nil do begin with p^ do writeln(' ', name, kolvo:5, cena:30:2); p := p^.next; inc(i); if i > step then exit; end; end; var i: integer; key: char; p, pn: pTovar; begin if beg = nil then begin Message('Spisok pyst'); exit end; window(3, 4, 78, 24); TextBackGround(LightGray); TextColor(white); p := beg; while true do begin pn := p; ShowPage(p); key := readkey; if key = #0 then key := readkey; case ord(key) of 27: exit; 13, 80{down}, 81: if p = nil then p := pn; 72, 73{up}: begin p := pn; for i := 1 to step do begin p := p^.prev; if p = nil then begin p := beg; break end; end; end; end; end; end; begin DefaultMode := LastMode; TextMode(C80); beg := nil; fin := nil; ReadFile(beg, fin); clrscr; ActiveColor := LightGreen; InactiveColor := Green; InitMenu(ActiveColor, InactiveColor); item := 1; prev := 1; while true do begin key := readkey; if key = #0 then key := readkey; case ord(key) of 13: case item of 1: ShowBase(beg); 2: begin Query(tovr); Add(beg, fin, tovr); end; 3: begin Query(tovr); Edit(beg, tovr); end; 4: begin QueryName(name); p := Find(beg, name); if p <> nil then Del(beg, fin, p); end; 5: begin QueryName(name); p := Find(beg, name); if p <> nil then Info(p^); end; 6: begin QueryName(name); SortByName(MasZap,MaxCount); end; 7: begin QueryName(name); SortByName(MasZap,MaxCount); end; 8: exit; end; 15{Shift+Tab}, 75{Left}: begin prev := item; dec(item); if item = 0 then item := n_items; end; 9{Tab}, 77{Right}: begin prev := item; inc(item); if item = n_items + 1 then item := 1; end; end; Clear; DrawItem(prev, InactiveColor); DrawItem(item, ActiveColor); end; TextMode(DefaultMode); end; end. |
Сообщ.
#5
,
|
|
|
Цитата The_Beginner @ Да вроде нормально описываете. Но вы ж не пользуетесь списками, а по индексам бегаете. Куда ж тут смотреть, на пузырёк? В данный момент меня интересует сортировка,программа пока не работает,просто посмотрите Процедуры SortByCena,SortByName. правильно ли я описываю их в своей программе,всё-таки у меня линейный список,указатели и прочее. Добавлено Ах да, вы же кашу создаёте в полях prev/next, когда в сортировке меняете пару. Там надо чинить эти поля, если нужны вам будут. |
Сообщ.
#6
,
|
|
|
The_Beginner,
1. Твоя прога из поста #4 даже не компилируется. 2. На другом форуме я уже давал тебе совет и ссылки что почитать. Судя по твоим постам здесь и на других форумах, ты просто перебираешь варианты. Но это - не ЕГЭ. Почему ты не хочешь думать?! На основе ссылок я собрал пример. Сортировка ListSort - цельнодраная из какого-то примера и за оптимальность не ручаюсь - для сравнения с твоей реализацией. Сортировка ListSortUni - она же после небольшой модификации для универсальности - ей дополнительно передаётся функция сравнения. program SortByField; type TInfo = record Name: string; Kolvo: integer; Cena: real; end; PBiDirList = ^TBiDirList; TBiDirList = record Info: TInfo; Next: PBiDirList; Prev: PBiDirList; end; CompareFunc = function(a, b: TInfo): integer; function Pad(const s: string; N: integer): string; var i: integer; r: string; begin r := s; for i := Length(s) + 1 to N do r := r + ' '; Pad := r; end; procedure ListAddItem(var List: PBiDirList; Info: TInfo); var tmp: PBiDirList; begin New(tmp); tmp^.Info := Info; tmp^.Next := nil; tmp^.Prev := nil; if List <> nil then begin List^.Prev := tmp; tmp^.Next := List; List := tmp; end; List := tmp; end; procedure ListClear(var List: PBiDirList); var tmp: PBiDirList; begin while List <> nil do begin tmp := List; List := List^.Next; Dispose(tmp); end; List := nil; end; procedure LoadListFromFile(var List: PBiDirList; FileName: string); var f: System.Text; Info: TInfo; begin Assign(f, FileName); {$I-} reset(f); {$I+} if IOResult <> 0 then exit; while not EOF(f) do begin {$I-} readln(f, Info.Name); if IOResult <> 0 then Break; readln(f, Info.Kolvo); if IOResult <> 0 then Break; readln(f, Info.Cena); if IOResult <> 0 then Break; {$I+} ListAddItem(List, Info); end; Close(f); end; procedure ListShow(List: PBiDirList); var i: integer; s: string; begin if List = nil then writeln('empty list'); i := 0; while List <> nil do begin Inc(i); with List^.Info do begin s := Pad(Name, 55); writeln(i: 4, '. ', s, Kolvo: 8, Cena: 8: 2); List := List^.Next; end; end; end; procedure ListSort(var List: PBiDirList); var tmp, rab: PBiDirList; tmps: TInfo; begin rab := List; while rab <> nil do begin tmp := rab^.Next; while tmp <> nil do begin if tmp^.Info.Cena < rab^.Info.Cena then begin tmps := tmp^.Info; tmp^.Info := rab^.Info; rab^.Info := tmps; end; tmp := tmp^.Next; end; rab := rab^.Next; end; end; { функции сравнения различных полей структуры TInfo. Результат: 1 - если поле из a больше поля из b, 0 - если поле из a равно полю из b, -1 - если поле из a меньше поля из b } function CompFuncName(a, b: TInfo): integer; begin if a.Name = b.Name then CompFuncName := 0 else if a.Name > b.Name then CompFuncName := 1 else CompFuncName := -1; end; function CompFuncKolvo(a, b: TInfo): integer; begin if a.Kolvo = b.Kolvo then CompFuncKolvo := 0 else if a.Kolvo > b.Kolvo then CompFuncKolvo := 1 else CompFuncKolvo := -1; end; function CompFuncCena(a, b: TInfo): integer; begin if a.Cena = b.Cena then CompFuncCena := 0 else if a.Cena > b.Cena then CompFuncCena := 1 else CompFuncCena := -1; end; procedure ListSortUni(var List: PBiDirList; comp: CompareFunc); var tmp, rab: PBiDirList; tmps: TInfo; begin rab := List; while rab <> nil do begin tmp := rab^.Next; while tmp <> nil do begin if comp(tmp^.Info, rab^.Info) < 0 then begin tmps := tmp^.Info; tmp^.Info := rab^.Info; rab^.Info := tmps; end; tmp := tmp^.Next; end; rab := rab^.Next; end; end; var List: PBiDirList; begin List := nil; LoadListFromFile(List, 'PriceList.txt'); ListShow(List); writeln('A list sorted by price:'); ListSortUni(List, @CompFuncCena); ListShow(List); writeln('A list sorted by name:'); ListSortUni(List, @CompFuncName); ListShow(List); writeln('A list sorted by number:'); ListSortUni(List, @CompFuncKolvo); ListShow(List); ListClear(List); writeln('A list after cleaning:'); ListShow(List); end. Добавлю тестовый файл с базой товаров 'PriceList.txt' Скрытый текст Звуковая карта C-Media 8738, PCI 100 280 Звуковая карта PCI C-Media CMI8738-SX, PCI, 6.1channel 150 380 Звуковая карта ESI Juli@ XTe 43 6650 Звуковая карта Creative X-Fi Go! Pro, USB 12 1890 Звуковая карта PCI Creative Audigy SE SB0570 OEM 121 890 Звуковая карта Creative 5.1 VX (SB1071), OEM 19 770 Звуковая карта ESI M4U XL USB 2.0 300 4590 Разберись, что будет неясно - спрашивай. ----------------- P.S. Возможно, я погорячился. Ты, может быть, ещё не открыл для себя режим отладки и просмотра текущих значений переменных. Отсюда и непонимание происходящего. Поищи как пользоваться отладчиком в TurboPascal, пошаговое исполнение, просмотр текущих значений переменных. |
Сообщ.
#7
,
|
|
|
Спасибо,да нет всё по делу.
Просто курсовая такая на Турбо Паскале и такие задания,вот и мечусь в разные стороны. Я попробую разобраться в предложенных вариантах,вечером уже отпишусь насчет успехов. |
Сообщ.
#8
,
|
|
|
Скажите пожалуйста,а зачем 2 записи обязательно или можно обойтись одной записью?)
|
Сообщ.
#9
,
|
|
|
Я уже выпал из темы...
Что такое 2 записи? |
Сообщ.
#10
,
|
|
|
TInfo = record Name: string; Kolvo: integer; Cena: real; end; PBiDirList = ^TBiDirList; TBiDirList = record Info: TInfo; Next: PBiDirList; Prev: PBiDirList; end; Одна за информацию о товаре отвечает,а 2-ая список,а нельзя их в одну сделать? |
Сообщ.
#11
,
|
|
|
А-а-а...
Наверное, type TInfo = record Name: string; Kolvo: integer; Cena: real; end; PBiDirList = ^TBiDirList; TBiDirList = record Info: TInfo; Next: PBiDirList; Prev: PBiDirList; end; Скажу честно. Все задания на динамические структуры очень похожи. И для них можно ничего не меняя использовать старинные исходники. Но в разных случаях хранимые данные всё же различаются. Вот для этого я сделал "универсальный" тип TInfo, у которого изменяется описание, ввод и вывод. А всё остальное, связанное со списками остаётся нетронутым - например, строки обмена значениями в процедуре сортировки tmps := tmp^.Info; tmp^.Info := rab^.Info; rab^.Info := tmps; |
Сообщ.
#12
,
|
|
|
Как вы думаете почему он может ругаться на идентификатор поля?
function Find(p: SkladList; const tovr:TInfo): pTovar; begin while p <> nil do begin if tovr=p^.name then-------------Предполагается идентификатор поля begin Find := p; exit; end; p := p^.next; end; Message('Tovar ne naiden'); Find := nil; end; Я соединил переменные вашего примера и свою неработающую программу. program sklad; uses crt; const l_name = 30; type str_name = string[l_name]; TInfo = record Name: string; Kolvo: integer; Cena: real; end; SkladList = ^TovList; TovList = record Info: TInfo; Next: SkladList; Prev: SkladList; var key: char; item: word; prev: word; beg: SkladList; fin: SkladList; p: SkladList; name: str_name; tovr: TInfo; end; |
Сообщ.
#13
,
|
|
|
p указывает не на набор полей, а на структуру Info, которая уже и содержит поля, т.е. нужно "if tovr=p^.Info.Name then"
--------------- Вернее p указывает на набор полей, но значимым в плане поиска является поле Info, которое является типом record. |
Сообщ.
#14
,
|
|
|
Спасибо,я веду отладку уже добрался до конца.
Это уже главная программа и описания для работы с меню var Spis,tmpl:SkladList; znach:integer; ch:char; Я ввёл ваши примеры и функции(функции ListSort и ListSortUni) и уже при описании пункта меню компилятор стал ругаться.Даже когда стояло List тоже ругался на ссылку. '5':begin QueryName(name); p := Find(beg, name); if p <> nil then Inform(p^.Info); end; '6':begin ListSortUni(spis,@CompFuncName);-Ошибочная ссылка на переменную end; end; |
Сообщ.
#15
,
|
|
|
Дело в том, что у меня уже нет TurboPascal - я пользуюсь FreePascal. А такие вещи как взятие адреса переменной или процедуры зависят от диалекта.
В общем - убери амперсанд - символ "@". ListSortUni(spis, CompFuncName); |