• XSS.stack #1 – первый литературный журнал от юзеров форума

Алгоритмы

А почему бы не решить 4 задачу графическим методом? Я так на олимпиадах делал. Вообщем рисуешь закрашенный треугольник одним цветом, а точку ставишь другим цветом. У поставленной точки проверяем соседние точки если у точек цвет треугольника, с любых трёх сторон, то точка в треугольнике. Могу выложить прогу на васике.
 
AKella
Это не легче получится... это шулерство получится... лишнии затраты... так ты закрашиваешь еще, вызываешь другие библиотеки и тому подобное... а так ты все по геометрии :) но всем лень достать учебник по геометрии :)
 
Lamer
Шулерство, зато легче. :D Давайте лучше что-то толковое по поводу задачи со скобками. Я ее еще серьезно не решал. Вот сяда завтра и думаю, решу.
 
Определим правильное скобочное вырожение следующим образом:
- пустое выражение правильное.
- если Е - правильное скобочное выражение, то (Е), [Е] {Е} <Е> - тоже правильные, причем () {} [] <> - -все возможные типы скобок,
- если E и F - правильные скобочные выражения, то EF - тоже правильное.
- других правильных скобочных вырожений нет.
Пример правильного: (), [<>]
Пример неправильного: (, ([)]
Необходимо определить, является ли правильным выражение, которое находится в data.txt

например вырезать из середины правильные участки пока строка не станет пустой. Если не станет - то неправильное.
 
Короче задача про треугольник.
Вот код, но он работает только для первой и второй четверти, т.е. когда y положительные. Дальше пока не дописал :D
Код:
#include <iostream.h>

void main (void)
{int x1=3, y1=6;
 int x2=8, y2=11;
 int x3=2, y3=7;
 int x0=2, y0=8;

 int i1,i2,i3,j1,j2,j3;
if (y1>y2 && y1>y3) 
 {i1=y1; j1=x1; i2=y2; j2=x2; i3=y3; j3=x3; }
if (y2>y1 && y2>y3) {i1=y2,j1=x2;i2=y1;j2=x1;i3=y3;j3=x3;}
if (y3>y1 && y3>y2) {i1=y3;j1=x3;i2=y1;j2=x1;}
if
(y0<=(i2 - i1)*(x0 - j1)/ (j2 - j1)+i1 &&
 y0<=(i3 - i1)*(x0 - j1)/ (j3 - j1)+i1 &&
 y0>=(i3 - i2)*(x0 - j2)/ (j3 - j2)+i2)
 cout << "Dannaya tochka prenadlezit treugolniku \n";
   else
     cout << "Tochka ne prenadlezit. \n";
}
 
Вот, вчера сидел часа полтора, над адресами мучался :) надо было поменять местами два елемента двунаправленного списка...
Код:
    	pTemp = pj -> LinkNext;

    	pj -> LinkNext = pi -> LinkNext;
    	pj -> LinkNext ? pj -> LinkNext -> LinkPrev = pj : NULL;

    	if(pi -> LinkNext != pTemp)
    	{
      pi -> LinkNext = pTemp;
      pTemp -> LinkPrev = pi;
    	}
    	pj -> LinkPrev ? pj -> LinkPrev -> LinkNext = pi : NULL;

    	pTemp = pj -> LinkPrev ? pj -> LinkPrev : NULL;

    	if(pi -> LinkPrev != pj)
      pj -> LinkPrev = pi -> LinkPrev;
    	else
      pj -> LinkPrev = pi;

    	pj -> LinkPrev -> LinkNext = pj;
    	pi -> LinkPrev = pTemp;
    	pTemp ? pTemp -> LinkNext = pi : NULL;
pTemp -- вспомагательный адрес
pj, pi -- адреса двух елементов, стоящих рядом в списке или на некотором расстоянии.
LinkNext, LinkPrev -- ссылка на следующий елемент и на предыдущий елемент, соответственно.

Кто чем может дополнить или нашел ошибку :) делимся :)... так же могу выкинуть сортировку методом Шелла для записей... тоже по инету лазил день, нашел 6 реализаций и не одна из них не была правельной... либо реализация через какуе-то стороннию библиотеку. И все реализации были для статических массивов... насколько моя правельная я не знаю :). Но сортирует так это точно.

Кстати, Метод Шелла очень моднявая сортировка... она сортирует за четверть секунды то, что тот же пузырек за 40 секунд... вот такая вот быстрая :) гы :) во всяком случаи так говорят в инете :)
 
magvaj
я посмотрю как ты будешь менять значения, если у тебя в объекте будет 100 полей..., да даже не 100 ну а хотя бы 20 полей, а если еще у тебя в объекте будет наследование, то ты вообще заипнешься ;-). И потом, надо иметь универсальное решение, а не на один случай... А мной было предложено универсальное решение...

Да... народ... помогите... уже несколько часов торможу... никак не могу придумать.
Вобщем надо написать рекурентную фукцию, которая будет создавать Бинарное дерево. Правило бинарного дерева... Ну допустим по левую сторону элементы что меньше int'ового поля в данном узле, а по правую стороны элементы что больше int'ового поля в данном узле ну и так дальше...
Вобщем обычное бинарное дерево. Я нашел в инете, но никак не могу переписать код под синтаксис С89...
Помогите плизззззз !!!
 
Кстати, Метод Шелла очень моднявая сортировка... она сортирует за четверть секунды то, что тот же пузырек за 40 секунд... вот такая вот быстрая :) гы :) во всяком случаи так говорят в инете :)
Гораздо быстрее "Быстрая" сортировка. Можешь проверить в Си(про стандарт Анси не помню) есть функция qsort.
 
Dude03
Я думаю, что народ который писал данные сортировки гораздо умнее обычного пользователя, да еще и код там более вылезанные. Если кому не лень, можете написать эту програмку и в debug посмотреть что и как делается :о).

Ладно, но мы сортировки не обсуждаем, потому как каждая сортировка обычно пишется под конкретный случай... в каком-то случаи одна лучше, а в другом другая.

P.S. желательно не флеймить тут, а предлагать конкретное решение.
 
Мдя... по ходу тут нет ни одного программиста ??? или всем очень и очень лень писать какой-то код ??? Хотя да, типа праздники и тому подобное...
Ладно, ну хотя бы помогите исправить или доработать функцию создания бинарного дерева.
Код:
unit *make_tree(unit *pUnit, /* остальные передаваемые значения для поля */)
{
	unit *pTemp = NULL;
	if(pUnit == NULL)
	{
  unit *p = new unit();
                /* Заполнение всех полей или еще какие действия */
  pUnit = p;
  return p;
	}
	else
	{
  if(/* Правило создание бинарного дерева */)
  {
         pTemp = make_tree(pUnit -> LinkLeft, /* остальные передаваемые значения для поля */);
         pUnit -> LinkLeft = pTemp;

  }
  else
  {
  	pTemp = make_tree(pUnit -> LinkRight, /* остальные передаваемые значения для поля */);
  	pUnit -> LinkRight = pTemp;
  }
	}
	return pUnit;
}
 
Собственно говоря задача была такая... пользователь вводит строку с выражением типа ((10+5)*10/5*(10+4))+10 и все это надо представить в виде бинарного дерева (не матюкайтесь сразу, потому что сам понимаю, что задание тупое и бинарное дерево не для этого... но таково было задание) и после чего надо обойдя все это дерево посчитать это варажение :) ... Собственно говоря вот... ловите :)
да, код написан на Pascal'e
Код:
Program MathExpr;
Uses CRT;
Type tr=^rec;             {Тип дерево}
     rec=record
               pole:string;   {Информационное поле }
               sym:boolean;  {Флаг символа        }
               zn:real;     {Значение переменной }
               rend:boolean;  {Вспомогательный флаг}
               l,r:tr;       {Указатели на потомка}
     end;
Var root,el : tr;         {вершина и узлы дерева}
    st : string;     {вспомогательная переменная}
    i,j : byte;       { -------"-------}
    x,y : integer;    { координаты для вывода дерева}
    g : byte;       {вспомогательная переменная}
    yn : char;       { -------"-------}
    code : integer;    { для procedure VAL }
Procedure Tree(p:tr);
  Procedure undertree(c:char);       { создает поддеревья}
    Procedure Skob;     {процедура для учитывания скобок}
    begin
         i:=i+1;
         repeat
               If p^.pole[i]='(' then Skob;
               i:=i+1;
         until p^.pole[i]=')';
    end; {End of Skob}
  begin
       for i:=1 to Length(p^.pole) do
           begin
                if p^.pole[i]='(' then
                begin
                     g:=i;
                     Skob;
                     if (p^.pole[i+1]<>'+')   and (p^.pole[i+1]<>'-')
                       and (p^.pole[i+1]<>'*') and (p^.pole[i+1]<>'/')
                       and (p^.pole[g-1]<>'*') and (p^.pole[g-1]<>'/')
                       and (p^.pole[g-1]<>'-') and (p^.pole[g-1]<>'+')
                       and (p^.pole[i+1]<>'^') and (p^.pole[g-1]<>'^')
                     then
                     begin
                          delete(p^.pole,i,1);
                          delete(p^.pole,1,1);
                          i:=0;
                     end;
                end;
           if p^.pole[i]=c then
              begin
                   New(p^.l);
                   p^.l^.l:=nil;
                   p^.l^.r:=nil;
                   p^.l^.pole:=copy(p^.pole,1,i-1);
                   p^.l^.zn:=0;
                   p^.l^.sym:=false;
                   New(p^.r);
                   p^.r^.l:=nil;
                   p^.r^.r:=nil;
                   p^.r^.pole:=copy(p^.pole,i+1,ord(p^.pole[0]));
                   p^.r^.zn:=0;
                   p^.r^.sym:=false;
                   i:=ord(p^.pole[0]);
                   p^.pole:=c;
              end;
       end; {for end}
  end; {end of UnderTree}
begin
     if p<>nil then
            {Строятся поддеревья в зависимости от приоритета}
            {арифметической операции                        }
     begin
          UnderTree('+');
          UnderTree('-');
          UnderTree('*');
          Undertree('/');
          Undertree('^');
          Tree(p^.l);
          Tree(p^.r);
     end;
end; {End of Tree}

      { Вычисление значения арифметического выражения}
Procedure Calc(p:tr);
begin
     if p<> nil then begin
        if p^.l^.sym and p^.r^.sym then begin
           case p^.pole[1] of
                '+' : begin
                           p^.zn:=p^.l^.zn+p^.r^.zn;
                           p^.sym:=true;
                end;
                '-' : begin
                           p^.zn:=p^.l^.zn-p^.r^.zn;
                           p^.sym:=true;
                end;
                '*' : begin
                           p^.zn:=p^.l^.zn*p^.r^.zn;
                           p^.sym:=true;
                end;
                '/' : begin
                           p^.zn:=p^.l^.zn/p^.r^.zn;
                           p^.sym:=true;
                end;
                '^' : begin
                           p^.zn:=EXP(p^.r^.zn*LN(p^.l^.zn));
                           p^.sym:=true;
                end;
           end; {end of case}
        end;
        Calc(p^.l);
        Calc(p^.r);
     end;
end; {end of calc}
  { Процедура определяет где в дереве переменная или значение,  }
  { и где знак операции. }
Procedure Symb(p:tr);
begin
     if p<> nil then
        begin
             if p^.pole[1] in ['a'..'z'] then
                begin
                     p^.sym:=true;
                     Write(p^.pole,'= ');
                     Readln(p^.zn);
                end;
             if p^.pole[1] in ['0'..'9'] then
                begin
                     p^.sym:=true;
                     VAL(p^.pole,p^.zn,code);
                end;
             Symb(p^.l);
             Symb(p^.r);
        end;
end; {End of Symb}
      { Процедура выводит на экран полученное дерево     }
Procedure OutTree(pr:tr;f:byte);
begin
     y:=y+2;
     if pr<>nil then
        begin
             if f=1 then x:=x-5;
             if f=2 then x:=x+9;
             GotoXY(X,Y);
             {Если f=0, то выводится корневая вершина}
             if f=0 then Writeln('[',pr^.pole,']');
             {Если f=1, то - левое поддерево}
             if f=1 then Writeln('[',pr^.pole,']/');
             {Если f=2, то - правое поддерево}
             if f=2 then Writeln('\[',pr^.pole,']');
             OutTree(pr^.l,1);   OutTree(pr^.r,2);
        end;
     y:=y-2;
end; {End of OutTree}

BEGIN           {Главная программа}
     repeat
          Window(1, 1, 80, 25);
          x := 22;
          y := 0;
          TextBackGround(0);
          TextColor(15);
          ClrScr;
          {Ввод выражения, которое надо посчитать}
          Writeln('Введите ваше выражение -->');
          GotoXY(40, 4);
          Write('Используйте следующие операции:');
          GotoXY(50, 5);
          Write(' + , - , * , / , ^ ');
          GotoXY(40, 7);
          Write('Программа применяет деревья для');
          GotoXY(40, 8);
          Write('вычисления арифметического  вы-');
          GotoXY(40, 9);
          Write('ражения.');
          GotoXY(1, 2);
          Readln(st);
          {root    Создается корневая вершина}
          New(el);
          el^.l := nil;
          el^.r := nil;
          el^.pole := st;
          el^.zn := 0;
          el^.sym := false;
          el^.rend := false;
          root := el;
          {end of root}
          Tree(root);        {Создается дерево}
          {Ввод значений переменных}
          Writeln('Введите значения:');
          Symb(root);
          Window(30, 1, 80, 25);
          TextBackGround(Blue);
          TextColor(White);
          ClrScr;
          WriteLn('Дерево выглядит так:');      {Вывод дерева на экран}
          OutTree(root, 0);
          repeat
                if root^.l^.sym and root^.r^.sym then
                   begin
                        Calc(root);
                        root^.rend:=true;
                   end
                else calc(root);
          until root^.rend;
          Window(1, 23, 29, 25);
          TextBackGround(15);
          TextColor(0);
          ClrScr;
          Writeln('Результат --> ',root^.zn:2:3);     {Вывод результата }
          Write('Еще?(y/n)');
          readln(yn);
     until yn<>'y';
end.
 
Прикольно=) но сам убедился, что обратную польскую нотацию лучше считать только через стек.
 
Dude03
Не факт, рекурсией тоже давольно просто считается...
 
Не факт, рекурсией тоже давольно просто считается...
Все равно для определения приоритета операций придеться стек(или как-нить по другому) использовать.
Поэтому легче сразу через стек
 
Б-деревья, если кому надо...
#include <iostream.h>
#include <stdlib.h>
#define TAMANO 100
struct stkey {
int valor;
long registr;
};
class bnode {
public:
bnode(int nKeys); // Constructor
~bnode(); // Destructor
private:
int keysUses;
stkey *key;
bnode **pointer;
bnode *parent;
friend class btree;
};
typedef bnode *pbnode;
bnode::bnode(int nKeys)
{
keysUses = 0;
key = new stkey[nKeys];
pointer = new pbnode[nKeys+1];
parent = NULL;
}
bnode::~bnode()
{
delete[] key;
delete[] pointer;
}
class btree {
public:
btree(int nClv);
~btree();
long Search(int key);
bool Insert(stkey key);
void Remove(int key);
void View();
private:
stkey *list;
pbnode *listpunt;
void Insert(stkey key, pbnode node, pbnode hijo1, pbnode hijo2);
void RemoveKey(pbnode node, int valor);
void RemoveNode(pbnode node);
void MoveKeyRight(pbnode right, pbnode parent, pbnode node, int posKeyParent);
void MoveKeyLeft(pbnode left, pbnode parent, pbnode node, int posKeyParent);
void FundirNode(pbnode left, pbnode &parent, pbnode right, int posKeyParent);
void Ver(pbnode node);
int nKeys, nodesMinimal;
pbnode Enter;
};
btree::btree(int nClv) : nKeys(nClv)
{
list = new stkey[nKeys+1];
listpunt = new pbnode[nKeys+2];
nodesMinimal = nKeys/2; // ((nKeys+1)/2)-1;
Enter = NULL;
}
btree::~btree()
{
delete[] list;
delete[] listpunt;
RemoveNode(Enter);
}
void btree::RemoveNode(pbnode node)
{
int i;
if(!node) return;
for(i = 0; i <= node->keysUses; i++) RemoveNode(node->pointer);
delete node;
}
void btree::View()
{
cout << "Tree" << endl;
Ver(Enter);
cout << "-----" << endl;
system("pause");
}

void btree::Ver(pbnode node)
{
int i;
if(!node) return;
for(i = 0; i < node->keysUses-1; i++) cout << node->key.valor << "-";
if(node->keysUses) cout << node->key.valor << " [";
if(node->parent) cout << (node->parent)->key[0].valor; else cout << "*";
cout << "]" << endl;
for(i = 0; i <= node->keysUses; i++) Ver(node->pointer);
}
long btree::Search(int key)
{
pbnode node = Enter;
int i;
while(node) {
i = 0;
while(i < node->keysUses && (node->key.valor < key)) i++;
if(node->key.valor == key) return node->key.registr;
else node = node->pointer;
}
return -1L;
}
bool btree::Insert(stkey key)
{
pbnode node, parent;
int i;
parent = node = Enter;
while(node) {
parent = node;
i = 0;
while(i < node->keysUses && (node->key.valor < key.valor)) i++;
if(node->key.valor == key.valor && i < node->keysUses) return false;
else node = node->pointer;
}
node = parent;
Insert(key, node, NULL, NULL);
return true;
}
void btree::Insert(stkey key, pbnode node, pbnode hijo1, pbnode hijo2)
{
pbnode parent, nnew;
int i, j;
bool salir = false;
do {
if(!node)
{
node = new bnode(nKeys);
node->keysUses = 0;
node->parent = NULL;
Enter = node;
}
parent = node->parent;
if(node->keysUses == nKeys) // overflow
{
nnew = new bnode(nKeys);
i = 0;
while(node->key.valor < key.valor && i < nKeys) {
list = node->key;
listpunt = node->pointer;
i++;
}
list = key;
listpunt = hijo1;
listpunt[i+1] = hijo2;
while(i < nKeys) {
list[i+1] = node->key;
listpunt[i+2] = node->pointer[i+1];
i++;
}
node->keysUses = nKeys/2;
for(j = 0; j < node->keysUses; j++) {
node->key[j] = list[j];
node->pointer[j] = listpunt[j];
}
node->pointer[node->keysUses] = listpunt[node->keysUses];

nnew->keysUses = nKeys - node->keysUses;
for(j = 0; j < nnew->keysUses; j++) {
nnew->key[j] = list[j+(nKeys/2)+1];
nnew->pointer[j] = listpunt[j+(nKeys/2)+1];
}
nnew->pointer[nnew->keysUses] = listpunt[nKeys+1];

for(j = 0; j <= node->keysUses; j++)
if(node->pointer[j]) (node->pointer[j])->parent = node;
for(j = 0; j <= nnew->keysUses; j++)
if(nnew->pointer[j]) (nnew->pointer[j])->parent = nnew;

key = list[nKeys/2];
hijo1 = node;
hijo2 = nnew;
node = parent;
}
else
{
i = 0;
if(node->keysUses > 0) {
while(node->key.valor < key.valor && i < node->keysUses) i++;
for(j = node->keysUses; j > i; j--)
node->key[j] = node->key[j-1];
for(j = node->keysUses+1; j > i; j--)
node->pointer[j] = node->pointer[j-1];
}
node->keysUses++;
node->key = key;
node->pointer = hijo1;
node->pointer[i+1] = hijo2;
if(hijo1) hijo1->parent = node;
if(hijo2) hijo2->parent = node;
salir = true;
}
} while(!salir);
}
void btree::Remove(int valor)
{
pbnode node;
bool inverse = false;
int i;

node = Enter;
while(node && !inverse) {
i = 0;
while(i < node->keysUses && (node->key.valor < valor)) i++;
if(node->key.valor == valor && i < node->keysUses) inverse = true;
else node = node->pointer;
}
if(inverse) RemoveKey(node, valor);
}
void btree::RemoveKey(pbnode node, int valor)
{
pbnode actual, right, left, parent;
int posKeyParent, pos, i;

pos = 0;
while(node->key[pos].valor < valor) pos++;

if(node->pointer[0]) {
actual = node->pointer[pos+1];
while(actual->pointer[0]) actual = actual->pointer[0];
node->key[pos] = actual->key[0];
pos = 0;
} else actual = node;

for(i = pos; i < actual->keysUses; i++)
actual->key = actual->key[i+1];
actual->keysUses--;

if(actual == Enter && actual->keysUses == 0) {
delete actual;
Enter = NULL;
return;
}
if(actual == Enter || actual->keysUses >= nodesMinimal) return;
do {
parent = actual->parent;
for(posKeyParent = 0;
parent->pointer[posKeyParent] != actual;
posKeyParent++);
if(posKeyParent > 0)
left = parent->pointer[posKeyParent-1];
else left = NULL;
if(posKeyParent < parent->keysUses)
right = parent->pointer[posKeyParent+1];
else right = NULL;
if(right && right->keysUses > nodesMinimal)
MoveKeyRight(right, parent, actual, posKeyParent);
else if(left && left->keysUses > nodesMinimal)
MoveKeyLeft(left, parent, actual, posKeyParent-1);
else if(right)
FundirNode(actual, parent, right, posKeyParent);
else
FundirNode(left, parent, actual, posKeyParent-1);
actual = parent;
} while(actual && actual != Enter && actual->keysUses < nodesMinimal);
}
void btree::MoveKeyRight(pbnode right, pbnode parent, pbnode node, int posKeyParent)
{
int i;
node->key[node->keysUses] = parent->key[posKeyParent];
node->keysUses++;
parent->key[posKeyParent] = right->key[0];
node->pointer[node->keysUses] = right->pointer[0];
if(right->pointer[0]) right->pointer[0]->parent = node;
for(i = 0; i < right->keysUses; i++) right->key = right->key[i+1];
for(i = 0; i <= right->keysUses; i++) right->pointer = right->pointer[i+1];
right->keysUses--;
}
void btree::MoveKeyLeft(pbnode left, pbnode parent, pbnode node, int posKeyParent)
{
int i;
for(i = node->keysUses; i > 0; i--) node->key = node->key[i-1];
for(i = node->keysUses+1; i > 0; i--) node->pointer = node->pointer[i-1];
node->keysUses++;
node->key[0] = parent->key[posKeyParent];
parent->key[posKeyParent] = left->key[left->keysUses-1];
node->pointer[0] = left->pointer[left->keysUses];
if(node->pointer[0]) node->pointer[0]->parent = node;
left->keysUses--;
}
void btree::FundirNode(pbnode left, pbnode &parent, pbnode right, int posKeyParent)
{
int i;
left->key[left->keysUses] = parent->key[posKeyParent];
parent->keysUses--;
for(i = posKeyParent; i < parent->keysUses; i++) {
parent->key = parent->key[i+1];
parent->pointer[i+1] = parent->pointer[i+2];
}
left->keysUses++;
for(i = 0; i < right->keysUses; i++)
left->key[left->keysUses+i] = right->key;
for(i = 0; i <= right->keysUses; i++) {
left->pointer[left->keysUses+i] = right->pointer;
if(right->pointer) right->pointer->parent = left;
}
left->keysUses += right->keysUses;
if(parent == Enter && parent->keysUses == 0) {
Enter = left;
Enter->parent = NULL;
delete parent;
parent = NULL;
}
delete right;
}
int main()
{
int matr[TAMANO];
btree tree(5);
stkey key;
int i;
srand(time(NULL));
for(i = 0; i < TAMANO; i++) {
do {
matr = rand()%10000;
key.valor = matr;
key.registr = i;
} while(!tree.Insert(key));
}
cout << "-----: " << "\n";
tree.View();

cout << "Search element 23:" << matr[23] << " position: " <<
tree.Search(matr[23]) << "\n";
system("PAUSE");

for(i = 0; i < TAMANO; i++) {
cout << "Delete: [" << i << "]: " << matr << "\n";
tree.Remove(matr);
}
tree.View();
return 0;
}
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх