番号が回文かどうかを確認するにはどうすればよいですか?
どんな言語でも。任意のアルゴリズム。(数値を文字列にしてから文字列を逆にするアルゴリズムを除く)。
number
をis a palindrome
意味し、何を意味するかから開始します。13E31(10進法)はどうですか?01210(先行ゼロ)?+ 10-10 + 1(5桁のバランスの取れた3値)?
番号が回文かどうかを確認するにはどうすればよいですか?
どんな言語でも。任意のアルゴリズム。(数値を文字列にしてから文字列を逆にするアルゴリズムを除く)。
number
をis a palindrome
意味し、何を意味するかから開始します。13E31(10進法)はどうですか?01210(先行ゼロ)?+ 10-10 + 1(5桁のバランスの取れた3値)?
回答:
これは、プロジェクトオイラー問題の1つです。私がHaskellでそれを解決したとき、あなたが提案したとおりに、数値を文字列に変換しました。次に、文字列が回文であることを確認するのは簡単です。それが十分に機能する場合、なぜわざわざ複雑にするのですか?回文であることは、数学的なものではなく、語彙的な特性です。
to describe an algorithm to convert an integer to a string, which of course requires you to understand modulo
いいえ。考えるために使用されている-あなたは、一般的に10進数からバイナリに変換する方法を考える(、目標数のシステムで計算を追加することができることでしょうバイナリ計算手段あなたが行うことができないという意味ではありませんが、例えば、10進法計算(とあなたがすることができません除算または2を法としない2進数から10進数への変換)
任意の数について:
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;
}
個々の数字をスタックにプッシュしてから、ポップします。それが前と後ろで同じなら、それは回文です。
余分なスペースを使用せずにこの問題を解決した答えに気付きませんでした。つまり、私が見たすべてのソリューションは、文字列または別の整数を使用して数値を反転したり、その他のデータ構造を使用していました。
Javaのような言語は、整数オーバーフローの上にラップアラウンドが、この動作はC.のような言語(で定義されていないJavaで2147483647(Integer.MAX_VALUEの)を反転してください)
回避策は、文体、私はかなりない、長いか何かを使用することだけに可能性そのアプローチのように。
現在、回文番号の概念は、その番号を同じように前方と後方に読む必要があるということです。すごい。この情報を使用して、最初の桁と最後の桁を比較できます。トリックは、最初の桁のために、私たちは数の順序が必要です。12321と言います。これを10000で割ると、先頭が1になります。末尾の1は、modを10にすると取得できます(12321 % 10000)/10 = (2321)/10 = 232
。これを232に減らします。そして今、10000を2分の1に減らす必要があります。それでは、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;
}
私が知っている最速の方法:
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
10進数のパリンドロームであるかどうかを手元にないコンピューターで尋ねられた場合は、10進数で書き出すことで確実にテストします。
少なくともPythonでは、「文字列操作は算術よりも遅い」というスローガンは実際には誤りです。スミンクの算術アルゴリズムを単純な文字列反転と比較しました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の回答もありましたが、それらは私には理解できませんでした。
これは、どのベースに対しても機能する関数を構築するSchemeバージョンです。冗長性チェックがあります。数値が基数の倍数(0で終わる)の場合、すばやくfalseを返します。
そして、それは全体の逆数を再構築するのではなく、半分だけです。
それだけで十分です。
(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)))))))
Golangバージョン:
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
}
テンプレートを使用したc ++のもう1つのソリューションを次に示します。このソリューションは、大文字と小文字を区別しない回文の文字列比較で機能します。
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
指定された番号をチェックするのが回文かどうか(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");
}
}
ここに投稿されたソリューションの多くは、整数を逆にして、に余分なスペースを使用する変数に格納し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
そのコンパクトさのため、私は常にこのpythonソリューションを使用しています。
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;
}
再帰的な方法、あまり効率的ではなく、オプションを提供するだけ
(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)