Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
ВнизРабота с текстом(перевёртыш) Найти похожие ветки
← →
SooM © (2010-05-05 21:43) [0]Вводиться число. Совпадает ли оно со своим "перевёртышем"(числом , получающимся при течение данного на оборот).
Заранее спасибо
← →
oldman © (2010-05-05 21:48) [1]Кто на ком стоял?
> при течение данного на оборот
велик могучим русский языка...
← →
Германн © (2010-05-05 21:50) [2]Не совпадает.
← →
oldman © (2010-05-05 21:57) [3]
> Работа с текстом(перевёртыш)
> Вводиться число
И не совпадет.
← →
' (2010-05-05 22:14) [4]Перевертыш зеркальный или перевертыш числовой.
Допустим
1)
123456
654321
2)
11110010
00001101
Первый реализуется циклом с конца строки в строкову переменную.
Второй реализуется заменой на противоположное число при условии.
← →
И. Павел © (2010-05-05 22:17) [5]Такую задачу интереснее решать, если запретить использование строк. Такие числа называются палиндромами. Перевертыши - это что-то из Лукьяненко :)
procedure TForm1.Button1Click(Sender: TObject);
var stroka:string;
ok:boolean;
i:integer;
begin
stroka := Edit1.Text;
ok:=true;
for i := 1 to length(stroka) div 2 do
if stroka[i] <> stroka[length(stroka)-i+1] then
Begin
ok:=false;
break;
end;
if ok then Application.MessageBox("Совпадают", "", 0)
else Application.MessageBox("Не совпадают", "", 0);
end;
← →
' (2010-05-05 22:37) [6]Йоо) ну и кодинг.
function prov(s,s1:string):boolean;
var
i:byte; g:string;
begin
g:="";
result:=false;
for i:=length(s) downto 1 do
g:=g+s[i];
if g=s1 then
result:=true;
end;
использовать так
if prov("stroka1","stroka2") then
showmeessage("sovpali") else showmeessage("net");
← →
И. Павел © (2010-05-05 22:49) [7]
> Йоо) ну и кодинг.
В моем коде нет бесполезных присваиваний (g:=g+s[i]), и цикл только до половины строки. Что не понравилось?
← →
И. Павел © (2010-05-05 22:51) [8]
> stroka := Edit1.Text;
Даже без этого можно обойтись.
← →
Smile (2010-05-05 22:52) [9]> "<> (05.05.10 22:37) [6]
Для чего нужно в функцию передавать s1, если это известный параметр?
:)
← →
DVM © (2010-05-05 22:56) [10]Вы дальтоники что ли, число от строки отличить не можете? Сказано же, вводится число.
← →
Игорь Шевченко © (2010-05-05 22:59) [11]
> Заранее спасибо
За ранее
← →
Smile (2010-05-05 23:04) [12]> DVM © (05.05.10 22:56) [10]
Число ввести невозможно
:)
← →
DVM © (2010-05-05 23:06) [13]
> Smile (05.05.10 23:04) [12]
> Число ввести невозможно
var
a: integer;
begin
writeln("Введите целое число");
read(a);
end;
← →
Smile (2010-05-05 23:06) [14]
> DVM © (05.05.10 22:56) [10]
Если не дальтоник, то читай [0]
Работа с текстом(перевёртыш)
:)
← →
DVM © (2010-05-05 23:12) [15]
> Smile (05.05.10 23:06) [14]
Задание, где на входе число в виде строки неинтересное и простое. А вот для числа уже есть над чем подумать.
← →
Smile (2010-05-05 23:21) [16]> DVM © (05.05.10 23:12) [15]
Трудно возразить
:(
← →
И. Павел © (2010-05-05 23:26) [17]Код можно и оптимизировать, но вроде бы работает:
procedure TForm1.Button1Click(Sender: TObject);
var chislo, c, l, a, b:integer;
ok:boolean;
begin
chislo:=12344321;
c:=chislo;
l:=1;
ok:=true;
repeat
l:=l*10;
c:=c div 10;
until c=0;
l:=l div 10;
repeat
if l=0 then break;
a:=chislo div l;
b:=chislo mod 10;
chislo := (chislo mod l) div 10;
l:=l div 100;
if a<>b then
Begin
ok:=false;
break;
end;
until chislo=0;
if ok then Application.MessageBox("Совпадает", "", 0)
else Application.MessageBox("Не совпадает", "", 0);
end;
← →
Игорь Шевченко © (2010-05-05 23:30) [18]И. Павел © (05.05.10 23:26) [17]
Купи книжку Стива МакКоннелла и учи наизусть.
← →
DVM © (2010-05-05 23:37) [19]у меня вот такой вариант для переворачивания:
function Reverse(x: integer): integer;
var
maxb: integer;
function Rev(a, b: integer): integer;
begin
if a = 0 then
begin
result := 0;
maxb := b div 10;
exit;
end;
result := (a mod 10) * (maxb div b) + Rev((a div 10), b * 10)
end;
begin
result := Rev(x, 1);
end;
← →
Inovet © (2010-05-05 23:47) [20]Эх.
http://delphimaster.net/view/2-1242503429
← →
DVM © (2010-05-05 23:51) [21]
> Inovet ©
что характерно, прошел год ровно.
← →
Игорь Шевченко © (2010-05-05 23:53) [22]DVM © (05.05.10 23:51) [21]
В сети мне как-то попалась методичка, все вопросы из которой задавались на delphimaster (и не только).
← →
' (2010-05-06 00:00) [23]Тогда у меня такой вариант:
var
original_num:longint;function perevernut(chislo:longint):longint;
var temp, copychislo:longint;
begin
copychislo:=chislo;
temp:=0;
while(copychislo<>0) do
begin
temp:=(temp*10)+(copychislo mod 10);
copychislo:=copychislo div 10;
end;
perevernut:=temp;
end;
original_num:=12345;
if perevernut(original_num)=original_num then
showmessage("ravno") else showmessage("net");
← →
Sha © (2010-05-06 01:39) [24]
function IsNumberPalindrome(num: integer): boolean;
var
cpy, pal: integer;
begin;
if (num<0) or (num>2147447412) //MaxInt=2147483647
then Result:=false
else begin;
pal:=0;
repeat;
cpy:=num;
num:=num div 10;
pal:=10*(pal-num) + cpy;
until (pal>=cpy) or (pal=num);
Result:=(pal<=cpy);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
const
Answers: array[boolean] of string= ("нет", "да");
begin;
Edit2.Text:=Answers[IsNumberPalindrome(StrToIntDef(Edit1.Text,-1))];
end;
← →
Германн © (2010-05-06 02:21) [25]
> DVM © (05.05.10 23:51) [21]
>
>
> > Inovet ©
>
> что характерно, прошел год ровно.
>
Ну и опять ученики кулинарного техникума получили задание из той же самой методички.
← →
Anatoly Podgoretsky © (2010-05-06 07:26) [26]> Игорь Шевченко (05.05.2010 23:53:22) [22]
Тебе попалась методичка, все вопросы из который взяты с delphimaster
← →
Омлет © (2010-05-06 12:08) [27]
function IsPalindrome(N: Integer): Boolean;
var
X, Y: Integer;
begin
if N < 10 then
Result := (N >= 0)
else begin
X := 0;
Y := N;
repeat
X := X * 10 + Y mod 10;
Y := Y div 10;
until (Y = 0);
Result := (N = X);
end;
end;
← →
Sha © (2010-05-06 13:07) [28]Алгоритм [24] может выдать неверный положительный результат, если число оканчивается нулем, например, 10.
Алгоритмы, основанные на "перевороте" числа и сравнении с исходным числом
теоретически тоже могут выдать неверный положительный результат
из-за возможного переполнения.
Интересно было бы продемонстрировать это на примере для произвольного основания системы счисления и разрядности чисел.
← →
DVM © (2010-05-06 14:53) [29]
> Sha © (06.05.10 13:07) [28]
> Интересно было бы продемонстрировать это на примере для
> произвольного основания системы счисления и разрядности
> чисел.
Для произвольной разрядности надо знать представление числа в памяти. Универсальный алгоритм вряд ли возможен. Если только для целочисленных типов из Delphi.
← →
Sha © (2010-05-06 14:55) [30]> Если только для целочисленных типов из Delphi.
Именно это я имел в виду.
← →
Sha © (2010-05-06 15:09) [31]Исправленная версия алгоритма [24]
function ShaIsNumberPalindrome(num: integer; radix: integer= 10): boolean;
var
cpy, rev: integer;
begin;
if num<radix
then Result:=(num>=0)
else begin;
cpy:=num;
num:=num div radix;
rev:=cpy - num * radix;
if rev=0
then Result:=false
else begin;
repeat;
cpy:=num;
num:=num div radix;
rev:=radix * (rev-num) + cpy;
until (rev>=cpy) or (rev=num);
Result:=(rev<=cpy);
end;
end;
end;
← →
Омлет © (2010-05-06 15:16) [32]> Sha © (06.05.10 15:09) [31]
ShaIsNumberPalindrome(11) = False
← →
Омлет © (2010-05-06 15:26) [33]И еще - подлянка от Дельфи:
ShaIsNumberPalindrome(3999999993) = False
← →
Sha © (2010-05-06 15:38) [34]> ShaIsNumberPalindrome(11) = False
Да, это ошибка.
Вынес первую итерацию из цикла, а repeat на while заменить забыл.
Хотелось поскорее найти переполнения.
Надеюсь, так будет верно
function ShaIsNumberPalindrome(num: integer; radix: integer= 10): boolean;
var
cpy, rev: integer;
begin;
if num<radix
then Result:=(num>=0)
else begin;
cpy:=num;
num:=num div radix;
rev:=cpy - num * radix;
if rev=0
then Result:=false
else begin;
while (rev<>num) and (rev<cpy) do begin;
cpy:=num;
num:=num div radix;
rev:=radix * (rev-num) + cpy;
end;
Result:=(rev<=cpy);
end;
end;
end;
> ShaIsNumberPalindrome(3999999993) = False
Это не integer, a cardinal, так что все верно.
Если параметр объявить как cardinal, получим правильный ответ для cardinal.
← →
Омлет © (2010-05-06 15:50) [35]Да, так работает.
> Это не integer, a cardinal, так что все верно.
Проблема в том, что компилятор не ругается на выход за пределы диапазона. А на глаз сразу и не скажешь, что это число уже не Integer ))
← →
Омлет © (2010-05-06 15:56) [36]> Если параметр объявить как cardinal, получим правильный
> ответ для cardinal.
И надо не забыть{$Q-}
← →
Омлет © (2010-05-06 16:04) [37]> Омлет © (06.05.10 15:50) [35]
> компилятор не ругается
Вру. Ругается. Просто я варнинг не заметил.
← →
Sha © (2010-05-06 17:42) [38]В работе алгоритма, аналогичного [27], с параметром integer
не удалось обнаружить ошибок, вызванных переполнением,
для всех значений radix в диапазоне 2..13 и нечетных значений 15,17,19...35.
← →
Sha © (2010-05-06 22:36) [39]Обнаружено, что алгоритм
//Из-за переполнения может выдавать неверный положительный результат
function StdIsNumberPalindrome(num: cardinal; radix: cardinal= 10): boolean;
var
save, cpy, rev: cardinal;
begin;
if num<radix
then Result:=true
else begin;
save:=num;
rev:=0;
repeat;
cpy:=num;
num:=num div radix;
rev:=(rev-num) * radix + cpy;
until num=0;
Result:=(rev=save);
end;
end;
более чем в 128000 случаях выдает неверный результат для radix=1025, например, для таких чисел
1 1089498130(10) 1.12.0.5(1025)
2 1090549780(10) 1.13.1.5(1025)
3 1091601430(10) 1.14.2.5(1025)
4 1092653080(10) 1.15.3.5(1025)
5 1093704730(10) 1.16.4.5(1025)
6 1094756380(10) 1.17.5.5(1025)
7 1095808030(10) 1.18.6.5(1025)
8 1096859680(10) 1.19.7.5(1025)
9 1097911330(10) 1.20.8.5(1025)
← →
Sha © (2010-05-06 23:19) [40]Версия алгоритма [27] для cardinal также работает не всегда верно:
//Неверно работает для radix=1025, num=2149584896(10) 1.1021.5.1021(1025)
function Alg27IsNumberPalindrome(num: cardinal; radix: cardinal= 10): boolean;
var
save, rev: cardinal;
begin;
if num<radix
then Result:=true
else begin;
save:=num;
rev:=0;
repeat;
rev:=rev * radix + num mod radix;
num:=num div radix;
until (num=0);
Result:=(num=rev);
end;
end;
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.07 c