Comment puis-je vérifier si un nombre est un palindrome?

Comment vérifier si un nombre est un palindrome?

N'Importe quelle langue. N'importe quel algorithme. (sauf l'algorithme de faire du nombre une chaîne, puis inverser la chaîne).

117
demandé sur bjb568 2008-10-14 02:10:39

30 réponses

C'est l'un des problèmes du projet Euler. Quand je l'ai résolu dans Haskell, j'ai fait exactement ce que vous suggérez, convertir le nombre en une chaîne. Il est alors trivial de vérifier que la chaîne est un pallindrome. Si cela fonctionne assez bien, alors pourquoi prendre la peine de le rendre plus complexe? Être un pallindrome est une propriété lexicale plutôt que mathématique.

118
répondu Dan Dyer 2008-10-13 22:14:30

Pour un nombre donné:

 n = num;
 rev = 0;
 while (num > 0)
 {
      dig = num % 10;
      rev = rev * 10 + dig;
      num = num / 10;
 }

Si n == rev, puis num est un palindrome:

cout << "Number " << (n == rev ? "IS" : "IS NOT") << " a palindrome" << endl;
257
répondu Jorge Ferreira 2014-12-31 11:42:16
def ReverseNumber(n, partial=0):
    if n == 0:
        return partial
    return ReverseNumber(n // 10, partial * 10 + n % 10)

trial = 123454321    
if ReverseNumber(trial) == trial:
    print("It's a Palindrome!")

Fonctionne uniquement pour les entiers. Il n'est pas clair de l'énoncé du problème si des nombres à virgule flottante ou des zéros en tête doivent être pris en compte.

24
répondu Mark Ransom 2017-02-18 13:17:42

Au-dessus de la plupart des réponses ayant un problème trivial est que la variable int peut éventuellement déborder.

Se référer à http://leetcode.com/2012/01/palindrome-number.html

boolean isPalindrome(int x) {
    if (x < 0)
        return false;
    int div = 1;
    while (x / div >= 10) {
        div *= 10;
    }
    while (x != 0) {
        int l = x / div;
        int r = x % 10;
        if (l != r)
            return false;
        x = (x % div) / 10;
        div /= 100;
    }
    return true;
}
20
répondu Jiaji Li 2013-08-28 05:47:03
int is_palindrome(unsigned long orig)
{
  unsigned long reversed = 0, n = orig;

  while (n > 0)
  {
    reversed = reversed * 10 + n % 10;
    n /= 10;
  }

  return orig == reversed;
}
14
répondu Robert Gamble 2008-10-13 22:27:19

Poussez chaque chiffre individuel sur une pile, puis sautez-les. Si c'est le même avant et arrière, c'est un palindrome.

9
répondu Grant Limberg 2008-10-13 22:15:10

Je n'ai remarqué aucune réponse qui résolvait ce problème sans espace supplémentaire, c'est-à-dire que toutes les solutions que j'ai vues utilisaient une chaîne ou un autre entier pour inverser le nombre, ou d'autres structures de données.

Bien que des langages comme Java s'enroulent sur le débordement entier, ce comportement n'est pas défini dans des langages comme C. [ essayez d'Inverser 2147483647 (entier.MAX_VALUE) en Java ] La solution de contournement pourrait être d'utiliser un long ou quelque chose mais, stylistiquement, Je n'aime pas tout à fait ça approche.

Maintenant, le concept d'un nombre palindromique est que le nombre devrait se lire de la même manière en avant et en arrière. Grand. En utilisant ces informations, nous pouvons comparer le premier chiffre et le dernier chiffre. Astuce consiste, pour le premier chiffre, nous avons besoin de l'ordre du nombre. Dis, 12321. Diviser cela par 10000 nous obtiendrait le premier 1. La fuite 1 peut être récupérée en prenant le mod avec 10. Maintenant, pour réduire cela à 232. (12321 % 10000)/10 = (2321)/10 = 232. Et maintenant, le 10000 devrait être réduit d'un facteur 2. Donc, maintenant sur le code Java...

private static boolean isPalindrome(int n) {
    if (n < 0)
        return false;

    int div = 1;
    // find the divisor
    while (n / div >= 10)
        div *= 10;

    // any number less than 10 is a palindrome
    while (n != 0) {
        int leading = n / div;
        int trailing = n % 10;
        if (leading != trailing)
            return false;

        // % with div gets rid of leading digit
        // dividing result by 10 gets rid of trailing digit
        n = (n % div) / 10;

        // got rid of 2 numbers, update div accordingly
        div /= 100;
    }
    return true;
}

Édité selon la suggestion de Hardik pour couvrir les cas où il y a des zéros dans le nombre.

8
répondu Debosmit Ray 2018-04-28 13:40:46

Sauf en faisant du nombre une chaîne, puis en inversant la chaîne.

Pourquoi rejeter cette solution? Il est facile à mettre en œuvre et lisible . Si on vous demandait sans ordinateur à portée de main si 2**10-23 est un palindrome décimal, vous le testeriez sûrement en l'écrivant en décimal.

En Python au moins, le slogan 'les opérations de chaîne sont plus lentes que l'arithmétique' est en fait faux. J'ai comparé l'algorithme arithmétique de Smink à l'inversion de chaîne simple int(str(i)[::-1]). Il n'y a aucune différence significative de vitesse-il est arrivé que l'inversion de chaîne soit légèrement plus rapide.

Dans les langages de bas niveau (C/C++), le slogan peut contenir, mais on risque des erreurs de débordement avec de grands nombres.


def reverse(n):
    rev = 0
    while n > 0:
        rev = rev * 10 + n % 10
        n = n // 10
    return rev

upper = 10**6

def strung():
    for i in range(upper):
        int(str(i)[::-1])

def arithmetic():
    for i in range(upper):
        reverse(i)

import timeit
print "strung", timeit.timeit("strung()", setup="from __main__ import strung", number=1)
print "arithmetic", timeit.timeit("arithmetic()", setup="from __main__ import arithmetic", number=1)

Résultats en secondes (plus bas est meilleur):

Enfilées 1.50960231881
arithmétique 1.69729960569

5
répondu Colonel Panic 2012-11-11 18:29:42

En Python, il y a une manière rapide et itérative.

def reverse(n):
    newnum=0
    while n>0:
        newnum = newnum*10 + n % 10
        n//=10
    return newnum

def palindrome(n):
    return n == reverse(n)

Cela empêche également les problèmes de mémoire avec la récursivité (comme l'erreur StackOverflow en Java)

5
répondu ytpillai 2018-05-23 18:56:57

J'ai répondu au problème D'Euler en utilisant une manière très brutale. Naturellement, il y avait un algorithme beaucoup plus intelligent à l'affichage quand je suis arrivé au nouveau fil de forum associé déverrouillé. A savoir, un membre qui est passé par la poignée Begoner avait une telle approche nouvelle, que j'ai décidé de réimplémenter ma solution en utilisant son algorithme. Sa version était en Python (en utilisant des boucles imbriquées) et je l'ai réimplémenté dans Clojure (en utilisant une seule boucle/récurrence).

Ici, pour votre amusement:

(defn palindrome? [n]
  (let [len (count n)]
    (and
      (= (first n) (last n))
      (or (>= 1 (count n))
        (palindrome? (. n (substring 1 (dec len))))))))

(defn begoners-palindrome []
  (loop [mx 0
         mxI 0
         mxJ 0
         i 999
         j 990]
    (if (> i 100)
      (let [product (* i j)]
        (if (and (> product mx) (palindrome? (str product)))
          (recur product i j
            (if (> j 100) i (dec i))
            (if (> j 100) (- j 11) 990))
          (recur mx mxI mxJ
            (if (> j 100) i (dec i))
            (if (> j 100) (- j 11) 990))))
      mx)))

(time (prn (begoners-palindrome)))

Il y avait des Lisp répond aussi bien, mais ils étaient ungrokable pour moi.

4
répondu Chris Vest 2008-10-13 22:49:10

Juste pour le plaisir, celui-ci fonctionne également.

a = num;
b = 0;
while (a>=b)
{
  if (a == b) return true;
  b = 10 * b + a % 10;
  if (a == b) return true;
  a = a / 10;
}
return false;
4
répondu Toon Krijthe 2008-10-14 06:46:27

Voici une version Scheme qui construit une fonction qui fonctionnera sur n'importe quelle base. Il a un contrôle de redondance: retourner false rapidement si le nombre est un multiple de la base (se termine par 0). Et il ne reconstruit pas tout le nombre inversé, seulement la moitié. C'est tout ce dont nous avons besoin.

(define make-palindrome-tester
   (lambda (base)
     (lambda (n)
       (cond
         ((= 0 (modulo n base)) #f)
         (else
          (letrec
              ((Q (lambda (h t)
                    (cond
                      ((< h t) #f)
                      ((= h t) #t)
                      (else
                       (let* 
                           ((h2 (quotient h base))
                            (m  (- h (* h2 base))))
                         (cond 
                           ((= h2 t) #t)
                           (else
                            (Q h2 (+ (* base t) m))))))))))           
            (Q n 0)))))))
4
répondu z5h 2009-06-30 17:49:57

Le moyen le plus rapide que je connaisse:

bool is_pal(int n) {
  if (n % 10 == 0) return 0;
  int r = 0;
  while (r < n) {
    r = 10 * r + n % 10;
    n /= 10;
  }
  return n == r || n == r / 10;
}
4
répondu Flowers 2015-10-20 06:40:35

Golang version:

package main

import "fmt"

func main() {
    n := 123454321
    r := reverse(n)
    fmt.Println(r == n)
}

func reverse(n int) int {
    r := 0
    for {
        if n > 0 {
            r = r*10 + n%10         
            n = n / 10
        } else {
            break
        }
    }
    return r
}
3
répondu Thomas Modeneis 2015-08-12 08:02:24

Solution récursive dans ruby, sans convertir le nombre en chaîne

def palindrome?(x, a=x, b=0)
  return x==b if a<1
  palindrome?(x, a/10, b*10 + a%10)
end

palindrome?(55655)
3
répondu dre-hh 2016-03-04 10:38:31

Sautez les premier et dernier chiffres et comparez-les jusqu'à épuisement. Il peut y avoir un chiffre à gauche, ou non, mais de toute façon, si tous les chiffres sautés correspondent, c'est un palindrome.

2
répondu Eli 2008-10-13 22:30:20

Voici une solution de plus en c++ en utilisant des modèles . Cette solution fonctionnera pour la comparaison de chaînes palindrome insensible à la casse .

template <typename bidirection_iter>
bool palindrome(bidirection_iter first, bidirection_iter last)
{
    while(first != last && first != --last)
    {
        if(::toupper(*first) != ::toupper(*last))
            return false;
        else
            first++;
    }
    return true;
}
2
répondu VikramChopde 2014-07-13 10:19:50

Une méthode avec un facteur constant un peu meilleur que la méthode @sminks:

num=n
lastDigit=0;
rev=0;
while (num>rev) {
    lastDigit=num%10;
    rev=rev*10+lastDigit;
    num /=2;
}
if (num==rev) print PALINDROME; exit(0);
num=num*10+lastDigit; // This line is required as a number with odd number of bits will necessary end up being smaller even if it is a palindrome
if (num==rev) print PALINDROME
1
répondu eku 2011-08-02 05:24:10

Voici une version f#:

let reverseNumber n =
    let rec loop acc = function
    |0 -> acc
    |x -> loop (acc * 10 + x % 10) (x/10)    
    loop 0 n

let isPalindrome = function
    | x  when x = reverseNumber x -> true
    | _ -> false
1
répondu Omu 2012-05-04 15:55:00

Un nombre est palindromique si sa représentation de chaîne est palindromique:

def is_palindrome(s):
    return all(s[i] == s[-(i + 1)] for i in range(len(s)//2))

def number_palindrome(n):
    return is_palindrome(str(n))
1
répondu hughdbrown 2012-07-06 17:59:26
def palindrome(n):
    d = []
    while (n > 0):
        d.append(n % 10)
        n //= 10
    for i in range(len(d)/2):
        if (d[i] != d[-(i+1)]):
            return "Fail."
    return "Pass."
1
répondu Rock 2013-02-01 05:37:30

Pour vérifier le nombre donné est Palindrome ou non (code Java)

class CheckPalindrome{
public static void main(String str[]){
        int a=242, n=a, b=a, rev=0;
        while(n>0){
                    a=n%10;  n=n/10;rev=rev*10+a;
                    System.out.println(a+"  "+n+"  "+rev);  // to see the logic
               }
        if(rev==b)  System.out.println("Palindrome");
        else        System.out.println("Not Palindrome");
    }
}
1
répondu sort_01out 2014-06-03 14:47:53

Beaucoup de solutions affichées ici inversent l'entier et le stockent dans une variable qui utilise un espace supplémentaire qui est O(n), Mais voici une solution avec O(1) Espace.

def isPalindrome(num):
    if num < 0:
        return False
    if num == 0:
        return True
    from math import log10
    length = int(log10(num))
    while length > 0:
        right = num % 10
        left = num / 10**length
        if right != left:
            return False
        num %= 10**length
        num /= 10
        length -= 2
    return True
1
répondu Sunny Raj 2015-03-05 21:57:50

J'utilise toujours Cette solution python en raison de sa compacité.

def isPalindrome(number):
    return int(str(number)[::-1])==number
1
répondu user2343020 2015-03-18 14:52:35

Essayez ceci:

reverse = 0;
    remainder = 0;
    count = 0;
    while (number > reverse)
    {
        remainder = number % 10;
        reverse = reverse * 10 + remainder;
        number = number / 10;
        count++;
    }
    Console.WriteLine(count);
    if (reverse == number)
    {
        Console.WriteLine("Your number is a palindrome");
    }
    else
    {
        number = number * 10 + remainder;
        if (reverse == number)
            Console.WriteLine("your number is a palindrome");
        else
            Console.WriteLine("your number is not a palindrome");
    }
    Console.ReadLine();
}
}
0
répondu vivek 2013-02-13 04:27:22

Voici une solution utilisant des listes comme piles en python:

def isPalindromicNum(n):
    """
        is 'n' a palindromic number?
    """
    ns = list(str(n))
    for n in ns:
        if n != ns.pop():
            return False
    return True

Popping la pile ne considère que le côté le plus à droite du nombre pour la comparaison et il échoue rapidement pour réduire les contrôles

0
répondu lwm 2013-06-29 19:54:13
 public class Numbers
 {
   public static void main(int givenNum)
   { 
       int n= givenNum
       int rev=0;

       while(n>0)
       {
          //To extract the last digit
          int digit=n%10;

          //To store it in reverse
          rev=(rev*10)+digit;

          //To throw the last digit
          n=n/10;
      }

      //To check if a number is palindrome or not
      if(rev==givenNum)
      { 
         System.out.println(givenNum+"is a palindrome ");
      }
      else
      {
         System.out.pritnln(givenNum+"is not a palindrome");
      }
  }
}
0
répondu BLaaaaaa 2013-07-21 05:53:12
let isPalindrome (n:int) =
   let l1 = n.ToString() |> List.ofSeq |> List.rev
   let rec isPalindromeInt l1 l2 =
       match (l1,l2) with
       | (h1::rest1,h2::rest2) -> if (h1 = h2) then isPalindromeInt rest1 rest2 else false
       | _ -> true
   isPalindromeInt l1 (n.ToString() |> List.ofSeq)
0
répondu mario 2013-09-17 19:24:32
checkPalindrome(int number)
{
    int lsd, msd,len;
    len = log10(number);
    while(number)
    {
        msd = (number/pow(10,len)); // "most significant digit"
        lsd = number%10; // "least significant digit"
        if(lsd==msd)
        {
            number/=10; // change of LSD
            number-=msd*pow(10,--len); // change of MSD, due to change of MSD
            len-=1; // due to change in LSD
            } else {return 1;}
    }
    return 0;
}
0
répondu MarianG 2013-10-02 09:02:50

Manière récursive, pas très efficace, il suffit de fournir une option

(code Python)

def isPalindrome(num):
    size = len(str(num))
    demoninator = 10**(size-1)
    return isPalindromeHelper(num, size, demoninator)

def isPalindromeHelper(num, size, demoninator):
    """wrapper function, used in recursive"""
    if size <=1:
        return True
    else:       
        if num/demoninator != num%10:
            return False
        # shrink the size, num and denominator
        num %= demoninator
        num /= 10
        size -= 2
        demoninator /=100
        return isPalindromeHelper(num, size, demoninator) 
0
répondu user1552891 2013-11-21 23:58:01