Как проверить, является ли число палиндромом?
Любой язык. Любой алгоритм. (кроме алгоритма преобразования числа в строку и последующего обращения строки).
Как проверить, является ли число палиндромом?
Любой язык. Любой алгоритм. (кроме алгоритма преобразования числа в строку и последующего обращения строки).
Это одна из задач Project Euler. Когда я решил это в Haskell, я сделал именно то, что вы предлагаете, преобразовал число в строку. Затем тривиально проверить, что строка является паллиндромом. Если он работает достаточно хорошо, то зачем усложнять его? Быть паллиндромом - это лексическое свойство, а не математическое.
to describe an algorithm to convert an integer to a string, which of course requires you to understand modulo
- нет. Вычисления в целевой системе счисления, возможность сложения подойдет (подумайте, как вы обычно конвертируете из десятичной системы в двоичную - привыкли думать, что вычисления означают двоичную систему, не означает, что вы не можете сделать, например, десятичная арифметика (и вы можете выполнять преобразование из двоичного в десятичное без деления или по модулю 2).
- person greybeard; 17.10.2016
Для любого заданного числа:
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)
.
- person Wiseguy; 21.05.2012
rev1
может переполниться. Рассмотрим ввод num = 2147483647
- person Arun; 28.04.2017
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!")
Работает только для целых чисел. Из постановки задачи неясно, нужно ли учитывать числа с плавающей запятой или начальные нули.
Выше большинства ответов, имеющих тривиальную проблему, является то, что переменная int может переполниться.
См. https://web.archive.org/web/20180222083908/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;
}
Поместите каждую отдельную цифру в стопку, а затем извлеките их. Если это то же самое вперед и назад, это палиндром.
Я не заметил никаких ответов, которые решали бы эту проблему без дополнительного пробела, т. Е. Все решения, которые я видел, использовали либо строку, либо другое целое число для обращения числа, либо какие-то другие структуры данных.
Несмотря на то, что такие языки, как Java, перекрывают целочисленное переполнение, это поведение не определено в таких языках, как C. (Попробуйте обратить 2147483647 (Integer.MAX_VALUE) в Java)
Обходным решением может быть использование длинного или что-то, но стилистически мне такой подход не совсем нравится.
Теперь концепция палиндромного числа заключается в том, что число должно читаться одинаково вперед и назад. Здорово. Используя эту информацию, мы можем сравнить первую цифру и последнюю цифру. Хитрость в том, что для первой цифры нам нужен порядок числа. Скажем, 12321. Разделив это на 10000, мы получим ведущую 1. Конечную 1 можно получить, взяв мод с 10. Теперь, чтобы уменьшить это до 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;
}
Отредактировано в соответствии с предложением Хардика, чтобы охватить случаи, когда в числе есть нули.
Самый быстрый способ, который я знаю:
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;
}
В Python есть быстрый итеративный способ.
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 в Java).
Просто для удовольствия, это тоже работает.
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;
за исключением того, что число становится строкой, а затем переворачивается строка.
Зачем отказываться от этого решения? Это просто реализовать и легко читать. Если бы вас спросили, не имея под рукой компьютера, является ли 2**10-23
десятичным палиндромом, вы бы наверняка проверили его, записав его в десятичной форме.
По крайней мере, в 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, но мне они были непонятны.
Вот версия схемы, которая создает функцию, которая будет работать с любой базой. У него есть проверка на избыточность: быстро вернуть 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)))))))
Рекурсивное решение на рубине без преобразования числа в строку.
def palindrome?(x, a=x, b=0)
return x==b if a<1
palindrome?(x, a/10, b*10 + a%10)
end
palindrome?(55655)
Голанг версия:
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
}
Выталкивайте первую и последнюю цифры и сравнивайте их, пока не закончатся. Может остаться цифра или нет, но в любом случае, если все выскочившие цифры совпадают, это палиндром.
Вот еще одно решение на С++ с использованием шаблонов. Это решение будет работать для сравнения строки палиндрома без учета регистра.
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
вот версия 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
Число является палиндромным, если его строковое представление является палиндромным:
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))
Чтобы проверить, является ли данный номер палиндромом или нет (код 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();
}
}
Вот решение, использующее списки как стеки в 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
при извлечении из стека для сравнения учитывается только крайняя правая часть числа, и быстро не удается уменьшить количество проверок
Рекурсивный способ, не очень эффективный, просто укажите вариант
(код 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)
кажется, что проще всего было бы найти противоположное число и сравнить два:
int max =(int)(Math.random()*100001);
int i;
int num = max; //a var used in the tests
int size; //the number of digits in the original number
int opos = 0; // the oposite number
int nsize = 1;
System.out.println(max);
for(i = 1; num>10; i++)
{
num = num/10;
}
System.out.println("this number has "+i+" digits");
size = i; //setting the digit number to a var for later use
num = max;
for(i=1;i<size;i++)
{
nsize *=10;
}
while(num>1)
{
opos += (num%10)*nsize;
num/=10;
nsize/=10;
}
System.out.println("and the number backwards is "+opos);
if (opos == max )
{
System.out.println("palindrome!!");
}
else
{
System.out.println("aint no palindrome!");
}
Попробуй это:
print('!* To Find Palindrome Number')
def Palindrome_Number():
n = input('Enter Number to check for palindromee')
m=n
a = 0
while(m!=0):
a = m % 10 + a * 10
m = m / 10
if( n == a):
print('%d is a palindrome number' %n)
else:
print('%d is not a palindrome number' %n)
просто перезвоните функции
Вот способ.
class Palindrome_Number{
void display(int a){
int count=0;
int n=a;
int n1=a;
while(a>0){
count++;
a=a/10;
}
double b=0.0d;
while(n>0){
b+=(n%10)*(Math.pow(10,count-1));
count--;
n=n/10;
}
if(b==(double)n1){
System.out.println("Palindrome number");
}
else{
System.out.println("Not a palindrome number");
}
}
}
Я использовал обычный подход, преобразовав число в строку, а затем преобразовав строку в charArray. Проходим через charArray и находим, равны ли числа в позициях или нет. Примечание. Не переворачивать строку.
public bool IsPalindrome(int num)
{
string st = num.ToString();
char[] arr = st.ToCharArray();
int len = arr.Length;
if (len <= 1)
{
return false;
}
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] == arr[len - 1])
{
if (i >= len)
{
return true;
}
len--;
}
else
{
break;
}
}
return false;
int reverse(int num)
{
assert(num >= 0); // for non-negative integers only.
int rev = 0;
while (num != 0)
{
rev = rev * 10 + num % 10;
num /= 10;
}
return rev;
}
Похоже, это тоже сработало, но учитывали ли вы возможность переполнения обратного числа? Если он переполняется, поведение зависит от языка (для Java число переносится при переполнении, но в C/C++ его поведение не определено). Фу.
Оказывается, сравнивать с двух сторон проще. Сначала сравните первую и последнюю цифру. Если они не совпадают, это не должно быть палиндромом. Если они одинаковые, отрежьте по одной цифре с обоих концов и продолжайте, пока у вас не останется цифр, из чего вы заключаете, что это должен быть палиндром.
Теперь получить и отрезать последнюю цифру несложно. Однако для того, чтобы получить и отсечь первую цифру обычным способом, требуется некоторое размышление. Решение ниже позаботится об этом.
int isIntPalindrome(int x)
{
if (x < 0)
return 0;
int div = 1;
while (x / div >= 10)
{
div *= 10;
}
while (x != 0)
{
int l = x / div;
int r = x % 10;
if (l != r)
return 0;
x = (x % div) / 10;
div /= 100;
}
return 1;
}
div = 10
, просто зациклить while (10 <= x)
, отступить от самого первого return
и убрать фигурные скобки вокруг div *= 10;
. Очень похоже, по крайней мере, на ответ user1552891.
- person greybeard; 17.05.2015
Не уверен, что это лучший ответ, и я новичок в программировании. (это в джаве)
import java.util.*;
public class Palin {
public static void main(String[] args) {
Random randInt = new Random();
Scanner kbd = new Scanner(System.in);
int t = kbd.nextInt(); //# of test cases;
String[] arrPalin = new String[t]; //array of inputs;
String[] nextPalin = new String[t];
for (int i = 0; i < t; i++) {
arrPalin[i] = String.valueOf(randInt.nextInt(2147483646) + 1);
System.out.println(arrPalin[i]);
}
final long startTime = System.nanoTime();
for (int i = 0; i < t; i++) {
nextPalin[i] = (unmatcher(incrementer(switcher(match(arrPalin[i])))));
}
final long duration = System.nanoTime() - startTime;
for (int i = 0; i < t; i++) {
System.out.println(nextPalin[i]);
}
System.out.println(duration);
}
public static String match(String N) {
int length = N.length();
//Initialize a string with length of N
char[] chars = new char[length];
Arrays.fill(chars, '0');
int count = 1;
for (int i = 0; i < length; i++) {
if ((i%2) == 0) { //at i = even.
if (i == 0) {
chars[i] = N.charAt(i);
} else
chars[i] = N.charAt(i/2);
} else //at i = odd
chars[i] = N.charAt(length - count);
count++;
}
return String.valueOf(chars);
}
public static String switcher(String N) {
int length = N.length();
char[] chars = new char[length];
Arrays.fill(chars, '0');
for (int i = 0; i < length; i++) {
if (i != 0) {
if ((i % 2) == 0) {
chars[i] = N.charAt(i);
} else if ((i % 2) != 0) {
chars[i] = N.charAt(i - 1);
}
}
if (i == 0) {
chars[0] = N.charAt(0);
}
}
return String.valueOf(chars);
}
public static String incrementer(String N) {
int length = N.length();
char[] chars = new char[length];
Arrays.fill(chars, '0');
char[] newN = N.toCharArray();
String returnVal;
int numOne, numTwo;
if ((length % 2) == 0) {
numOne = N.charAt(length-1);
numTwo = N.charAt(length-2);
newN[length-1] = (char)(numOne+1);
newN[length-2] = (char)(numTwo+1);
returnVal = String.valueOf(newN);
} else {
numOne = N.charAt(length-1);
newN[length-1] = (char)(numOne+1);
returnVal = String.valueOf(newN);
}
return returnVal;
}
public static String unmatcher(String N) {
int length = N.length();
char[] chars = new char[length];
Arrays.fill(chars, '0');
char[] newN = N.toCharArray();
for (int i = 0; i < length; i++) {
if (((i % 2) == 0) && (i != 0)) { // for i > 0, even
newN[i / 2] = N.charAt(i);
} else if ((i % 2) == 0 && (i == 0)) { // for i = 0
newN[0] = N.charAt(0);
}
}
for (int i = (length/2); i < length; i++) {
newN[i] = newN[Math.abs(i - (length - 1))];
}
return String.valueOf(newN);
}
}
Итак, для этого кода введите число (я сделал случайные числа, сколько я хочу), оно будет преобразовано, например, ввод 172345 в 157423. Затем он изменит его на 117722, затем, если четное сделает его 117733, если нечетное сделайте то же самое только для последней цифры. Тогда сделайте это 173371. Это не поиск палиндрома, а поиск следующего по величине числа палиндрома.
открытый класс PalindromePrime {
private static int g ,n =0,i,m ;
private javax.swing.JTextField jTextField;
static String b ="";
private static Scanner scanner = new Scanner( System.in );
public static void main(String [] args) throws IOException {
System.out.print(" Please Inter Data : ");
g = scanner.nextInt();
System.out.print(" Please Inter Data 2 : ");
m = scanner.nextInt();
count(g,m);
}
public static int count(int L, int R) {
int resultNum = 0;
for( i= L ; i<= R ;i++){
int count= 0 ;
for( n = i ; n >=1 ;n -- ){
if(i%n==0){
count = count + 1 ;
// System.out.println(" Data : \n " +count );
}
}
if(count == 2)
{
//b = b +i + "" ;
String ss= String .valueOf(i);
// System.out.print("\n" +i );
if(isPalindrome(i))
{
//0 System.out.println("Number : " + i + " is a palindrome");
//number2[b] = Integer.parseInt(number_ayy[b]);
//String s = String .valueOf(i);
//System.out.printf("123456", s);
resultNum++;
}
else{
//*System.out.println("Number : " + i + " is Not a palindrome");
}
//System.out.println(" Data : \n " +ss.length() );
}
// palindrome(i);
}
// System.out.print(" Data : ");
// System.out.println(" Data : \n " +b );
return resultNum;
}
@SuppressWarnings("unused")
public static boolean isPalindrome(int number ) {
int p = number; // ประกาศ p เป็น int ให้เท่ากับ number ของ ตัวที่ มาจาก method
int r = 0; //ประกาศ r เป็น int โดยให้มีค่าเรื่องต้นเท่ากับ 0
int w = 0 ;
while (p != 0) { // เงื่อนไข While ถ้า p ไม่เท่ากับ 0 เช่น 2!= 0 จริง เข้า
w = p % 10; // ประกาศตัว แปร W ให้ เท่ากับค่า p ที่มาจาก parramiter ให้ & mod กับ 10 คือ เช่น 2 % 10 = 2 ; w= 2 ; 3% 10 ; w =3
r = r * 10 + w; // (ให้ R ที่มาจาก การประกาศค่ตัวแปร แล้ว * 10) + w จะมาจากค่า w = p % 10; ที่ mod ไว้ เช่น 0*10 + 2 = 2
p = p / 10; //แล้วใช้ p ที่จมาจากตัว paramiter แล้วมาหาร 10 เพราะถ้าไม่มี ก็จะสามารถพิมพ์ค่าออกมาได้ || ทำไงก็ได้ให้เป็น 0 และเอามาแทนค่ตัวต่อไป
}
// 1 วนวูปเช็คว่า (p != 0) หรือไม่ โดย p มาจาก p = number ที่รับมา
// 2 r = (r * 10) + (p%10) ;
//3 p = p /10 ; เพื่อเช็ค ว่าให้มันเป็น 0 เพื่อหลุด Loop
if (number == r) {
// for(int count = 0 ; count <i ;count ++){
String s1 = String.valueOf(i);
//countLines(s1);
System.out.println("Number : " + "'"+s1 +"'"+" is a palindrome");
return true; //เรียก return ไป
}
return false;
}
public static int countLines(String str)
{
if (str == null || str.length() == 0)
return 0;
int lines = 1;
int len = str.length();
for( int pos = 0; pos < len; pos++) {
char c = str.charAt(pos);
if( c == '\r' ) {
System.out.println("Line 0 : " + "'"+str );
lines++;
if ( pos+1 < len && str.charAt(pos+1) == '\n' )
System.out.println("Line : " + "'"+str );
pos++;
} else if( c == '\n' ) {
lines++;
System.out.println("Line 2 : " + "'"+str );
}
}
return lines;
}
public static int countLines1(String sd) throws IOException {
LineNumberReader lineNumberReader = new LineNumberReader(new StringReader(sd));
int count = 0 ;
System.out.printf("Line : " , count = count + 1 );
lineNumberReader.skip(Long.MAX_VALUE);
return lineNumberReader.getLineNumber();
}
}
Этот код преобразует int в String, а затем проверяет, является ли строка паллиндромной. Преимущество в том, что это быстро, а недостаток в том, что он преобразует int в String, тем самым ставя под угрозу идеальное решение вопроса.
static int pallindrome=41012;
static String pallindromer=(Integer.toString(pallindrome));
static int length=pallindromer.length();
public static void main(String[] args) {
pallindrome(0);
System.out.println("It's a pallindrome");
}
static void pallindrome(int index){
if(pallindromer.charAt(index)==pallindromer.charAt(length-(index+1))){
if(index<length-1){
pallindrome(++index);
}
}
else{
System.out.println("Not a pallindrome");
System.exit(0);
}
}
Однострочный код Python:
def isPalindrome(number):
return True if str(number) == ''.join(reversed(str(number))) else False
Проверьте это решение в java:
private static boolean ispalidrome(long n) {
return getrev(n, 0L) == n;
}
private static long getrev(long n, long initvalue) {
if (n <= 0) {
return initvalue;
}
initvalue = (initvalue * 10) + (n % 10);
return getrev(n / 10, initvalue);
}
isPalindrome(123454328)
привести к арифметическому переполнению?
- person greybeard; 17.10.2016
Просто получите количество цифр числа с помощью математических функций, а затем выполните итерацию, используя операции «/» и «%» следующим образом. После того, как x = (x % делитель) / 10, мы должны разделить делитель на 100, так как мы сделали 2 нулевых операции.
public static boolean isPalindrome(int x) {
if (x < 0) return false;
if (x < 10) return true;
int numDigits = (int)(Math.log10(x)+1);
int divider = (int) (Math.pow(10, numDigits - 1));
for (int i = 0; i < numDigits / 2; i++) {
if (x / divider != x % 10)
return false;
x = (x % divider) / 10;
divider /= 100;
}
return true;
}
Лично я делаю это так, и нет никакого наложения; код прекращает проверку соответствия символов в правильном месте, независимо от того, имеет ли строка четную или нечетную длину. Некоторые из других методов, опубликованных выше, будут пытаться сопоставить один дополнительный раз, когда в этом нет необходимости.
Если мы используем length/2, он все равно будет работать, но выполнит одну дополнительную проверку, в которой нет необходимости. Например, слово «поп» имеет длину 3. 3/2 = 1,5, поэтому он перестанет проверять, когда i = 2 (поскольку 1‹1,5, он будет проверять и при i = 1), но нам нужно, чтобы он остановился на 0, а не на единице. Первая «p» находится в позиции 0, и она будет проверять себя на длину-1-0 (текущая позиция), которая является последней «p» в позиции 2, и тогда у нас останется центральная буква, которая не нуждается в проверке. Когда мы делаем length/2, мы останавливаемся на 1, поэтому происходит дополнительная проверка, когда i находится в позиции 1 («o») и сравнивается с самой собой (length-1-i).
// Checks if our string is palindromic.
var ourString = "A Man, /.,.()^&*A Plan, A Canal__-Panama!";
isPalin(ourString);
function isPalin(string) {
// Make all lower case for case insensitivity and replace all spaces, underscores and non-words.
string = string.toLowerCase().replace(/\s+/g, "").replace(/\W/g,"").replace(/_/g,"");
for(i=0; i<=Math.floor(string.length/2-1); i++) {
if(string[i] !== string[string.length-1-i]) {
console.log("Your string is not palindromic!");
break;
} else if(i === Math.floor(string.length/2-1)) {
console.log("Your string is palindromic!");
}
}
}
Это мой Java-код. В основном сравнение первого и последнего значения строки и следующей пары внутренних значений и так далее.
/*Palindrome number*/
String sNumber = "12321";
int l = sNumber.length(); // getting the length of sNumber. In this case its 5
boolean flag = true;
for (int i = 0; i <= l; ++i) {
if (sNumber.charAt(i) != sNumber.charAt((l--) -1)) { //comparing the first and the last values of the string
System.out.println(sNumber +" is not a palindrome number");
flag = false;
break;
}
//l--; // to reducing the length value by 1
}
if (flag) {
System.out.println(sNumber +" is a palindrome number");
}
Ниже приведен ответ в быстром виде. Он считывает число слева и справа и сравнивает их, если они одинаковы. Поступая таким образом, мы никогда не столкнемся с проблемой целочисленного переполнения (что может произойти при реверсировании числового метода), поскольку мы не создаем другое число.
Шаги:
конец туалета вернуть истину
func isPalindrom(_ input: Int) -> Bool {
if input < 0 {
return false
}
if input < 10 {
return true
}
var num = input
let length = Int(log10(Float(input))) + 1
var i = length
while i > 0 && num > 0 {
let ithDigit = (input / Int(pow(10.0, Double(i) - 1.0)) ) % 10
let r = Int(num % 10)
if ithDigit != r {
return false
}
num = num / 10
i -= 1
}
return true
}
Это решение довольно эффективно, так как я использую StringBuilder, что означает, что класс StringBuilder реализован как изменяемая последовательность символов. Это означает, что вы добавляете новые строки или символы в StringBuilder.
public static boolean isPal(String ss){
StringBuilder stringBuilder = new StringBuilder(ss);
stringBuilder.reverse();
return ss.equals(stringBuilder.toString());
}
Предполагая, что ведущие нули игнорируются. Ниже приведена реализация:
#include<bits/stdc++.h>
using namespace std;
vector<int>digits;
stack<int>digitsRev;
int d,number;
bool isPal=1;//initially assuming the number is palindrome
int main()
{
cin>>number;
if(number<10)//if it is a single digit number than it is palindrome
{
cout<<"PALINDROME"<<endl;
return 0;
}
//if the number is greater than or equal to 10
while(1)
{
d=number%10;//taking each digit
number=number/10;
//vector and stack will pick the digits
//in reverse order to each other
digits.push_back(d);
digitsRev.push(d);
if(number==0)break;
}
int index=0;
while(!digitsRev.empty())
{
//Checking each element of the vector and the stack
//to see if there is any inequality.
//And which is equivalent to check each digit of the main
//number from both sides
if(digitsRev.top()!=digits[index++])
{
cout<<"NOT PALINDROME"<<endl;
isPal=0;
break;
}
digitsRev.pop();
}
//If the digits are equal from both sides than the number is palindrome
if(isPal==1)cout<<"PALINDROME"<<endl;
}
Черт возьми, я сошел с ума! http://www.palindromelist.net/palindromes-d/
Отдельные шаги пример: является ли 332 палиндромным числом?
n = 332
q = n / 10 = 33
r = n - 10 * q = 2
r > 0
r != q
n = q = 33
n > r
q = n / 10 = 3
r -= q = 4294967295
r *= 10 = 4294967286
r += n = 23
r != n
r != q
n = q = 3
n > r ? No, so 332 isn't a palindromic number.
Переполнение тоже не проблема. Было необходимо два деления, в коде (C#) они выполняются с умножением. N-значное число: ~n/2 деления!
const ulong c0 = 0xcccccccdUL;
static bool isPal(uint n)
{
if (n < 10) return true;
uint q = (uint)(c0 * n >> 35);
uint r = n - 10 * q;
if (r == 0) return false;
if (r == q) return true;
n = q;
while (n > r)
{
q = (uint)(c0 * n >> 35);
r -= q;
r *= 10;
r += n;
if (r == n || r == q) return true;
n = q;
}
return false;
}
Палиндромных чисел ‹ 2^32 142948, их сумма равна 137275874705916.
using System;
class Program
{
static void Main() // take a break
{
uint n, c; var sw = System.Diagnostics.Stopwatch.StartNew();
n = ~0u; c = 0; sw.Restart(); while (n > 0) if (isPal0(n--)) c++;
Console.WriteLine(sw.Elapsed + " " + c); // 76 s
n = ~0u; c = 0; sw.Restart(); while (n > 0) if (isPal1(n--)) c++;
Console.WriteLine(sw.Elapsed + " " + c); // 42 s
n = ~0u; c = 0; sw.Restart(); while (n > 0) if (isPal2(n--)) c++;
Console.WriteLine(sw.Elapsed + " " + c); // 31 s
Console.Read();
}
static bool isPal0(uint u)
{
uint n = u, rev = 0;
while (n > 0) { uint dig = n % 10; rev = rev * 10 + dig; n /= 10; }
return u == rev;
}
static bool isPal1(uint u)
{
uint n = u, r = 0;
while (n >= 10) r = n + (r - (n /= 10)) * 10;
return u == 10 * r + n;
}
static bool isPal2(uint n)
{
if (n < 10) return true;
uint q = n / 10, r = n - 10 * q;
if (r == 0 || r == q) return r > 0;
while ((n = q) > r)
{
q /= 10; r -= q; r *= 10; r += n;
if (r == n || r == q) return true;
}
return false;
}
}
Этот вроде быстрее.
using System;
class Program
{
static void Main()
{
uint n, c; var sw = System.Diagnostics.Stopwatch.StartNew();
n = ~0u; c = 0; sw.Restart(); while (n > 0) if (isPal(n--)) c++;
Console.WriteLine(sw.Elapsed + " " + c); // 21 s
Console.Read();
}
static bool isPal(uint n)
{
return n < 100 ? n < 10 || n % 11 == 0 :
n < 1000 ? /* */ n / 100 == n % 10 :
n < 10000 ? n % 11 == 0 && n / 1000 == n % 10 && isP(n) :
n < 100000 ? /* */ n / 10000 == n % 10 && isP(n) :
n < 1000000 ? n % 11 == 0 && n / 100000 == n % 10 && isP(n) :
n < 10000000 ? /* */ n / 1000000 == n % 10 && isP(n) :
n < 100000000 ? n % 11 == 0 && n / 10000000 == n % 10 && isP(n) :
n < 1000000000 ? /* */ n / 100000000 == n % 10 && isP(n) :
n % 11 == 0 && n / 1000000000 == n % 10 && isP(n);
}
static bool isP(uint n)
{
uint q = n / 10, r = n - 10 * q;
do { n = q; q /= 10; r -= q; r *= 10; r += n; } while (r < q);
return r == q || r == n;
}
}
С почти сбалансированным спагетти-деревом бинарного поиска.
using System;
class Program
{
static void Main()
{
uint n, c; var sw = System.Diagnostics.Stopwatch.StartNew();
n = c = 0; sw.Restart(); while (n < ~0u) if (isPal(n++)) c++;
Console.WriteLine(sw.Elapsed + " " + c); // 17 s
Console.Read();
}
static bool isPal(uint n)
{
return n < 1000000 ? n < 10000 ? n < 1000 ? n < 100 ?
n < 10 || n % 11 == 0 : n / 100 == n % 10 :
n / 1000 == n % 10 && isP(n) : n < 100000 ?
n / 10000 == n % 10 && isP(n) :
n / 100000 == n % 10 && isP(n) :
n < 100000000 ? n < 10000000 ?
n / 1000000 == n % 10 && isP(n) :
n % 11 == 0 && n / 10000000 == n % 10 && isP(n) :
n < 1000000000 ? n / 100000000 == n % 10 && isP(n) :
n % 11 == 0 && n / 1000000000 == n % 10 && isP(n);
}
static bool isP(uint n)
{
uint q = n / 10, r = n - 10 * q;
do { n = q; q /= 10; r -= q; r *= 10; r += n; } while (r < q);
return r == q || r == n;
}
}
Неуравновешенный вверх ногами.
using System;
class Program
{
static void Main()
{
uint n, c; var sw = System.Diagnostics.Stopwatch.StartNew();
n = c = 0; sw.Restart(); while (n < ~0u) if (isPal(n++)) c++;
Console.WriteLine(sw.Elapsed + " " + c); // 16 s
Console.Read();
}
static bool isPal(uint n)
{
return
n > 999999999 ? n % 11 == 0 && n / 1000000000 == n % 10 && isP(n) :
n > 99999999 ? n / 100000000 == n % 10 && isP(n) :
n > 9999999 ? n % 11 == 0 && n / 10000000 == n % 10 && isP(n) :
n > 999999 ? n / 1000000 == n % 10 && isP(n) :
n > 99999 ? n % 11 == 0 && n / 100000 == n % 10 && isP(n) :
n > 9999 ? n / 10000 == n % 10 && isP(n) :
n > 999 ? n % 11 == 0 && n / 1000 == n % 10 && isP(n) :
n > 99 ? n / 100 == n % 10 :
n < 10 || n % 11 == 0;
}
static bool isP(uint n)
{
uint q = n / 10, r = n - 10 * q;
do { n = q; q /= 10; r -= q; r *= 10; r += n; } while (r < q);
return r == q || r == n;
}
}
number
иis a palindrome
должны означать в этом контексте: как насчет 13E31 (десятичная система счисления)? 01210 (ведущий ноль)? +10-10+1 (пятизначный сбалансированный тройной)? - person greybeard   schedule 31.12.2014