Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> проверка палиндрома 
:(
    Опции темы
ArniLand
Дата 27.12.2010, 14:28 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 17.8.2008

Репутация: нет
Всего: нет



Дано пятизначное число и нужно проверить является данное число палиндромом. Можно использовать только арифметические/логические операции и операторы while/if. Массивы использовать нельзя. Начала с изучения основ программирования на С++, не могу понять какой алгоритм данной задачи. И вопрос немного отходя от темы. Сам придумать алгоритм я не могу и не понять пока что как решить такую задачу, не является это признаком того что программированием я заниматься не смогу?
PM MAIL   Вверх
mes
Дата 27.12.2010, 15:06 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(ArniLand @  27.12.2010,  13:28 Найти цитируемый пост)
 Можно использовать только арифметические/логические операции и операторы while/if

Пытаясь придумать алгоритм в "компьютерной записи" Вы пропустили важный момент:
для начала сформулируйте понятные для человека признаки по которым можно проверить палиндром ли это.. 
а после уже спокойно и без проблем перевести на ЯП.. 




--------------------
PM MAIL WWW   Вверх
Игорь1024
Дата 27.12.2010, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 11.5.2009
Где: Дальний Восток

Репутация: нет
Всего: нет



Код

#include "iostream.h"
int val=0x12321, res=0;
count()
{
__asm
{
cmp val, val+4
jne exit
cmp val+1, val+3
jne exit
mov res, 1d
exit: ret
}
}

void main()
{
count();
if(res==1)cout<<"It is";
}


Не тестил. Скорее всего есть ошибки. Спать хочу.

Это сообщение отредактировал(а) Игорь1024 - 31.12.2010, 18:35
--------------------
The God is real,unless he is declared as integer.
PM MAIL   Вверх
Crafty
Дата 27.12.2010, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 319
Регистрация: 3.11.2008

Репутация: 12
Всего: 14



Игорь1024, а причем здесь ассемблер?
PM MAIL   Вверх
mes
Дата 27.12.2010, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Игорь1024 @  27.12.2010,  14:24 Найти цитируемый пост)
Не тестил

хм..smile  в разделе "C++ для новичков" предлагать asm код...    smile 
да к тому же неправильный.. палиндром же задан не в 16ричной системе  smile 


--------------------
PM MAIL WWW   Вверх
Игорь1024
Дата 27.12.2010, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 11.5.2009
Где: Дальний Восток

Репутация: нет
Всего: нет



 smile мда, на сях слишком долгие вычисления, а я спать хочу. Мало ли, может подошло бы.
На счёт неправильности.... Система счисления не была указана  smile 

Это сообщение отредактировал(а) Игорь1024 - 27.12.2010, 15:35
--------------------
The God is real,unless he is declared as integer.
PM MAIL   Вверх
mes
Дата 27.12.2010, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Игорь1024 @  27.12.2010,  14:35 Найти цитируемый пост)
. Система счисления не была указана   

так у Вас же "12321" есть десятичное число  smile 

к тому же сдвиг идет по байтово, хотя одна шестнадцатиричная цифра занимает ровно половину.. 
smile
 


Это сообщение отредактировал(а) mes - 27.12.2010, 15:58


--------------------
PM MAIL WWW   Вверх
Игорь1024
Дата 27.12.2010, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 11.5.2009
Где: Дальний Восток

Репутация: нет
Всего: нет



Баю-баюшки баю...  smile 
--------------------
The God is real,unless he is declared as integer.
PM MAIL   Вверх
baldina
Дата 27.12.2010, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата

Сам придумать алгоритм я не могу и не понять пока что как решить такую задачу, не является это признаком того что программированием я заниматься не смогу? 

нет, не является  smile 
любое боль-менее сложное занятие требует знаний и практики. всё получится
PM MAIL   Вверх
darkart
Дата 27.12.2010, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 379
Регистрация: 9.11.2005

Репутация: нет
Всего: 31



Код

#include <iostream>

using namespace std;

const int BASE = 10;

int GetDigits( int number )
{
    int digits = 0;
    do
    {
        number = number /= BASE;
        digits++;
    }
    while( number );
    return digits;
}

bool IsPalindrome( int number )
{
    bool result = true;
    int mod, div;
    int digits = GetDigits( number );
    if( digits > 1 )
    {
        mod = BASE;
        div = 1;
        for( int j = 1; j < digits; j++ )
            div *= BASE;    
        int i = 0;
        while( ( i < digits / 2 ) && ( ( ( number % mod ) / ( mod / BASE ) ) ==  ( ( number / div ) % BASE ) ) )
        {
            i++;
            mod *= BASE;
            div /= BASE;
        }
        result = i == digits / 2;
    }
    return result;
}

int main()
{
    int number;
    cout << "Please enter a number:" << endl;
    cin >> number;
    cout << number << " is ";
    if( !IsPalindrome( number ) )
        cout << "not ";
    cout << "palindrome" << endl;
    return 0;
}

PM MAIL WWW ICQ Skype GTalk   Вверх
baldina
Дата 27.12.2010, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



определим палиндром как слово (строка) S длиной N в некотором алфавите,  (т.е. просто последовательность букв алфавита), обладающая свойством
S(i) = S(N-i-1), i изменяется от 0 до N-1
говоря неформально, палиндром - симметричная строка, читающаяся одинаково слева направа и справа налево.
для определенности будем считать пустую строку палиндромом.
для проверки надо последовательно проверить совпадение первого с последним, второго с предпоследним и т.д.

обобщенный алгоритм проверки (в реализации на С++) будет такой:
Код

template <typename Iterator>
bool is_palindrome (Iterator begin, Iterator end)
{
  //  begin - итератор, указывающий на первый элемент
  //  end - итератор, указывающий на последний элемент
  //  операции ++ и -- передвигают итератор на следующий и предыдущий элемент соответственно
  //  *x - значение элемента последовательности, на которое указывает x

  while (begin < end)
  {
     if (*begin != *end)
        return false;

     ++begin;
     --end;
  }

  return true;
}

это не самая общая (и не вполне правильная) реализация на С++, она приводится для простоты введения в тему. вышеприведенный код будет работать для итераторов произвольного доступа, если входная последовательность непуста.
более общий и правильный код будет ниже, а пока поговорим об этом.
ключевое место алгоритма - понятие итератора (у нас это begin и end), который позволяет
1. идентифицировать элемент в последовательности
2. передвигаться вперед и назад
сам алгоритм прост и вытекает из определения палиндрома. замечу, что он использует только цикл, логические и арифметические операции. операции над итераторами в алгоритме похожи на операции с указателями и массивами, однако тут они выражают семантику алгоритма и необязательно работают с массивами и реальными указателями. все зависит от того, чем конкретно является (как реализован) тип Iterator.

В данной задаче алфавитом являются десятичные цифры 0...9, а строкой - запись числа в десятичной системе. т.к. числа в компьютере представлены в двоичном виде, нужно уметь получать первую, вторую...последнюю (десятичную) цифру числа из внутреннего представления. если это решить, останется просто применить вышеприведенный тривиальный алгоритм.

полностью решение приводить не буду, но путь следующий:
операция 
Код

y = x % 10;

помещает в переменную y остаток от деления числа x на 10, т.е. значение последней цифры.

в качестве приложения - менее очевидный, но более общий и правильный код, работающий и для  последовательных итераторов, и пустых строк:
Код

template <typename Iterator>
bool is_palindrome (Iterator begin, Iterator end)
{
  //  begin - указатель на первый элемент
  //  end - указатель на элемент, следующий за последним
  //  если последовательность пуста, то begin == end

  while (begin != end)
  {
     --end;
     if (begin == end)
        return true;
     if (*begin != *end)
        return false;
     ++begin;
  }

  return true;
}

эту функцию можно непосредственно применить к явным последовательностям (контейнерам, имеющим двунаправленные итераторы, в т.ч. к обычным массивам), например
Код

std::string str = "арозаупаланалапуазора";
int arr1[5] = {1,2,3,2,1};
int arr2[5] = {1,2,3,4,5};
std::list<int> l;
l.push_back(2);
l.push_back(1);
l.push_back(2);
std::cout << is_palindrome (str.begin(), str.end()); // вывод: 1
std::cout << is_palindrome (arr1, arr1+5); // вывод: 1
std::cout << is_palindrome (arr2, arr2+5); // вывод: 0
std::cout << is_palindrome (l.begin(), l.end()); // вывод: 1


PM MAIL   Вверх
bsa
Дата 27.12.2010, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



PM   Вверх
baldina
Дата 27.12.2010, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



bsa, не то. там все про массивы, тут низзя
PM MAIL   Вверх
Skevalt
Дата 27.12.2010, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 30.11.2006

Репутация: нет
Всего: 3



Уже привели правильные решения, напишу и этот вариант на всякий случай
Код

#include <iostream>
#include <cmath>

typedef unsigned int uint;

uint pow10(uint base)
{
    uint res = 1;
    for(int i = base; i > 0; i--)
        res *= 10;
    return res;
}

bool isPalindrome(unsigned int num)
{
    uint quotient  = 0;
    uint remainder = 0;
    uint position  = 0;
    uint reverseNum = 0;
    uint sourceNum = num;

    position = uint(log10(double(num)));
    do{
        quotient  = sourceNum / 10;        
        remainder = sourceNum % 10;
        reverseNum += remainder*pow10(position);
        sourceNum /= 10;
        position--; 
    }while(quotient);

    return (num == reverseNum);
}

int main(int argc, char* argv[])
{
    uint testNum1 = 12321;
    uint testNum2 = 12345;
    uint testNum3 = 1234321;

    if(isPalindrome(testNum1 ))
        std::cout << testNum1 << " is palindrome" << std::endl;
    else
        std::cout << testNum1 << " isn't palindrome" << std::endl;

    if(isPalindrome(testNum2 ))
        std::cout << testNum2 << " is palindrome" << std::endl;
    else
        std::cout << testNum2 << " isn't palindrome" << std::endl;

    if(isPalindrome(testNum3 ))
        std::cout << testNum3 << " is palindrome" << std::endl;
    else
        std::cout << testNum3 << " isn't palindrome" << std::endl;

    return 0;
}


PM MAIL   Вверх
baldina
Дата 27.12.2010, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



продолжим...
надеюсь, ТС подумал самостоятельно прежде чем читать дальше  smile 
требуется построить итератор для целых чисел такой, что бы были корректно реализованы операции сравнения итераторов, разыменования (получения значения, на которое указывает итератор), инкремента и декремента
такой итератор в простейшей реализации мог бы выглядеть так:
Код

/* простейший итератор без контроля выхода за границы */
struct DecDigIter {
  int x;
  int p;
  DecDigIter(int x, bool end=false): x(x),p(0) {
    if (end)
      for (int y=x; y != 0; y /= 10)
         ++p;
  }
  bool operator==(const DecDigIter& other) const { return p==other.p; }
  bool operator!=(const DecDigIter& other) const { return !(*this == other); }
  int operator*() const { return (x/pow10(p)) % 10; }
  DecDigIter& operator++() { ++p; return *this; }
  DecDigIter& operator--() { --p; return *this; }
};

т.е. итератор хранит само число х и текущую позицию p. инкремент/декремент производится тривиальным образом, для разыменования (получение цифры в позиции p) используется выражение
(x/pow10(p)) % 10; Здесь самая трудоемкая операция - возведение в степень.
И хотя реализация нашего алгоритма с этим итератором и "правильной" реализацией возведения в степень чуть быстрее реализации darkart, интуитивно чувствуется, что резерв есть, и можно придумать алгоритм быстрее.

PM MAIL   Вверх
mimik
Дата 27.12.2010, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не Rohoss Я
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 1.11.2010

Репутация: нет
Всего: 2



Цитата(ArniLand @  27.12.2010,  14:28 Найти цитируемый пост)
Дано пятизначное число и нужно проверить является данное число палиндромом

Код

int n = 12321;
if (n/10000==n%10 && n/1000%10==n/10%10)
    cout << "yes";

PM   Вверх
baldina
Дата 27.12.2010, 18:48 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



идея следующая: если удастся простым способом получить "перевернутое" число, его можно просто сравнить с исходным.
такой алгоритм потребует вычисления остатка от деления на 10 для всех цифр исходного числа и формирования из остатков перевернутого числа, умножаемого на 10.
т.е. получается довольно простой цикл.
пока я это писал Skevalt привел почти тот самый алгоритм. если "отсечь лишнее", получится попроще (и побыстрее).
Код

bool is_palindrome (unsigned x)
{
  int z = x;
  int y = 0;
  while (x>0)
  {
    y *= 10;
    y += x%10;
    x /= 10;
  }
  return (y==z);
}

PM MAIL   Вверх
mes
Дата 27.12.2010, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(baldina @  27.12.2010,  17:36 Найти цитируемый пост)
 и текущую позицию p

Цитата(baldina @  27.12.2010,  17:36 Найти цитируемый пост)
 Здесь самая трудоемкая операция - возведение в степень.

может позицию хранить не как индекс, а как степень десяти ?
т.е. итерацию проводить не как ++/--, а как *=10 / /=10

Добавлено через 3 минуты и 40 секунд
Цитата(baldina @  27.12.2010,  17:48 Найти цитируемый пост)
идея следующая: если удастся простым способом получить "перевернутое" число, его можно просто сравнить с исходным.

у этого алгоритма есть недостаток возможно  переполнение и как следствие не правильный результат..

Добавлено через 4 минуты и 37 секунд
Цитата(baldina @  27.12.2010,  17:48 Найти цитируемый пост)
 и формирования из остатков перевернутого числа, умножаемого на 10.

а чем не устраивает хранение промежуточного числа как строки ?



--------------------
PM MAIL WWW   Вверх
mimik
Дата 27.12.2010, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не Rohoss Я
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 1.11.2010

Репутация: нет
Всего: 2



Цитата(mes @  27.12.2010,  18:57 Найти цитируемый пост)
у этого алгоритма есть недостаток возможно  переполнение и как следствие не правильный результат..

в упор не вижу где?
Цитата(mes @  27.12.2010,  18:57 Найти цитируемый пост)
а чем не устраивает хранение промежуточного числа как строки ?

это тот же массив
PM   Вверх
baldina
Дата 27.12.2010, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата

хранение промежуточного числа как строки

не устраивает ТС'а т.к. по условию массивы нельзя использовать.

у перевернутого числа действительно возможно переполнение, но вообще он красивый и мне нравится smile
промышленная реализация, возможно, должна была бы анализировать число и выбирать оптимальный алгоритм.

Цитата

т.е. итерацию проводить не как ++/--, а как *=10 / /=10

не вижу смысла. операция должна проводиться не над текущей цифрой, а над предыдущей или следующей. так что можем выиграть лишь одно умножение на 10, стоит ли ради этого жертвовать ясностью?
хотя там есть небольшие возможности оптимизации, например можно более оптимально подсчитывать число цифр, вычисляя логарифм эффективным методом.
PM MAIL   Вверх
mes
Дата 27.12.2010, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(mimik @  27.12.2010,  18:09 Найти цитируемый пост)
в упор не вижу где?

ну на примере unsigned char : 
126 -> [621] -> 109

та же проблема, но на других значениях есть и других целочисленных типов.. 
smile

Добавлено через 2 минуты и 52 секунды
Цитата(baldina @  27.12.2010,  18:14 Найти цитируемый пост)
не вижу смысла. операция должна проводиться не над текущей цифрой, а над предыдущей или следующей. так что можем выиграть лишь одно умножение на 10, стоит ли ради этого жертвовать ясностью?

это смотря как подходить к вопросу.. мне кажется можноэтим подходом как раз повысить ясность..сейчас попробую.. 



--------------------
PM MAIL WWW   Вверх
mimik
Дата 27.12.2010, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не Rohoss Я
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 1.11.2010

Репутация: нет
Всего: 2



Цитата(mes @  27.12.2010,  19:21 Найти цитируемый пост)
126 -> [621] -> 109

да, ступил smile 

хотя при этом алгоритм может и работать правильно, надо проверить
PM   Вверх
mes
Дата 27.12.2010, 21:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(mes @  27.12.2010,  18:21 Найти цитируемый пост)
 мне кажется можноэтим подходом как раз повысить ясность..сейчас попробую.. 

отвлекся.. вот выбрал минутку и сделал набросок :
Код

template <size_t Rank>
struct shift
{
   unsigned left(unsigned value) {
      return value * Rank;
   }
   unsigned right (unsigned value) {
      return value / Rank;
   }   
};

template <>
struct shift<0x10>
{
   unsigned left(unsigned value) {
      return value << 4;
   }
   unsigned right (unsigned value) {
      return value >> 4;
   }   
};

template <size_t Rank = 10>
struct DigIter {
  
  unsigned value;
  unsigned base;

  DigIter& operator++() {
       base = shift<Rank>::left(base); return *this; 
  }
  DigIter& operator--() {
       base = shift<Rank>::right(base); return *this; 
  } 
};




--------------------
PM MAIL WWW   Вверх
Dov
Дата 28.12.2010, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 11
Всего: 88



Цитата(ArniLand @  27.12.2010,  13:28 Найти цитируемый пост)
Можно использовать только арифметические/логические операции и операторы while/if. Массивы использовать нельзя.

Да чего уж там? Запрещать, так запрещать. Тогда уж и без if/while обойдёмся...  smile 
Код
bool isPalindrome(int val, int cnt)
{
    return val < 100 && cnt ? 
           val / 10 == val % 10 : cnt ? 
           val / (int)pow(10, cnt) % 10 == val % 10 ? 
           isPalindrome(val / 10, cnt - 2) : false : true;
}

int main()
{
    int  value = 12321;
    
    cout << value << " -" 
         << (isPalindrome(value, (int)log10(value)) ? " " : " not ")
         << "palindrome\n";

    return 0;
}


Цитата(ArniLand @  27.12.2010,  13:28 Найти цитируемый пост)
Начала с изучения основ

Цитата(ArniLand @  27.12.2010,  13:28 Найти цитируемый пост)
Сам придумать алгоритм я не могу

Цитата(ArniLand @  27.12.2010,  13:28 Найти цитируемый пост)
не является это признаком того что программированием я заниматься не смогу?

Ты бы, для начала, с полом определил(ась/ся) бы...   smile 





--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
mes
Дата 28.12.2010, 01:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Dov @  27.12.2010,  23:26 Найти цитируемый пост)
 Тогда уж и без if/while обойдёмся...  

тогда уж и без рекурсии smile

а вообще для 5ти-значного числа из задания, все гораздо проще :
Код

return a / 1000 ==   a / 10 % 10 + a % 10 * 10;


Добавлено через 2 минуты и 16 секунд
или, как было приведено выше :
Цитата(mimik @  27.12.2010,  17:41 Найти цитируемый пост)
(n/10000==n%10 && n/1000%10==n/10%10)




--------------------
PM MAIL WWW   Вверх
baldina
Дата 28.12.2010, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



mes, все верно. вчера спешил и не сразу сообразил)))
точнее, сам себя запутал)

Это сообщение отредактировал(а) baldina - 28.12.2010, 10:32
PM MAIL   Вверх
mes
Дата 28.12.2010, 10:37 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Dov @  27.12.2010,  23:26 Найти цитируемый пост)
(int)log10(value)

http://liveworkspace.org/code/bbaad377991f...faf6e91ea7d57b8


--------------------
PM MAIL WWW   Вверх
mes
Дата 28.12.2010, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(mes @  27.12.2010,  17:57 Найти цитируемый пост)
Цитата

идея следующая: если удастся простым способом получить "перевернутое" число, его можно просто сравнить с исходным.

у этого алгоритма есть недостаток возможно  переполнение и как следствие не правильный результат..

чтоб не было переполнения можно ведь переворачивать только половину числа.. 
Код

bool is_pal (unsigned a)
{

   unsigned len = value_len(a);
   unsigned len2 = len >> 1;
   
   unsigned b = 0;
   
   for (size_t i=0; i < len2; ++i)              
   {
      b *= 10;
      b += a % 10;
      a /= 10;
   }
   
   if (len % 2) a /= 10;
     
   return a == b;
      
}


Добавлено @ 11:19
вот еще один вариант получения длины числа (32х битного):
Код

template <size_t Len>
struct base
{
    enum { value = base<Len-1> :: value * 10 };
};
template <>
struct base<1>
{
    enum { value = 1 };
};
template <>
struct base<0> {};

size_t value_len(unsigned a)
{
    return          a < base<6>::value 
                    ? a < base<4>::value
                      ? a < base<2>::value 
                        ? 1 
                        : a < base<3>::value   
                          ? 2
                          : 3
                       : a < base<5>::value     
                         ? 4
                         : 5
                    : a < base<8>::value
                      ? a < base<7>::value  
                        ? 6
                        : 7  
                      : a < base<10>::value
                        ? a < base<9>::value 
                          ? 8
                          : 9
                        : 10;              
}

этот "switch" можно метагенерить, но мне сейчас лень об этом думать

Это сообщение отредактировал(а) mes - 28.12.2010, 11:26


--------------------
PM MAIL WWW   Вверх
baldina
Дата 28.12.2010, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(mes @  28.12.2010,  11:17 Найти цитируемый пост)
чтоб не было переполнения можно ведь переворачивать только половину числа

 smile 

переворачивая половину числа можно не вычислять число цифр
Код

bool is_pal2 (unsigned x)
{
  if (x == 0)
    return true;
  if (x%10 == 0)
    return false;

  unsigned y = 0;
  while (x>y)
  {
    y *= 10;
    y += x%10;
    x /= 10;
  }
  return y == x || y/10 == x;
}


PM MAIL   Вверх
Dov
Дата 28.12.2010, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 11
Всего: 88



Цитата(mes @  28.12.2010,  09:37 Найти цитируемый пост)
http://liveworkspace.org/code/bbaad377991f...faf6e91ea7d57b8

Чего там? У меня не открывается ссылка. Здесь выложи...



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
mes
Дата 28.12.2010, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Dov @  28.12.2010,  12:13 Найти цитируемый пост)
Чего там? У меня не открывается ссылка. Здесь выложи...

Код


int main () {

  unsigned a  = ~0;
  std::cout << "value: "<< a << " len: " << (int)log10(a) << " ?! ";

}

Цитата

value: 4294967295 len: 9 ?! 


Добавлено через 13 минут и 41 секунду
Цитата(baldina @  28.12.2010,  11:24 Найти цитируемый пост)
переворачивая половину числа можно не вычислять число цифр

 smile 


--------------------
PM MAIL WWW   Вверх
Dov
Дата 28.12.2010, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 11
Всего: 88



Цитата(mes @  28.12.2010,  12:23 Найти цитируемый пост)
value: 4294967295 len: 9 ?! 

Не понял тонкого намёка.  smile 

Цитата(baldina @  28.12.2010,  11:24 Найти цитируемый пост)
переворачивая половину числа можно не вычислять число цифр

Да, алгоритм хороший, но абсолютно не эффективный.   Ведь в заданном числе уже первая и последняя цифра могут не совпасть. Зачем же всё это число 'разбирать на запчасти' ? smile
Но по репе заработал всё-равно...  smile 

Я  бы изменил как-то так:
Код
bool is_pal2 (unsigned x)
{
    unsigned y = (unsigned)pow(10., (unsigned)log10(x));
    
    while (y)
    {
        if(x / y % 10 != x % 10)
            return false;

        x /= 10;
        y /= 100;
    }

    return true;
}





Это сообщение отредактировал(а) Dov - 28.12.2010, 20:03


--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
mes
Дата 28.12.2010, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Dov @  28.12.2010,  18:58 Найти цитируемый пост)
Не понял тонкого намёка.  

в числе
Цитата(Dov @  28.12.2010,  18:58 Найти цитируемый пост)
4294967295

10 цифр(если конечно я правильно подсчитал ),  а не 9   smile

Добавлено через 56 секунд
другими словами (int)log10 показывает неправильный результат..



--------------------
PM MAIL WWW   Вверх
Dov
Дата 28.12.2010, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 11
Всего: 88



Цитата(mes @  28.12.2010,  19:06 Найти цитируемый пост)
другими словами (int)log10 показывает неправильный результат..

всё правильно показывает, так надо.  smile 



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
baldina
Дата 29.12.2010, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(Dov @  28.12.2010,  19:58 Найти цитируемый пост)
Цитата(baldina @  28.12.2010,  11:24 )
переворачивая половину числа можно не вычислять число цифр

Да, алгоритм хороший, но абсолютно не эффективный.   Ведь в заданном числе уже первая и последняя цифра могут не совпасть. Зачем же всё это число 'разбирать на запчасти' ? 
Но по репе заработал всё-равно...   

Ну, положим, из всех вышеприведенных он самый эффективный.
Во-вторых, "могут не совпасть" и "не совпадут" вещи неодинаковые. Надо анализировать средний случай. Для этого надо знать, какова вероятность появления палиндрома среди множества проверяемых чисел.
А то можно и алгоритм линейного поиска называть самым эффективным, т.к. "может совпасть" при первом же сравнении.
Аналитические исследования проводить лениво, а вот стандартный генератор случайных чисел на 200млн значений генерит 2.5млн палиндромов. В этих условиях алгоритм с обработкой половины значительно обгоняет другие. А самые медленные реализации те, что вызывают встроенные pow и log.
Кстати, данный результат неформально можно объяснить так - для определения какая цифра первая, а какая последняя, требуется узнать число цифр. Что сразу делает такой алгоритм зависящим от n, где n - число цифр.
"Алгоритм половины числа"  (назовем его так) в среднем (на произвольном числе) зависит от n/2.
зы: за репу спасибо
PM MAIL   Вверх
baldina
Дата 29.12.2010, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



кому интересно, тут результаты:
http://liveworkspace.org/code/5ad1983fdeb2...2368c01d7f3b717

длину числа пришлось ограничить тремя 000, т.к. на более длинных не проходит тест рекурсивного алгоритма Dov (видимо переполнение, не стал вникать).

у себя имею такие результаты (N/A - тест не пройден): 
для трехзначных чисел
Код

(darkart):
        0.252 sec,              1091528 palindromes in 10000000 numbers
Simple iterator +1 (baldina):
        0.268 sec,              1091528 palindromes in 10000000 numbers
Compare (Skevalt):
        0.442 sec,              1091528 palindromes in 10000000 numbers
Simple iterator *10 (baldina, mes):
        0.259 sec,              1091528 palindromes in 10000000 numbers
Compare (baldina):
        0.095 sec,              1091528 palindromes in 10000000 numbers
Recursion (Dov):
        0.467 sec,              1091528 palindromes in 10000000 numbers
Compare half (mes, baldina):
        0.123 sec,              1091528 palindromes in 10000000 numbers
Division (Dov):
        0.411 sec,              1091528 palindromes in 10000000 numbers


для любых чисел (32bit)
Код

(darkart):
        0.357 sec,              129934 palindromes in 10000000 numbers
Simple iterator +1 (baldina):
        0.375 sec,              129934 palindromes in 10000000 numbers
Compare (Skevalt):
        0.557 sec,              129934 palindromes in 10000000 numbers
Simple iterator *10 (baldina, mes):
        0.352 sec,              129934 palindromes in 10000000 numbers
Compare (baldina):
        0.176 sec,              129934 palindromes in 10000000 numbers
Recursion (Dov):
        N/A
Compare half (mes, baldina):
        0.139 sec,              129934 palindromes in 10000000 numbers
Division (Dov):
        0.482 sec,              129934 palindromes in 10000000 numbers


для любых чисел (64bit)
Код

(darkart):
        0.75 sec,               129842 palindromes in 10000000 numbers
Simple iterator +1 (baldina):
        0.738 sec,              129842 palindromes in 10000000 numbers
Compare (Skevalt):
        N/A
Simple iterator *10 (baldina, mes):
        0.777 sec,              129842 palindromes in 10000000 numbers
Compare (baldina):
        0.26 sec,               129842 palindromes in 10000000 numbers
Recursion (Dov):
        0.545 sec,              105257 palindromes in 10000000 numbers
Compare half (mes, baldina):
        0.182 sec,              129842 palindromes in 10000000 numbers
Division (Dov):
        N/A



Это сообщение отредактировал(а) baldina - 29.12.2010, 17:53
PM MAIL   Вверх
Skevalt
Дата 29.12.2010, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 30.11.2006

Репутация: нет
Всего: 3



Ура! Я античемпион!
PM MAIL   Вверх
mes
Дата 29.12.2010, 23:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Dov @  28.12.2010,  19:19 Найти цитируемый пост)
всё правильно показывает, так надо.  

ах да.. сорри.. запутался в трех соснах smile
но с нулем все равно надо быть осторожным..

Добавлено через 2 минуты и 24 секунды
baldina, не думал, что эта тема может сподвигнуть на подобные исследования smile





--------------------
PM MAIL WWW   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1666 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.