Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Интересные и занимательные задачи по программированию > Перевернуть число int задом наперёд.


Автор: ANTON_AL 31.1.2007, 10:42
Здравствуйте!
Помню, как то мне попалась задачка при поступлении на одни курсы:
Дано целое число ( любое ).
Без опреаций со строками преобразовать его так, чтобы оно было записано задом наперёд.

Я так и не знаю, как её решить....


С уважением, Антон.

Автор: Strannik 31.1.2007, 11:08
Код

var i,n,j: integer;
      a: array [1..10] of byte
begin
 readln(n);
 i:=0;
 while n<>0 do
  begin
   inc(i);
   a[i]:=n mod 10;
   n:=n div 10;
  end;
 for j:=i to 1 do
 write(a[i]);
end.
Так?

Автор: Romikgy 31.1.2007, 11:25
Код

var i,n,j: integer;
      
begin
 readln(n);
 i:=0;
 while n<>0 do
  begin
   
   j:=n mod 10;
   i:=i*10;
   i:=i+j;
   n:=n div 10;
  end;

 write(i);
 readln;
end.

мой вариант smile

Автор: ANTON_AL 31.1.2007, 11:54
Я тогда примерно так и написал, но меня интересует, можни ли её решить каким нибудь хитрым способом, поигавшись с числами, может в бинарном виде. ( Это типа как обменять значения двух переменных без участия третьей ) Вот в таком вот духе...

Автор: Romikgy 31.1.2007, 12:05
т.к. числа десятичные то без модулей 10 ничего не будет работать, 
и хитрее можно сделать но код усложнится на порядок имхо
было бы 16 ричные вопросов не возниклобы

Автор: V.A.KeRneL 31.1.2007, 13:15
Ну, блин, ANTON_AL, чё-то ты ни фига подробно, то нужно не засписал!.. 
Во-первых, не указал язык программирования => приходится гадать между двумя самыми пополярными C (C++) и Pascal (Delphi). 
Во-вторых, что не так очевидно, не указана система счисления, представление числа в которой требуется инвертировать. Скорее всего десятиное. Но также вполне возможно, что двоичное. [Крайне мало-]вероятны все остальные. 
В-третьих, не слишком жёсткие ограниения, которые легко обошёл Strannik, заюзав в каестве дополнительной временной структуры хранения данных не строку, а массив. Наверное, надо было сказать, что допустимы только численные (в т.ч. побитовые) операции, без прочих внешних копирований. 
В-четвёртых: «Дано целое число ( любое )». Наверно, всё-таки, не любое, а неотрицательное. 
Пока, вроде, все замечания... smile

Romikgy привёл более устойчивую к ограниениям версию, чем Strannik.

Ещё есть такие понятия, как реверс битов и байтов. Может прогится...
Из книжки Генри Уоррена, мл. «Алгоритмические трюки для программистов»: 
«Ниже показан эффективный метод реверса битов в слове [3]: в первой строке меняются местами соседние биты, во второй — соседние 2-битовые поля и т.д.Все пять операторов присвоения можно выполнять в произвольном порядке.

Код

x = (x & 0x55555555) <<  1 | (x & 0xAAAAAAAA) >>  1;
x = (x & 0x33333333) <<  2 | (x & 0xCCCCCCCC) >>  2;
x = (x & 0x0F0F0F0F) <<  4 | (x & 0xF0F0F0F0) >>  4;
x = (x & 0x00FF00FF) <<  8 | (x & 0xFF00FF00) >>  8;
x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16;


Для ряда машин можно воспользоваться усовершенствованием, приведённым влистинге 7.1, которое заключается в том, чтобы избежать больших непосредственно задаваемых значений. Этот код требует выполнения 30 базовых RISC-команд и не использует команд ветвления.

Листинг 7.1. Реверс битов
Код

unsigned rev(unsigned x) 
{ 
    x = (x & 0x55555555) <<  1 | (x >>  1) & 0x55555555;
    x = (x & 0x33333333) <<  2 | (x >>  2) & 0x33333333;
    x = (x & 0x0F0F0F0F) <<  4 | (x >>  4) & 0x0F0F0F0F;
    x = (x << 24) | ((x & 0xFF00) <<  8) | 
        ((x >>  8) & 0xFF00) | (x >> 24);
    return x;
}


--------------------
[ИСТОНИКИ ИНФОРМАЦИИ]
3. Найдено в подпрограмме интерпретатора REXX, написанной Марком Аусландером (Marc A. Auslander).»

Автор: Strannik 31.1.2007, 15:15
Цитата

Romikgy привёл более устойчивую к ограниениям версию, чем Strannik.

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

V.A.KeRneL, респект! Классную информацию нашел. Мне вот буквально только что эту книгу («Алгоритмические трюки для программистов») скинули...

Автор: mr.Anderson 4.2.2007, 16:16
Ой, как все сложно... smile Приведу мой вариант, покороче.
Код

Program Revers;
Var num: Integer;
Begin

 Readln( num );

 while( num mod 10 > 0 )
 begin
  Write( num mod 10 );
  num = num div 10;
 end;

End.

Все! smile Коротко, ясно, и переменная всего одна.

Автор: Dov 4.2.2007, 17:05
Цитата(mr.Anderson @  4.2.2007,  15:16 Найти цитируемый пост)
Коротко, ясно, и переменная всего одна.


mr.Anderson
, а ты свой код проверял? Чё та мне кажется, что если ввести число, например 12034,  то будет не так уж коротко, а тем более, ясно. Но, может быть я ошибаюсь.  smile 

Автор: V.A.KeRneL 4.2.2007, 17:56
Неа, не ошибаешься. smile Там, конечно, надо 
Код

 while( num > 0 )

 вместо 
Код

 while( num mod 10 > 0 )


Автор: mr.Anderson 4.2.2007, 18:59
Ступил. smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)