숫자가 회문인지 어떻게 확인합니까?
모든 언어. 모든 알고리즘. (숫자를 문자열로 만든 다음 문자열을 되 돌리는 알고리즘 제외).
number
및 is a palindrome
방법 13E31에 대한 (기본 열을) :이 상황에서 의미한다? 01210 (제로 0)? + 10-10 + 1 (5 자리 균형 삼항)?
숫자가 회문인지 어떻게 확인합니까?
모든 언어. 모든 알고리즘. (숫자를 문자열로 만든 다음 문자열을 되 돌리는 알고리즘 제외).
number
및 is a palindrome
방법 13E31에 대한 (기본 열을) :이 상황에서 의미한다? 01210 (제로 0)? + 10-10 + 1 (5 자리 균형 삼항)?
답변:
이것은 프로젝트 오일러 문제 중 하나입니다 . Haskell에서 해결했을 때 정확히 제안한대로 숫자를 문자열로 변환하십시오. 문자열이 pallindrome인지 확인하는 것은 사소한 일입니다. 성능이 충분하다면 왜 더 복잡하게 만드는가? pallindrome이된다는 것은 수학적인 것이 아니라 어휘 적 속성입니다.
to describe an algorithm to convert an integer to a string, which of course requires you to understand modulo
아뇨. 당신이 일반적 이진 진수로 변환하는 방법을 생각하는 (할 것입니다 추가 할 수있는 대상 번호 시스템에서 계산하는 것은 - 생각하는 데 사용되는 계산 수단 바이너리 , 당신이 할 수없는 것은 예를 들면,하지 않는 소수 연산 (당신은 할 수 할 나누기 또는 모듈로없이 2 진수에서 10 진수로 변환 2)
주어진 숫자에 대해 :
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;
num
나누기 후의 부분을 유지하는 언어로 언어를 구현하는 경우 (루터 타이핑) 그렇게해야합니다 num = floor(num / 10)
.
사소한 문제가있는 대부분의 대답은 int 변수가 오버플로 될 수 있다는 것입니다.
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;
}
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;
}
각 개별 숫자를 스택으로 밀고 튀어 나옵니다. 앞뒤로 같은 경우 회문입니다.
여분의 공간을 사용하지 않고이 문제를 해결 한 답변을 보지 못했습니다. 즉, 문자열이나 다른 정수를 사용하여 숫자를 바꾸거나 다른 데이터 구조를 사용하는 모든 솔루션을 보았습니다.
자바와 같은 언어는 정수 오버 플로우에 랩 어라운드 있지만,이 동작은 C. 같은 언어 (에 정의되지 자바 2147483647 (는 Integer.MAX_VALUE를) 반전 시도 )
해결 방법 문체, 꽤하지 않습니다, 긴 또는 무언가를 사용할 수 있지만, 할 수있다 그 접근법처럼.
회문 숫자의 개념은 숫자가 앞뒤로 동일하게 읽혀 져야한다는 것입니다. 큰. 이 정보를 사용하여 첫 번째 숫자와 마지막 숫자를 비교할 수 있습니다. 트릭은 첫 번째 숫자의 경우 순서가 필요합니다. 이것을 12321이라고 말하십시오. 이것을 10000으로 나누면 1을 얻을 수 있습니다. 후행 1은 10으로 mod를 가져 와서 검색 할 수 있습니다. 이제 이것을 232로 줄 (12321 % 10000)/10 = (2321)/10 = 232
입니다. 이제 10000을 2 배로 줄여야합니다. 이제 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;
}
숫자가 0 인 경우를 다루기 위해 Hardik 의 제안에 따라 편집했습니다 .
파이썬에는 빠르고 반복적 인 방법이 있습니다.
def reverse(n):
newnum=0
while n>0:
newnum = newnum*10 + n % 10
n//=10
return newnum
def palindrome(n):
return n == reverse(n)
또한 재귀와 관련된 메모리 문제를 방지합니다 (예 : Java의 StackOverflow 오류)
내가 아는 가장 빠른 방법 :
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;
}
숫자를 문자열로 만든 다음 문자열을 되 돌리는 것을 제외하고.
왜 그 해결책을 무시합니까? 쉽게 구현하고 읽을 수 있습니다. 컴퓨터가 없어도 2**10-23
십진 회문 인지 묻는다면 십진법으로 그것을 작성하여 테스트해야합니다.
파이썬에서 적어도 '문자열 연산이 산술보다 느리다'라는 슬로건은 실제로 거짓입니다. Smink의 산술 알고리즘을 간단한 문자열 반전과 비교했습니다 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
나는 매우 무자비한 방법으로 오일러 문제에 답했다. 당연히, 새로운 잠금 해제 관련 포럼 스레드에 도착했을 때 훨씬 더 똑똑한 알고리즘이 표시되었습니다. 즉, Begoner 핸들을 지나간 멤버는 참신한 접근 방식을 사용하여 알고리즘을 사용하여 솔루션을 다시 구현하기로 결정했습니다. 그의 버전은 Python (중첩 루프 사용)이고 Clojure (단일 루프 / 반복 사용)로 다시 구현했습니다.
여기 당신의 즐거움을 위해 :
(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)))
Common Lisp 답변도 있었지만 나에게 확고하지 못했습니다.
다음은 모든 기본에 대해 작동하는 함수를 구성하는 구성표 버전입니다. 중복 검사 기능이 있습니다. 숫자가 기수의 배수이면 신속하게 false를 반환합니다 (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)))))))
다음은 템플릿을 사용하는 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;
}
@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
주어진 숫자가 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");
}
}
여기에 게시 된 많은 솔루션은 정수를 뒤집어 추가 공간 인을 사용하는 변수에 저장 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
나는 컴팩트하기 때문에 항상이 파이썬 솔루션을 사용합니다.
def isPalindrome(number):
return int(str(number)[::-1])==number
이 시도:
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();
}
}
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");
}
}
}
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;
}
매우 효율적이지 않은 재귀 방식은 옵션을 제공합니다.
(파이썬 코드)
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)