Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2005.11.13;
Скачать: [xml.tar.bz2];

Вниз

Сравнение двоичных чисел   Найти похожие ветки 

 
Delphman   (2005-10-13 22:04) [0]

Допустим есть число (двоичное) заданное строкой типа string s="10001111"
Как автоматизировать следующий процесс:
Эта строка делится пополам и сравнивается:
1000<=1111
затем делится так (от цендра или концов не важно):
   00<=11
10    <=   11
затем так:
1      <=      1
 0    <=    1
   0  <=  1
     0<=1

Длина строки равна 2^n, n=2,3,4...26

Можно ли такое сделать? Чё то в голову ничего не приходит.


 
ArtemESC ©   (2005-10-13 22:47) [1]

1)Перевод числа из двоичного в десятичное (если нужно)

function BinToDecimal(str: string): DWORD;
var
len: integer;
i  : integer;
begin
len     := length(str);
Result  := 0;
for i := 1 to len do
  If (str[i] = "1") then Result := Result + Round(IntPower(2, len - i));
end;


2)+ Несложные Манипуляции с shl  и shr


 
Игорь Шевченко ©   (2005-10-14 00:06) [2]

ArtemESC ©   (13.10.05 22:47) [1]

Откуда пример, если не секрет ?


 
ArtemESC ©   (2005-10-14 00:19) [3]

>>Игорь Шевченко
А что не так?


 
Fay ©   (2005-10-14 01:12) [4]

2 ArtemESC ©   (14.10.05 0:19) [3]
Сравни.

uses
 Math;

{$DEFINE ArtemESC}

{$IFDEF ArtemESC}

function BinToDecimal(str : string) : DWORD;
var
 len : integer;
 i : integer;
begin
 len := length(str);
 Result := 0;
 for i := 1 to len do
   if (str[i] = "1") then Result := Result + Round(IntPower(2, len - i));
end;

{$ELSE}

function BinToDecimal(const s : String) : DWORD;
var
 i, n : Integer;
begin
 Result := 0;
 n := Length(s);
 for i := 1 to n do
   if (s[i] = "1") then
     Result := Result or DWORD($01 shl (n - i));
end;
{$ENDIF}

{$R *.dfm}

procedure TForm1.Button1Click(Sender : TObject);
const
 TEST_STR = "010101010101010101010101010101";
var
 pf, pc1, pc2 : Int64;
 i : Integer;
 s : String;
begin
 s := TEST_STR;
 QueryPerformanceFrequency(pf);
 QueryPerformanceCounter(pc1);
 for i := 0 to 999999 do
   BinToDecimal(s);
 QueryPerformanceCounter(pc2);
 ShowMessage(Format("%d ms", [((pc2 - pc1) * 1000) div pf]))
end;


P.S.
Нафиг ваще потребовался сопр?


 
Fay ©   (2005-10-14 10:57) [5]

Delphman   (13.10.05 22:04)
затем делится так (от цендра или концов не важно):
  00<=11
10    <=   11
затем так:
1      <=      1
0    <=    1
  0  <=  1
    0<=1


Чё это значит?


 
Игорь Шевченко ©   (2005-10-14 11:07) [6]

Fay ©   (14.10.05 01:12) [4]

function BinToDecimal(const s : String) : DWORD;
var
I: Integer;
begin
Result := 0;
for i := 1 to Length(s) do
  if S[I] in ["0","1"] then
    Result := (Result shl 1) + (Ord(S[I]) - Ord("0"));
  else
    raise EConvertError.CreateFmt ("Illegal character %c", [S[I]]);
end;


?


 
Fay ©   (2005-10-14 11:17) [7]

2 Игорь Шевченко ©   (14.10.05 11:07) [6]
Вы пессимист 8)


 
Fay ©   (2005-10-14 11:29) [8]

2 Игорь Шевченко ©   (14.10.05 11:07) [6]
... И это самый быстрый способ из уже предложенный...
8)


 
Anatoly Podgoretsky ©   (2005-10-14 16:12) [9]

Не требуется самый быстрый, требуется решение именно по институтскому заданию.


 
Fay ©   (2005-10-14 16:43) [10]

2 Anatoly Podgoretsky ©   (14.10.05 16:12) [9]
Анатолий, Вы понимаете суть задания?


 
Anatoly Podgoretsky ©   (2005-10-14 16:46) [11]

Меня суть не интересовала, не готов решать задания в форумах. Да и суть не важно, надо не думать, а трясти.


 
Delphman   (2005-10-14 17:08) [12]

Переводить числа в десятичные я и сам умею, мне их нужно сравнивать именно так. Строка делится пополам, сравнивается; эти строки делются тоже пополам, сравниваются, и так далее.
Если условие верно то
Result:="+" else begin Result:="-"; exit; end;


 
Delphman   (2005-10-14 21:59) [13]

В теории это выглятит так:
http://dvo.sut.ru/libr/himath/w163rabk/7.htm
см. класс монотонных функций, может легче можно сделать, чем я тут писал.


 
Fay ©   (2005-10-14 22:04) [14]

2 Delphman   (14.10.05 17:08) [12]

>> Строка делится пополам, сравнивается; эти строки
>> делются тоже пополам, сравниваются и так далее.
Что "и так далее" ?

>> Если условие верно
Какое условие?


 
palva ©   (2005-10-14 23:57) [15]

Да, чему теперь в институтах учат! Ничего не понятно.
Самое образованное поколение!


 
Delphman   (2005-10-15 12:56) [16]

>> Да, чему теперь в институтах учат! Ничего не понятно.
Да, еслиб это было в институте, а то в технаре, а в институте вообще ничему не учат покрайне мере в моём.

>>Какое условие?
во пример есть при длине строки 2^2:
0110
01<=10 result="+"
0  <=  0 result="+"
 1<=1 result="+"

1110
11<=10 result="-" exit

1010
10<=10 result="+"
1<=0 result="-" exit


 
Delphman   (2005-10-15 13:06) [17]

<= вот это условие если выполняется, то дальше делим и сравниваем, если нет result="-" и выходим


 
Delphman   (2005-10-15 17:55) [18]

Во кое чё получилось, но бажет непойму где (хотя я вижу где, но не знаю как
исправить).

procedure TForm1.Button1Click(Sender: TObject);
const
s="1001110010011100";
var
i,j: integer;
x: real;
op1,op2: string;
begin
i:=0;x:=1;
memo1.Lines.add(s);
repeat
x:=exp(ln(2) * i);
for j:=1 to trunc(x) do begin
op1:=copy(s,j,(length(s) div 2) div trunc(x));
op2:=copy(s,(length(s) div 2)+j,(length(s) div 2) div trunc(x));
memo1.Lines.add(floattostr(x)+" op1="+op1+" op2="+op2);
end;
inc(i);
until x=length(s) div 2;
end;


 
Delphman   (2005-10-15 18:49) [19]

Во посмотрите правильно ли сдела? Может чтонибудь можно сделать для
оптимизации кода, с учётом того что длина строки может быть 2^26

procedure TForm1.Button1Click(Sender: TObject);
const
s="1234567887654321"; //test1 n=16
//s="12344321";         //test2 n=8
//s="1221";             //test3 n=4
//s="12";             //test4 n=2
var
i,j,cols: integer;
x: real;
op1,op2,r: string;
begin
i:=0;x:=1;
memo1.Lines.add(s);
repeat
x:=exp(ln(2) * i);
cols:=(length(s) div 2) div trunc(x);
for j:=1 to trunc(x) do begin
op1:=copy(s,j*cols-cols+1,cols);
op2:=copy(s,length(s)-(j*cols-1),cols);
if strtoint(op1)<=strtoint(op2) then
r:="+" else r:="-";
memo1.Lines.add(floattostr(x)+" op1="+op1+" op2="+op2+" r= "+r);
end;
inc(i);
until x=length(s) div 2;
end;


 
Fenik ©   (2005-10-15 20:03) [20]

> x:=exp(ln(2) * i);

Это что?


 
Delphman   (2005-10-16 10:54) [21]

так вычисляется количество повторений


 
Fenik ©   (2005-10-16 17:30) [22]

Может я чего-то не понял, но по твоим примерам сделал вот это:

function MonoFunc(const BinStr: string): Boolean;
var I, L: Integer;
begin
 Result := True;
 L := Length(BinStr);
 if L mod 2 = 0 then
 for I := 0 to L div 2 - 1 do
   if (PChar(BinStr)[I]       = "1") and
      (PChar(BinStr)[L-(I+1)] = "0") then
   begin
     Result := False;
     Break;
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 if MonoFunc(Edit1.Text) then
   Caption := "+"
 else
   Caption := "-";
end;


 
Fenik ©   (2005-10-16 18:15) [23]

> Delphman  (15.10.05 18:49) [19]

Или важно место, где возникает "-", а не то, возникает он вообще или нет?


 
Delphman   (2005-10-17 18:59) [24]

Fenik спасибо, так кароче чем у меня, но я ещё не проверял.


 
Delphman   (2005-10-18 11:20) [25]

Всё бы хорошо, но 1001 выдаёт +, а должен - т.к.
10<=01 result="-"


 
Fenik ©   (2005-10-19 02:24) [26]

Блин, точно. Теперь вьехал :)
Завтра доделаю.


 
Fenik ©   (2005-10-19 18:12) [27]

uses Math;

function MonoFunc(const BinStr: string): Boolean;
var I, J, L, N, Left, Right: Integer;
begin
 Result := False;
 L := Length(BinStr);
 if L > 1 then begin
   if Frac(Log2(L)) <> 0 then
     Exit; { Длина строки не является степенью двойки, поэтому выходим. }

   N := L div 2; { длина сравниваемых подстрок }
   repeat
     Left := 0;      { позиция начала текущей левой подстроки в BinStr }
     Right := L - N; { позиция начала текущей правой подстроки в BinStr }
     for I := 1 to L div (N+N) do begin
       for J := 0 to N - 1 do begin
         if PChar(BinStr)[Left + J]  = "1" then begin
           if PChar(BinStr)[Right + J] = "0" then
             Exit;  { Условие нарушено. Выходим с отрицательным результатом. }
         end
         else
           if PChar(BinStr)[Right + J] = "1" then
             Break; { Дальше проверять не стоит: ясно, что правое число больше левого. }
       end;
       Inc(Left, N);
       Dec(Right, N);
     end;
     N := N div 2;
   until N < 1;
   Result := True;
 end;
end;



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2005.11.13;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.039 c
14-1130155998
Дельфятник
2005-10-24 16:13
2005.11.13
Где можно можно скачать Report Builder?


4-1126241076
Фагот
2005-09-09 08:44
2005.11.13
Перехват клавиш в консольном приложении


2-1129795481
koks
2005-10-20 12:04
2005.11.13
Форматирование вычисляемого поля


4-1126766053
Новый
2005-09-15 10:34
2005.11.13
окно приветствия


2-1129799356
Gear
2005-10-20 13:09
2005.11.13
Как сделать главную форму без рамки но...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский