अगर कोई नंबर एक पैलिंड्रोम है तो मैं कैसे जांचूं?


127

अगर कोई नंबर एक पैलिंड्रोम है तो मैं कैसे जांचूं?

कोई भी भाषा। कोई एल्गोरिथ्म। (संख्या को एक स्ट्रिंग बनाने के एल्गोरिथ्म को छोड़कर और फिर स्ट्रिंग को उल्टा करना)।


5
क्या आप बिट्स में पूर्णांक के आकार का पता लगा सकते हैं? यदि हाँ, कहो तो A नहीं है और s का आकार B = A << s / 2 है यदि A & B == 2 ^ s-1 - 2 ^ (s / 2) + 1
नितिन गर्ग

10
'नंबर को एक स्ट्रिंग बनाने और फिर स्ट्रिंग को उलटने' में क्या गलत है?
कर्नल पैनिक

इस संदर्भ में क्या numberऔर क्या is a palindromeहोगा, इसे परिभाषित करके शुरू करें : 13E31 (आधार दस) के बारे में कैसे? 01210 (अग्रणी शून्य)? + १०-१० + १ (पांच अंक संतुलित त्रिगुट)?
ग्रेबर्ड

जवाबों:


128

यह प्रोजेक्ट यूलर समस्याओं में से एक है । जब मैंने इसे हास्केल में हल किया तो मैंने वही किया जो आप सुझाव देते हैं, संख्या को स्ट्रिंग में परिवर्तित करें। फिर यह जांचना तुच्छ है कि स्ट्रिंग एक पैलिंड्रोम है। यदि यह पर्याप्त रूप से अच्छा प्रदर्शन करता है, तो इसे और अधिक जटिल बनाने से क्यों परेशान होता है? पैलिंड्रोम होना एक गणितीय के बजाय एक शाब्दिक गुण है।


14
वास्तव में। आपके द्वारा किए गए किसी भी एल्गोरिदम को कम से कम संख्या को आधार -10 अंकों में विभाजित करना होगा, जो कि वैसे भी एक स्ट्रिंग में 90% परिवर्तित होता है।
Blorgbeard

5
यह निश्चित रूप से एक स्ट्रिंग में बदलने के लिए एक साफ-सुथरी चाल है, लेकिन यह इस तरह की हार को इंगित करता है यदि आपसे यह एक साक्षात्कार पर पूछा गया क्योंकि बिंदु यह निर्धारित करने के लिए होगा कि क्या आप मोडुलो को समझते हैं।
रॉबर्ट Noack

7
@ रोबर्ट नैक - साक्षात्कारकर्ता तब एक पूर्णांक को एक स्ट्रिंग में बदलने के लिए एक एल्गोरिथ्म का वर्णन करने के लिए कह सकता है, जो आपको मॉडुलो को समझने के लिए निश्चित रूप से आवश्यक है।
स्टीव

@ स्टीव ३१४ to describe an algorithm to convert an integer to a string, which of course requires you to understand modulo- नहीं। लक्ष्य संख्या प्रणाली में कम्प्यूटिंग, जोड़ने में सक्षम होगा (यह सोचें कि आप आमतौर पर दशमलव से द्विआधारी में कैसे परिवर्तित होते हैं - गणना सोचने के लिए उपयोग किए जाने का अर्थ है द्विआधारी का मतलब यह नहीं है कि आप ऐसा नहीं कर सकते, जैसे, दशमलव अंकगणित (और आप कर सकते हैं) विभाजन या मॉडुलो 2 के बिना बाइनरी से दशमलव में रूपांतरण)।
ग्रेबियर्ड

@ ग्रेबियर - मैं मान रहा हूं कि अंकगणित उस प्रकार पर किया जाता है जो अंकगणित का समर्थन करता है और स्ट्रिंग ऑपरेशन उस प्रकार पर किया जाता है जो स्ट्रिंग संचालन का समर्थन करता है - जो कि पूर्णांक के लिए विभाजन और मोडुलो / शेष है और स्ट्रिंग के लिए वर्णों को प्रस्तुत करता है। बेशक आप अपने लिए स्ट्रिंग्स पर अंकगणित को लागू कर सकते हैं , लेकिन (1) क्या आप वास्तव में जा रहे हैं? बस एक पूर्णांक को एक स्ट्रिंग में बदलने के लिए ?, (2) हालांकि आप इसे (अक्षम रूप से) इसके बिना संभाल सकते हैं, आपको कुछ बिंदुओं पर समझने की आवश्यकता होगी - आपके पास इसके बिना तार पर पूर्ण पूर्णांक अंकगणित नहीं है।
स्टीव 314

269

किसी भी दिए गए नंबर के लिए:

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

तो n == revफिर numविलोमपद:

cout << "Number " << (n == rev ? "IS" : "IS NOT") << " a palindrome" << endl;

कि मैं क्या w / भी आया था मुझे लगता है कि मेरे लिए अब इसे पोस्ट करने में कोई अर्थ नहीं है। +1
एस्टेबन अरया

क्या यह मान लिया गया है कि रिवीजन शून्य के लिए आरंभिक है?
जस्टाल्ट

हाँ जस्टसाल्ट। रिवाइज वैरिएबल को शून्य पर आरंभीकृत किया जाता है।
जॉर्ज फरेरा

31
राहगीरों के लिए ध्यान दें: यदि इसे उस भाषा में लागू करना है जो numविभाजन के बाद के आंशिक भाग को बनाए रखेगा (शिथिल टाइपिंग), तो आपको इसे बनाने की आवश्यकता होगी num = floor(num / 10)
वाइजग्यू

22
यह समाधान पूरी तरह से सही नहीं है। चर खुदाई संभवतः अतिप्रवाह हो सकती है। उदाहरण के लिए, मुझे लगता है कि संख्या का प्रकार अंतर है, मान लगभग Integer.Max है, इसका अंतिम अंक 789 है, जब रिवर्स खुदाई, फिर अतिप्रवाह।
जियाजी ली

24
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!")

पूर्णांकों के लिए ही काम करता है। समस्या कथन से यह स्पष्ट नहीं है कि फ्लोटिंग पॉइंट नंबर या अग्रणी शून्य पर विचार करने की आवश्यकता है।


22

एक तुच्छ समस्या के अधिकांश उत्तरों के ऊपर यह है कि संभवतया अंतर चर अतिप्रवाह हो सकता है।

का संदर्भ लें http://articles.leetcode.com/palindrome-number/

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;
}

विफल हो जाएगा जब संख्याओं में शून्य है। उदाहरण: 10000021.
विराज


9

एक स्टैक पर प्रत्येक व्यक्तिगत अंक को पुश करें, फिर उन्हें पॉप ऑफ करें। यदि यह आगे और पीछे एक ही है, तो यह एक ताल है।


आप पूर्णांक से प्रत्येक व्यक्तिगत अंक को कैसे धक्का देते हैं?
एस्टेबन अराया

1
की तर्ज पर कुछ: int firstDigit = originalNumber% 10; int tmpNumber = originalNumber / 10; int secondDigit = tmpNumber% 10; .... जब तक आप कर रहे हैं।
ग्रांट लिम्बर्ग

यह LeetCode प्रश्न के संदर्भ में काम नहीं करेगा - अतिरिक्त स्थान की अनुमति नहीं है।
होलोग्राम

8

मैंने बिना किसी अतिरिक्त स्थान का उपयोग किए, इस समस्या को हल करने वाले किसी भी उत्तर पर ध्यान नहीं दिया, अर्थात, मेरे द्वारा देखे गए सभी समाधानों में संख्या को उलटने के लिए एक स्ट्रिंग, या किसी अन्य पूर्णांक का उपयोग किया गया, या कुछ अन्य डेटा संरचनाएँ।

हालाँकि जावा जैसी भाषाएँ पूर्णांक ओवरफ़्लो पर चारों ओर लिपटी रहती हैं, लेकिन यह व्यवहार सी जैसी भाषाओं में अपरिभाषित है (Java में 2147483647 (Integer.MAX_VALUE) को उलट
कर देखें ) वर्कअराउंड लंबे या कुछ और का उपयोग करने के लिए हो सकता है लेकिन, शैलीगत रूप से, मैं काफी नहीं हूं उस दृष्टिकोण की तरह।

अब, एक palindromic संख्या की अवधारणा यह है कि संख्या को आगे और पीछे एक ही पढ़ना चाहिए। महान। इस जानकारी का उपयोग करके, हम पहले अंक और अंतिम अंक की तुलना कर सकते हैं। ट्रिक है, पहले अंक के लिए, हमें संख्या के क्रम की आवश्यकता है। कहते हैं, 12321। इसे 10000 से विभाजित करने पर हमें अग्रणी 1 मिलेगा। ट्रेलिंग 1 को मॉड के साथ 10. प्राप्त करके इसे 232 तक कम करने के लिए पुनः प्राप्त किया जा सकता है (12321 % 10000)/10 = (2321)/10 = 232। और अब, 10000 को 2 के कारक से कम करना होगा। इसलिए, अब जावा कोड पर ...

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;
}

उन मामलों को कवर करने के लिए हार्दिक के सुझाव के अनुसार संपादित किया गया जहां संख्या में शून्य हैं।


6

पायथन में, एक तेज़, पुनरावृत्त तरीका है।

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

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

यह पुनरावृत्ति के साथ स्मृति समस्याओं को भी रोकता है (जैसे जावा में StackOverflow त्रुटि)


बंद करें, लेकिन आप ऐसा करते समय n को म्यूट कर रहे हैं। आप मूल n मान को संग्रहीत करना चाहते हैं और रिटर्न की तुलना इसके बजाय करते हैं
RGroppa

6

सबसे तेज़ तरीका मुझे पता है:

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;
}

120 (दशमलव) एक "दशमलव पैलिंड्रोम" है? अविश्वसनीय रूप से तेजी से, और eku के जवाब के समान ।
ग्रेबर्ड

5

सिर्फ मनोरंजन के लिए, यह भी काम करता है।

a = num;
b = 0;
if (a % 10 == 0)
  return a == 0;
do {
  b = 10 * b + a % 10;
  if (a == b)
    return true;
  a = a / 10;
} while (a > b);
return a == b;

5

संख्या को एक स्ट्रिंग बनाने के अलावा और फिर स्ट्रिंग को पीछे करना।

उस समाधान को क्यों खारिज करें? इसे लागू करना और पठनीय करना आसान है । यदि आपसे पूछा जाए कि कोई ऐसा कंप्यूटर नहीं 2**10-23है, जो दशमलव पैलिंड्रोम हो, तो आप निश्चित रूप से इसे दशमलव में लिखकर परीक्षण करेंगे।

कम से कम पाइथन में, 'स्ट्रिंग ऑपरेशंस अंकगणित की तुलना में धीमी हैं' वास्तव में गलत है। मैंने स्मिंक के अंकगणितीय एल्गोरिथ्म की तुलना साधारण स्ट्रिंग रिवर्सल से की int(str(i)[::-1])। गति में कोई महत्वपूर्ण अंतर नहीं था - ऐसा हुआ कि स्ट्रिंग रिवर्सल मामूली रूप से तेज था।

संकलित भाषाओं (C / C ++) में नारा पकड़ में आ सकता है, लेकिन एक जोखिम बड़ी संख्या के साथ त्रुटियों को ओवरफ्लो करता है।

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)

सेकंड में परिणाम (कम बेहतर है):

स्ट्रोंग 1.50960231881 अंकगणित 1.69729960569


4

मैंने बहुत क्रूरतापूर्ण तरीके से ईलर समस्या का जवाब दिया। स्वाभाविक रूप से, जब मैं नए अनलॉक किए गए संबद्ध फ़ोरम थ्रेड के लिए मिला तो प्रदर्शन में बहुत अधिक स्मार्ट एल्गोरिथ्म था। अर्थात्, एक सदस्य जो हैंडल बेगनर के पास गया था, उसके पास ऐसा उपन्यास दृष्टिकोण था, जिसे मैंने अपने एल्गोरिदम का उपयोग करके अपने समाधान को फिर से लागू करने का निर्णय लिया। उसका संस्करण पायथन (नेस्टेड लूप्स का उपयोग करके) में था और मैंने इसे क्लोजर (एक लूप / रिकूर ​​का उपयोग करके) में फिर से लागू किया।

यहाँ आपके मनोरंजन के लिए:

(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)))

सामान्य लिस्प उत्तर भी थे, लेकिन वे मेरे लिए असहनीय थे।


1
मैंने यहां पोस्ट किए गए कुछ "गणितीय" पैलिंड्रोम परीक्षणों की कोशिश की, लेकिन आश्चर्यचकित था कि यह स्ट्रिंग आधारित संस्करण सबसे तेज था।
क्रिस वेस्ट

शायद यह आश्चर्य की बात नहीं होनी चाहिए - आखिरकार, आप जिस संख्या को महसूस कर सकते हैं वह सबसे तेज़ तरीका है जो आपको दिया गया था, जो पहले आधा भाग था, फिर दूसरी छमाही को पढ़ना, किसी भी प्रकार का अंकगणित नहीं करना
ज़ुबिन मुखर्जी

4

यहां एक योजना संस्करण है जो एक फ़ंक्शन का निर्माण करता है जो किसी भी आधार के खिलाफ काम करेगा। इसकी अतिरेक जांच होती है: यदि संख्या आधार का एक से अधिक है (तो 0 में समाप्त होता है) झूठा वापस लौटें।
और यह पूरी उलटी संख्या का पुनर्निर्माण नहीं करता है, केवल आधा।
बस इतना ही चाहिए।

(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

माणिक में पुनरावर्ती समाधान, स्ट्रिंग को संख्या में परिवर्तित किए बिना।

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

गोलंग संस्करण:

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
}

2

पहले और अंतिम अंकों को बंद करें और जब तक आप बाहर नहीं निकलते हैं, तब तक उनकी तुलना करें। वहाँ एक अंक छोड़ दिया जा सकता है, या नहीं, लेकिन किसी भी तरह से, अगर सभी पॉपिंग अंक अंकों से मेल खाते हैं, तो यह एक ताल है।


2

यहाँ टेम्पलेट का उपयोग करके c ++ में एक और समाधान है। यह समाधान केस असंवेदनशील पैलिंड्रोम स्ट्रिंग तुलना के लिए काम करेगा।

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;
}

1

@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

यहाँ पर # संस्करण है:

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

यदि स्ट्रिंग का प्रतिनिधित्व पैलिंड्रोमिक है, तो एक संख्या पलिंडोमिक है:

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
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

दिए गए नंबर की जाँच करने के लिए Palindrome है या नहीं (Java Code)

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

यहां पोस्ट किए गए बहुत सारे समाधान पूर्णांक को उलट देते हैं और इसे एक चर में संग्रहीत करते हैं जो अतिरिक्त स्थान का उपयोग करता है जो कि है O(n), लेकिन यहां O(1)अंतरिक्ष से एक समाधान है।

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

मैं हमेशा इस कॉम्पैक्ट समाधान का उपयोग इसकी कॉम्पैक्टनेस के कारण करता हूं।

def isPalindrome(number):
    return int(str(number)[::-1])==number

4
यह कॉम्पैक्ट है, लेकिन ओपी ने विशेष रूप से कहा " संख्या को एक स्ट्रिंग बनाने की एल्गोरिथ्म को छोड़कर और फिर स्ट्रिंग को उल्टा करना "
एडवर्ड

0

इसे इस्तेमाल करे:

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

यहाँ अजगर में ढेर के रूप में एक समाधान usings सूची है:

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

स्टैक को पॉप करना केवल तुलना के लिए संख्या का सही पक्ष मानता है और यह चेक को कम करने में तेजी से विफल होता है


0
 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
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
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;
}

बुरा, बुरा हल। Log10 एक बहुत ही धीमा, फ्लोटिंग-पॉइंट ऑपरेशन है। इसका उपयोग न करें।
रोक क्रलज

0

पुनरावर्ती तरीका, बहुत कुशल नहीं, बस एक विकल्प प्रदान करें

(पायथन कोड)

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) 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.