![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
![]() Доброго дня. Помогите реализовать алгоритм. Я не буду описывать всю программу, напишу чуть иначе. Есть алгоритм, как реализовать в коде - не хватает ума.
Итак. Имеется массив чисел. Числа положительные и отрицательные. Массив мы представим в виде listbox1 на форме. Так же на форме будет listbox2 и listbox3 - для запихивания значений из массива. Итак поехали : Массив представляет собой последовательность чисел в listbox1. В итоге массив должен начинаться с положительного числа, и заканчиваться отрицательным. Числа должны чередоваться, НЕчетные - положительны, четные элементы отрицательны. Это то что должно получиться в итоге. Сразу мы имеем массив чисел, которые идут по нарастающей : +35 -42 +96 -112 +186 -740 Вот в этом примере массив шикарен и все правильно. Но бывает такое : 1. Два числа подряд идут отрицательных 2. Два числа идут положительных 3. Массив начинается НЕ с положительного 4. Массив заканчивается НЕ отрицательным - это вещи с которыми будем бороться Пример : -15 +35 -42 +78 -116 -182 +350 -360 +620 +630 -700 +730 В этом массиве имеется все 4 описанных косяка. Что программа должна с ними делать. 1. В первую очередь, обязательно проверить начинается ли и заканчивается ли массив сотв-но положительным и отрицательными. Если нет - в начало listbox сунуть положительное (0) в конец отрицательное (-800). 2. Далее если программа в списке находит два подряд идущих отрицательных (-116,-182) то : 2.1 Если ВТОРОЕ отрицательное отличается от первого отричательно меньше чем на 2 - удалить ил listbox первое отрицательное. Если второе(otr2) отрицательное отличается от первого(otr1) БОЛЬШЕ чем на два - между этими числами нужно вставить положительное - которое будет равно отрицательному(переведенному в положительное) плюс 2. Получится -116, + 118, -182 3. Если в списке два плюса(+620,+630) - почти то же самое : Если второе положительное отличается от первого положительного менее чем на 2 - второе положительное нужно удалить. Если второе положительное больше первого более чем на 2 - между ними нужно воткнуть отрицательное число, которое будет равно второму положительному минус два, перевернутое в отрицательное. т.е. мы получим 620,-628,630. Итак в listbox1 был кривоватый массив который программа исправила. Было бы идеально, если бы пары чиле которые НЕ исправлялись - ушли в listbox2 а те что исправлены - в listbox3. На нашем примеремы получим исправленный массив : 0 -15 +35 -42 +78 -116 +118 -182 +350 -360 +620 -628 +630 -700 +730 -800 т.е. все числа пойду в листбокс2, кроме : отмечных красным. Если логика непонятна - поясню боллее развернуто. Спасибо заранее)) Последний раз редактировалось alexusankov, 27.09.2012 в 10:19. |
#2
|
||||
|
||||
![]() Цитата:
|
#3
|
||||
|
||||
![]() Как это в коде реализовывается.
Как искать в массиве сочетания ++, или --. Если я воткнуть изменения в массив, между ++ один - например. |
#4
|
||||
|
||||
![]() Цитата:
Цитата:
Код:
ListBox1.Items.Insert(7, '-'); |
#5
|
||||
|
||||
![]() Хоть убиться, не могу представить как это в коде реализовать
|
#6
|
||||
|
||||
![]() Цитата:
|
#7
|
||||
|
||||
![]() Да вообще принципиально всю.
Пока написано : Код:
for x:=1 to (listbox1.Items.Count div 2) + (listbox1.Items.Count mod 2) do begin i1:=strtoint(listbox1.Items[i]); // 0 1 2 3 5 5 i2:=strtoint(listbox1.items[i+1]); // 1 2 3 4 5 7 edit1.Text := inttostr((listbox1.Items.Count div 2) + (listbox1.Items.Count mod 2)); if (i1 > 0) and (i2 < 0) then begin listbox2.Items.Add(inttostr(i1)); listbox2.Items.add(inttostr(i2)); i:=i+2; end; end; Думаю.. з.ы. хрень какая то. чувствую не по 2 строки брать нужно.... **** Да, нужно брать по 1 переменной I:=i+1; иначе по 2 плюса или минуса не найти. попробуем.. Последний раз редактировалось alexusankov, 27.09.2012 в 13:14. |
#8
|
||||
|
||||
![]() Цитата:
|
#9
|
||||
|
||||
![]() Цитата:
Код:
if Copy(listbox1.Items[0],1,1) = '-' then listbox1.Items.Insert(0,'+1'); if Copy(listbox1.Items[listbox1.Items.count - 1],1,1) = '+' then listbox1.Items.Add('-1440'); З.ы. Кажись нужно сувать значение в переменную так, чтобы в а1 оказалось предыдущее значение а2. Мне кажется это правильный путь. И флаг добавить. Точно, буду думать. Час. Последний раз редактировалось alexusankov, 27.09.2012 в 13:26. |
#10
|
||||
|
||||
![]() Цитата:
Вот, проверяй, вроде работает: Код:
procedure TForm1.Button1Click(Sender: TObject); var i, i1, i2: Integer; begin ListBox1.Items.Text := '-15'#13'+35'#13'-42'#13'+78'#13'-116'#13'-182'#13'+350'#13'-360'#13'+620'#13'+630'#13'-700'#13'+730'; if StrToInt(ListBox1.Items[0]) < 0 then ListBox1.Items.Insert(0, '0'); if StrToInt(ListBox1.Items[ListBox1.Items.Count - 1]) >= 0 then ListBox1.Items.Add('-800'); i := 0; while i < ListBox1.Items.Count - 1 do begin i1 := StrToInt(ListBox1.Items[i]); i2 := StrToInt(ListBox1.Items[i + 1]); if (i1 < 0) and (i2 < 0) then begin if Abs(i1 - i2) < 2 then begin ListBox1.Items.Delete(i); end else begin ListBox1.Items.Insert(i + 1, '+' + IntToStr(2 - i1)); Inc(i); end; end else if (i1 >= 0) and (i2 >= 0) then begin if Abs(i1 - i2) < 2 then begin ListBox1.Items.Delete(i); end else begin ListBox1.Items.Insert(i + 1, IntToStr(2 - i2)); Inc(i); end; end else begin Inc(i); end; end; end; Цитата:
![]() |
#11
|
||||
|
||||
![]() Внезапно.....
Какой маленький кусок, а почти все делает. буду до вечера пытаться понять, почему у меня другой код, и почему этот работает. А что значит if Abs и Inc(i); ? Если в списке будет три минуса, в принципе, все пройдет гладко я так понимаю? Я так понимаю, что я сам себе вынес мозг на столько, что голова не понимает. Завтра попытаюсь понять, зачем я все в своем коде так сложно навернул Последний раз редактировалось alexusankov, 27.09.2012 в 16:21. |
#12
|
||||
|
||||
![]() Цитата:
Цитата:
![]() |
#13
|
|||
|
|||
![]() Ну, в принципе, можно и так изгаляться.
Но есть вариант попроще. 1. Создаем 2 служебных списка. 2. В один список кладем все положительные числа. 3. Во второй - все отрицательные. 4. Сортируем списки, если надо. 5. Делаем проверку, что нужную последовательность вообще можно составить (число элементов в обоих списках должно быть одинаковым) 6. Составляем новый список, поочередно беря элементы из служебных. Код:
var I : Integer; P, N : Array Of Integer; D : Integer; begin // Prepare SetLength(P,0); SetLength(N,0); // Split source list For I := 0 To ListBox1.Items.Count-1 Do Begin D := StrToInt(ListBox1.Items[i]); If D > 0 Then Begin SetLength(P,Length(P)+1); P[High(P)] := D; End Else Begin SetLength(N,Length(N)+1); N[High(N)] := D; End; End; // Check lengths If Length(P) <> Length(N) Then Raise Exception.Create('ERROR!!!'); // Sort - if needed ... // Build new list ListBox1.Items.Clear; For I := Low(P) To High(P) Do Begin ListBox1.Items.Add(IntToStr(P[i])); ListBox1.Items.Add(IntToStr(N[i])); End; end; |
#14
|
||||
|
||||
![]() Цитата:
|
#15
|
|||
|
|||
![]() Ну дык о том и речь. Если кол-во положительных и отрицательных чисел не равно, то требуемвй список построить нельзя. Да, напрямую это в задании не сказано. Но как ты построишь список, начинающийся с положительного числа, заканчивающийся отрицательным и в котором пол. и отр. числа чередуются, если у тебя 5 пол. и 3 отр. числа? Это просто невозможно.
ЗЫ. Может я не очень внимательно читал задание, но мне показалось что условие именно такого, как я описал. |