So I'm trying to reverse a number in java using a forloop, I get the right value but I'm not sure if thats the best way of doing it.
package forloops;
/*
% prints the last number in the sequence
/ prints every number except for the last one
*/
public class modulusForLoops {
public static void main(String[]args) {
int orig = 123456789;
int num = orig;
for (int i = 0; i < 1; i++) {
num = orig % 10; //9
int secondDigit = orig / 10; //12345678
int secondDigitPrinted = secondDigit % 10; //8
int thirdDigit = secondDigit / 10; //1234567
int thirdDigitPrinted = thirdDigit % 10; //7
int fourthDigit = thirdDigit / 10; //123456
int fourthDigitPrinted = fourthDigit % 10; //6
int fifthDigit = fourthDigit / 10; //12345
int fifthDigitPrinted = fifthDigit % 10;
int sixthDigit = fifthDigit / 10; //1234
int sixthDigitPrinted = sixthDigit % 10; //4
int seventhDigit = sixthDigit / 10; //123
int seventhDigitPrinted = seventhDigit % 10; //3
int eigthDigit = seventhDigit / 10; //12
int eigthDigitPrinted = eigthDigit % 10; //2
int lastDigit = eigthDigit / 10; //1
System.out.println(orig + " reversed is " + num + secondDigitPrinted + thirdDigitPrinted + fourthDigitPrinted + fifthDigitPrinted + sixthDigitPrinted + seventhDigitPrinted + eigthDigitPrinted + lastDigit);
}
}
}
You could simply convert it to String and using java.lang.StringBuilder reverse the string.
int orig = 123456789;
String numString = Integer.toString(orig);
String reversed = "";
for (int i = numString.length() - 1; i >= 0; i--) { // loop through the string from back to front
reversed += numString.charAt(i); // add each character to the resulting string
}
System.out.println(reversed);
Or alternatively
int orig = 123456789;
String numString = Integer.toString(orig); // convert int to String
String reversed = new StringBuilder(numString).reverse().toString(); // reverse string
System.out.println(reversed);
Let's stick with the logic you have in mind to reverse any number. For better understanding, let's list out the algorithm steps that you are using.
Repeat below steps until there are no digits left in the given number:
I) get the last digit from the number, i.e. lastDigit = number % 10
II) remove the last digit from the number, i.e. numberWithoutLast = number / 10
When we want to go through a sequence of steps multiple times, i.e. repeat them, we make use of the looping structures like for, while or do...while
Therefore, if we were to rewrite your program-the loop part-it would be as follows:
public static void main(String[] ar) {
int orig = 123456789;
int lastDigit = 0;
/* we'll use the copy of original number for step I & II
* instead of messing with the original number
*/
int numberWithoutLast = orig;
String reversed = ""; // we'll use this to store every last digit
for(int i = 0;
i < Integer.toString(orig).length(); /* this will repeat the loop for number of digits in "orig" */
i++) {
lastDigit = numberWithoutLast % 10;
reversed += Integer.toString(lastDigit);
numberWithoutLast = numberWithoutLast / 10;
}
// lastly we print the reversed number
System.out.println("Reversed Number: " + reversed);
}
This was the manual way of reversing an integer. For an automatic way, you can have a look at #Andreas's answer.
Just in case you want to know how to do it by modulus and loop. The idea is to pop the unit digit from the source and push it to the destination in every iteration, in a number way.
int orig = 123456789; //assume > 0
int num = 0;
for(int temp = orig;temp > 0;temp/=10)
{
num = num * 10 + temp % 10;
}
System.out.println(orig + " reversed is " + num);
How can I convert int=43707 to two other numbers?
The first number is made by value of odd bits. Second number is made by value of even bits.
int x = 43707; // 1010101010111011
var even = 0;
var odd = 0;
for (int i = 0; i<=31; i++) {
if(i%2 == 0) {
?
} else {
?
}
}
Your looking for the bitwise AND operation: &. you can use it together with a binary mask (normally specified in hex notation 0x00FF). so you need to do something like:
int x= 707; //10110011
int oddBits = 0x5555; //01010101
int evenBits = 0xAAAA; //10101010
int oddResult = x & oddBits;
System.out.println(oddResult);
int evenResult = x & evenBits;
System.out.println(evenResult);
which returns: 65 //00010001
and 642 // 10100010
Just convert int into digits as shown below:
List<Integer> digits = new ArrayList<Integer>();
while(x > 0) {
digits.add(x % 10);
x /= 10;
}
System.out.println(digits);
Once you have the separated the digits then apply the even odd logic. Here is complete code:
int x = 43707; // 1010101010111011
List<Integer> digits = new ArrayList<>();
while(x > 0) {
digits.add(x % 10);
x /= 10;
}
int i = 0;
int length = digits.size();
while (i < length) {
if(digits.get(i)%2 == 0){
System.out.println("Even Number" + digits.get(i));
} else {
System.out.println("Odd Number" + digits.get(i));
}
i++;
}
If you are looking for the Binary conversion then you can use the below code.
int x = 43707; // 1010101010111011
int testNumber;
String binaryNumber = Integer.toBinaryString(x);
for (int i = 0 ; i != binaryNumber.length() ; i++) {
char c = binaryNumber.charAt(i);
testNumber = Character.getNumericValue(binaryNumber.charAt(i));
if(testNumber == 0){
System.out.println("Even Number");
} else {
System.out.println("Odd Number");
}
System.out.println(c);
}
System.out.println(binaryNumber);
It converts the Int to Binary and then check even and odd numbers.
Hope, it works for you as per your desired output.
I came up to this:
int x = 43707;
String binary = Integer.toBinaryString(x);
System.out.println("binary=" + binary);
String odds = "";
String evens = "";
for (int i = binary.length() - 1; i >= 0; i--) {
if ((i + 1) % 2 == 0) {
odds += binary.charAt(i);
} else {
evens += binary.charAt(i);
}
}
System.out.println("odds=" + odds);
System.out.println("evens=" + evens);
int odd = Integer.parseInt(odds, 2);
int even = Integer.parseInt(evens, 2);
System.out.println("number from odd bits=" + odd);
System.out.println("number from even bits=" + even);
prints
binary=1010101010111011
odds=10100000
evens=11111111
number from odd bits=160
number from even bits=255
I'm counting right to left the bits.
I'm trying create a method which returns char type. The condition is this: system takes 9 digits from user input and calculate it. The method converts each char in the nextLine() input and computes the sum then take % 11. If the remainder is 10, method return 'X' and if the remainder is 0 through 9, then the method returns that digit but must be in char type. So far I'm lost at why it will always output '/' and nothing else. Please help me find out the mistake of my algorithms.
public static char getCheckSum(String isbn) {
int sum = 0;
char charSum;
for (int i = 0; i < isbn.length(); i++) {
int[] num = new int[isbn.length()];
num[i] = Character.getNumericValue(i) * (i+1);
sum = sum + num[i];
}
int last = (sum % 11);
if (last == 10){
charSum = (char) 88;
} else {
charSum = (char) (last + 48);
}
return charSum;
//this is the next part where it inserts hyphens just as a reference
public static String formatISBNWithHyphens(String isbn) {
// original isbn: 123456789
// possible new isbn: 1-234-56789-X
char isbn10 = getCheckSum(isbn);
String isbn10Str = isbn + Character.toString(isbn10);
// char[] c = new char[isbn10Str.length()]; *leaving this here for future learning.
String[] cStr = new String[isbn10Str.length()];
String isbnStr = "";
for (int i = 0; i < isbn10Str.length(); i++){
cStr[i] = Character.toString(isbn10Str.charAt(i));
// c[i] = isbn10Str.charAt(i); *leaving this here for future learning.
if (i == 0 || i == 3 || i == 8 ) {
cStr[i] += '-';
}
isbnStr += cStr[i];
}
return isbnStr;
}
// The final outcome is always like this 321654987/ and 3-216-54987-/
it is supposed to be either numbers from 0 to 9 or X if remainder is 10.
Please help. Thanks a bunch.
I think the problem is here
for (int i = 0; i < isbn.length(); i++) {
int[] num = new int[isbn.length()];
num[i] = Character.getNumericValue(i) * (i+1);
sum = sum + num[i];
}
The for cycle returning a result has no relationship with the isbn's content, the result just depends on the isbn string length!
so you can change the code to the following one below
for (int i = 0; i < isbn.length(); i++) {
int[] num = new int[isbn.length()];
num[i] = Character.getNumericValue(isbn.charAt(i));
sum = sum + num[i];
}
the code above returns a result depending on the isbn's content
Data file:
J A V A
1 H 11 H 21 H
1 V 2 V 3 V
2 H 12 H 22 H
3 V 4 V 5 V
7 H 6 V 17 H
Code (part of a larger program):
File dataFile = new File("data.txt");
Scanner in;
in = new Scanner (dataFile);
String letter1 = in.next(); //Reads first letter of the word and stores it as a string
String letter2 = in.next(); //Reads second letter of the word and stores it as a string
String letter3 = in.next(); //Reads third letter of the word and stores it as a string
String letter4 = in.next(); //Reads fourth letter of the word and stores it as a string
// Not all of these ints are used in the code shown here
int firstLetterValue1;
int secondLetterValue1;
int thirdLetterValue1;
int fourthLetterValue1;
int firstLetterValue2;
int secondLetterValue2;
int thirdLetterValue2;
int fourthLetterValue2;
int firstLetterValue3;
int secondLetterValue3;
int thirdLetterValue3;
int fourthLetterValue3;
int multiplier1 = 1;
int multiplier2 = 1;
int multiplier3 = 1;
int totalWordValue1 = 0;
int totalWordValue2 = 0;
int totalWordValue3 = 0;
// These test to see whether the first, second, third, or fourth letter of the word
// Are equal to a specified letter and if they are,
// then a value is stored into a different integer
if (letter1.equalsIgnoreCase("A") || letter1.equalsIgnoreCase("E"))
{
firstLetterValue1 = 1;
firstLetterValue2 = 1;
firstLetterValue3 = 1;
}
else if (letter1.equalsIgnoreCase("D") || letter1.equalsIgnoreCase("R"))
{
firstLetterValue1 = 2;
firstLetterValue2 = 2;
firstLetterValue3 = 2;
}
else if (letter1.equalsIgnoreCase("B") || letter1.equalsIgnoreCase("M"))
{
firstLetterValue1 = 3;
firstLetterValue2 = 3;
firstLetterValue3 = 3;
}
else if (letter1.equalsIgnoreCase("V") || letter1.equalsIgnoreCase("Y"))
{
firstLetterValue1 = 4;
firstLetterValue2 = 4;
firstLetterValue3 = 4;
}
// For example, in the word "J A V A", the first letter, which is "J", will store
// the value "8" into the integers inside the brackets (firstLetterValue1, firstLetterValue2, etc.)
else if (letter1.equalsIgnoreCase("J") || letter1.equalsIgnoreCase("X"))
{
firstLetterValue1 = 8;
firstLetterValue2 = 8;
firstLetterValue3 = 8;
}
for (int num = 0; num <= 4; num++)
{
int location1 = in.nextInt();
String direction1 = in.next();
// This is where I am getting my problem: "The local variable firstLetterValue1 has not been initialized"
if ((location1 == 1) && (direction1.equalsIgnoreCase("H")))
{
firstLetterValue1 *= 1;
secondLetterValue1 *= 1;
thirdLetterValue1 *= 2;
fourthLetterValue1 *= 1;
multiplier1 = 1;
totalWordValue1 = (firstLetterValue1 + secondLetterValue1 + thirdLetterValue1 + fourthLetterValue1) * multiplier1;
}
}
I tried to outline my problem with the comments. So, I am getting an error at the part with if ((location1 == 1) && (direction1.equalsIgnoreCase("H"))). I know that the program wants me to declare the integer by int firstLetterValue1 = 0;, but the problem I am getting is that the whole part before it with the if statements will just be skipped. I want the firstLetterValue1, firstLetterValue2, etc. integers to keep their value.
If this is still unclear let me know
You just have to assign default value to local variables that would make it compilable
int i = -1;
if( /* some condition */) {
i = 10;
}
System.out.println(i);
If none of the conditions in the if / else if is true, the variables won't be initialised. Two options:
initialise them with a default value when you declare them
add an else statement to ensure that the variables will always be initialised
Firstly here is the problem:
A positive integer is called a palindrome if its representation in the decimal system is the same when read from left to right and from right to left. For a given positive integer K of not more than 1000000 digits, write the value of the smallest palindrome larger than K to output. Numbers are always displayed without leading zeros.
Input: The first line contains integer t, the number of test cases. Integers K are given in the next t lines.
Output: For each K, output the smallest palindrome larger than K.
Example
Input:
2
808
2133
Output:
818
2222
Secondly here is my code:
// I know it is bad practice to not cater for erroneous input,
// however for the purpose of the execise it is omitted
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.lang.Exception;
import java.math.BigInteger;
public class Main
{
public static void main(String [] args){
try{
Main instance = new Main(); // create an instance to access non-static
// variables
// Use java.util.Scanner to scan the get the input and initialise the
// variable
Scanner sc=null;
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
String input = "";
int numberOfTests = 0;
String k; // declare any other variables here
if((input = r.readLine()) != null){
sc = new Scanner(input);
numberOfTests = sc.nextInt();
}
for (int i = 0; i < numberOfTests; i++){
if((input = r.readLine()) != null){
sc = new Scanner(input);
k=sc.next(); // initialise the remainder of the variables sc.next()
instance.palindrome(k);
} //if
}// for
}// try
catch (Exception e)
{
e.printStackTrace();
}
}// main
public void palindrome(String number){
StringBuffer theNumber = new StringBuffer(number);
int length = theNumber.length();
int left, right, leftPos, rightPos;
// if incresing a value to more than 9 the value to left (offset) need incrementing
int offset, offsetPos;
boolean offsetUpdated;
// To update the string with new values
String insert;
boolean hasAltered = false;
for(int i = 0; i < length/2; i++){
leftPos = i;
rightPos = (length-1) - i;
offsetPos = rightPos -1; offsetUpdated = false;
// set values at opposite indices and offset
left = Integer.parseInt(String.valueOf(theNumber.charAt(leftPos)));
right = Integer.parseInt(String.valueOf(theNumber.charAt(rightPos)));
offset = Integer.parseInt(String.valueOf(theNumber.charAt(offsetPos)));
if(left != right){
// if r > l then offest needs updating
if(right > left){
// update and replace
right = left;
insert = Integer.toString(right);
theNumber.replace(rightPos, rightPos + 1, insert);
offset++; if (offset == 10) offset = 0;
insert = Integer.toString(offset);
theNumber.replace(offsetPos, offsetPos + 1, insert);
offsetUpdated = true;
// then we need to update the value to left again
while (offset == 0 && offsetUpdated){
offsetPos--;
offset =
Integer.parseInt(String.valueOf(theNumber.charAt(offsetPos)));
offset++; if (offset == 10) offset = 0;
// replace
insert = Integer.toString(offset);
theNumber.replace(offsetPos, offsetPos + 1, insert);
}
// finally incase right and offset are the two middle values
left = Integer.parseInt(String.valueOf(theNumber.charAt(leftPos)));
if (right != left){
right = left;
insert = Integer.toString(right);
theNumber.replace(rightPos, rightPos + 1, insert);
}
}// if r > l
else
// update and replace
right = left;
insert = Integer.toString(right);
theNumber.replace(rightPos, rightPos + 1, insert);
}// if l != r
}// for i
System.out.println(theNumber.toString());
}// palindrome
}
Finally my explaination and question.
My code compares either end and then moves in
if left and right are not equal
if right is greater than left
(increasing right past 9 should increase the digit
to its left i.e 09 ---- > 10) and continue to do
so if require as for 89999, increasing the right
most 9 makes the value 90000
before updating my string we check that the right
and left are equal, because in the middle e.g 78849887
we set the 9 --> 4 and increase 4 --> 5, so we must cater for this.
The problem is from spoj.pl an online judge system. My code works for all the test can provide but when I submit it, I get a time limit exceeded error and my answer is not accepted.
Does anyone have any suggestions as to how I can improve my algorithm. While writing this question i thought that instead of my while (offset == 0 && offsetUpdated) loop i could use a boolean to to make sure i increment the offset on my next [i] iteration. Confirmation of my chang or any suggestion would be appreciated, also let me know if i need to make my question clearer.
This seems like a lot of code. Have you tried a very naive approach yet? Checking whether something is a palindrome is actually very simple.
private boolean isPalindrome(int possiblePalindrome) {
String stringRepresentation = String.valueOf(possiblePalindrome);
if ( stringRepresentation.equals(stringRepresentation.reverse()) ) {
return true;
}
}
Now that might not be the most performant code, but it gives you a really simple starting point:
private int nextLargestPalindrome(int fromNumber) {
for ( int i = fromNumber + 1; ; i++ ) {
if ( isPalindrome( i ) ) {
return i;
}
}
}
Now if that isn't fast enough you can use it as a reference implementation and work on decreasing the algorithmic complexity.
There should actually be a constant-time (well it is linear on the number of digits of the input) way to find the next largest palindrome. I will give an algorithm that assumes the number is an even number of digits long (but can be extended to an odd number of digits).
Find the decimal representation of the input number ("2133").
Split it into the left half and right half ("21", "33");
Compare the last digit in the left half and the first digit in the right half.
a. If the right is greater than the left, increment the left and stop. ("22")
b. If the right is less than the left, stop.
c. If the right is equal to the left, repeat step 3 with the second-last digit in the left and the second digit in the right (and so on).
Take the left half and append the left half reversed. That's your next largest palindrome. ("2222")
Applied to a more complicated number:
1. 1234567887654322
2. 12345678 87654322
3. 12345678 87654322
^ ^ equal
3. 12345678 87654322
^ ^ equal
3. 12345678 87654322
^ ^ equal
3. 12345678 87654322
^ ^ equal
3. 12345678 87654322
^ ^ equal
3. 12345678 87654322
^ ^ equal
3. 12345678 87654322
^ ^ equal
3. 12345678 87654322
^ ^ greater than, so increment the left
3. 12345679
4. 1234567997654321 answer
This seems a bit similar to the algorithm you described, but it starts at the inner digits and moves to the outer.
There is no reason to fiddle with individual digits when the only needed operation is one simple addition. The following code is based on Raks' answer.
The code stresses simplicity over execution speed, intentionally.
import static org.junit.Assert.assertEquals;
import java.math.BigInteger;
import org.junit.Test;
public class NextPalindromeTest {
public static String nextPalindrome(String num) {
int len = num.length();
String left = num.substring(0, len / 2);
String middle = num.substring(len / 2, len - len / 2);
String right = num.substring(len - len / 2);
if (right.compareTo(reverse(left)) < 0)
return left + middle + reverse(left);
String next = new BigInteger(left + middle).add(BigInteger.ONE).toString();
return next.substring(0, left.length() + middle.length())
+ reverse(next).substring(middle.length());
}
private static String reverse(String s) {
return new StringBuilder(s).reverse().toString();
}
#Test
public void testNextPalindrome() {
assertEquals("5", nextPalindrome("4"));
assertEquals("11", nextPalindrome("9"));
assertEquals("22", nextPalindrome("15"));
assertEquals("101", nextPalindrome("99"));
assertEquals("151", nextPalindrome("149"));
assertEquals("123454321", nextPalindrome("123450000"));
assertEquals("123464321", nextPalindrome("123454322"));
}
}
Well I have constant order solution(atleast of order k, where k is number of digits in the number)
Lets take some examples
suppose n=17208
divide the number into two parts from middle
and reversibly write the most significant part onto the less significant one.
ie, 17271
if the so generated number is greater than your n it is your palindrome, if not just increase the center number(pivot) ie, you get 17371
other examples
n=17286
palidrome-attempt=17271(since it is less than n increment the pivot, 2 in this case)
so palidrome=17371
n=5684
palidrome1=5665
palidrome=5775
n=458322
palindrome=458854
now suppose n = 1219901
palidrome1=1219121
incrementing the pivot makes my number smaller here
so increment the number adjacent pivot too
1220221
and this logic could be extended
public class NextPalindrome
{
int rev, temp;
int printNextPalindrome(int n)
{
int num = n;
for (int i = num+1; i >= num; i++)
{
temp = i;
rev = 0;
while (temp != 0)
{
int remainder = temp % 10;
rev = rev * 10 + remainder;
temp = temp / 10;
}
if (rev == i)
{
break;
}
}
return rev;
}
public static void main(String args[])
{
NextPalindrome np = new NextPalindrome();
int nxtpalin = np.printNextPalindrome(11);
System.out.println(nxtpalin);
}
}
Here is my code in java. Whole idea is from here.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter number of tests: ");
int t = sc.nextInt();
for (int i = 0; i < t; i++) {
System.out.println("Enter number: ");
String numberToProcess = sc.next(); // ne proveravam dal su brojevi
nextSmallestPalindrom(numberToProcess);
}
}
private static void nextSmallestPalindrom(String numberToProcess) {
int i, j;
int length = numberToProcess.length();
int[] numberAsIntArray = new int[length];
for (int k = 0; k < length; k++)
numberAsIntArray[k] = Integer.parseInt(String
.valueOf(numberToProcess.charAt(k)));
numberToProcess = null;
boolean all9 = true;
for (int k = 0; k < length; k++) {
if (numberAsIntArray[k] != 9) {
all9 = false;
break;
}
}
// case 1, sve 9ke
if (all9) {
whenAll9(length);
return;
}
int mid = length / 2;
if (length % 2 == 0) {
i = mid - 1;
j = mid;
} else {
i = mid - 1;
j = mid + 1;
}
while (i >= 0 && numberAsIntArray[i] == numberAsIntArray[j]) {
i--;
j++;
}
// case 2 already polindrom
if (i == -1) {
if (length % 2 == 0) {
i = mid - 1;
j = mid;
} else {
i = mid;
j = i;
}
addOneToMiddleWithCarry(numberAsIntArray, i, j, true);
} else {
// case 3 not polindrom
if (numberAsIntArray[i] > numberAsIntArray[j]) { // 3.1)
while (i >= 0) {
numberAsIntArray[j] = numberAsIntArray[i];
i--;
j++;
}
for (int k = 0; k < numberAsIntArray.length; k++)
System.out.print(numberAsIntArray[k]);
System.out.println();
} else { // 3.2 like case 2
if (length % 2 == 0) {
i = mid - 1;
j = mid;
} else {
i = mid;
j = i;
}
addOneToMiddleWithCarry(numberAsIntArray, i, j, false);
}
}
}
private static void whenAll9(int length) {
for (int i = 0; i <= length; i++) {
if (i == 0 || i == length)
System.out.print('1');
else
System.out.print('0');
}
}
private static void addOneToMiddleWithCarry(int[] numberAsIntArray, int i,
int j, boolean palindrom) {
numberAsIntArray[i]++;
numberAsIntArray[j] = numberAsIntArray[i];
while (numberAsIntArray[i] == 10) {
numberAsIntArray[i] = 0;
numberAsIntArray[j] = numberAsIntArray[i];
i--;
j++;
numberAsIntArray[i]++;
numberAsIntArray[j] = numberAsIntArray[i];
}
if (!palindrom)
while (i >= 0) {
numberAsIntArray[j] = numberAsIntArray[i];
i--;
j++;
}
for (int k = 0; k < numberAsIntArray.length; k++)
System.out.print(numberAsIntArray[k]);
System.out.println();
}
}
Try this
public static String genNextPalin(String base){
//check if it is 1 digit
if(base.length()==1){
if(Integer.parseInt(base)==9)
return "11";
else
return (Integer.parseInt(base)+1)+"";
}
boolean check = true;
//check if it is all 9s
for(char a: base.toCharArray()){
if(a!='9')
check = false;
}
if(check){
String num = "1";
for(int i=0; i<base.length()-1; i++)
num+="0";
num+="1";
return num;
}
boolean isBasePalin = isPalindrome(base);
int mid = base.length()/2;
if(isBasePalin){
//if base is palin and it is odd increase mid and return
if(base.length()%2==1){
BigInteger leftHalf = new BigInteger(base.substring(0,mid+1));
String newLeftHalf = leftHalf.add(BigInteger.ONE).toString();
String newPalin = genPalin2(newLeftHalf.substring(0,mid),newLeftHalf.charAt(mid));
return newPalin;
}
else{
BigInteger leftHalf = new BigInteger(base.substring(0,mid));
String newLeftHalf = leftHalf.add(BigInteger.ONE).toString();
String newPalin = genPalin(newLeftHalf.substring(0,mid));
return newPalin;
}
}
else{
if(base.length()%2==1){
BigInteger leftHalf = new BigInteger(base.substring(0,mid));
BigInteger rightHalf = new BigInteger(reverse(base.substring(mid+1,base.length())));
//check if leftHalf is greater than right half
if(leftHalf.compareTo(rightHalf)==1){
String newPalin = genPalin2(base.substring(0,mid),base.charAt(mid));
return newPalin;
}
else{
BigInteger leftHalfMid = new BigInteger(base.substring(0,mid+1));
String newLeftHalfMid = leftHalfMid.add(BigInteger.ONE).toString();
String newPalin = genPalin2(newLeftHalfMid.substring(0,mid),newLeftHalfMid.charAt(mid));
return newPalin;
}
}
else{
BigInteger leftHalf = new BigInteger(base.substring(0,mid));
BigInteger rightHalf = new BigInteger(reverse(base.substring(mid,base.length())));
//check if leftHalf is greater than right half
if(leftHalf.compareTo(rightHalf)==1){
return genPalin(base.substring(0,mid));
}
else{
BigInteger leftHalfMid = new BigInteger(base.substring(0,mid));
String newLeftHalfMid = leftHalfMid.add(BigInteger.ONE).toString();
return genPalin(newLeftHalfMid);
}
}
}
}
public static String genPalin(String base){
return base + new StringBuffer(base).reverse().toString();
}
public static String genPalin2(String base, char middle){
return base + middle +new StringBuffer(base).reverse().toString();
}
public static String reverse(String in){
return new StringBuffer(in).reverse().toString();
}
static boolean isPalindrome(String str) {
int n = str.length();
for( int i = 0; i < n/2; i++ )
if (str.charAt(i) != str.charAt(n-i-1))
return false;
return true;
}
HI Here is another simple algorithm using python,
def is_palindrome(n):
if len(n) <= 1:
return False
else:
m = len(n)/2
for i in range(m):
j = i + 1
if n[i] != n[-j]:
return False
return True
def next_palindrome(n):
if not n:
return False
else:
if is_palindrome(n) is True:
return n
else:
return next_palindrome(str(int(n)+1))
print next_palindrome('1000010')
I have written comments to clarify what each step is doing in this python code.
One thing that need to be taken into consideration is that input can be very large that we can not simply perform integer operations on it. So taking input as string and then manipulating it would be much easier.
tests = int(input())
results = []
for i in range(0, tests):
pal = input().strip()
palen = len(pal)
mid = int(palen/2)
if palen % 2 != 0:
if mid == 0: # if the number is of single digit e.g. next palindrome for 5 is 6
ipal = int(pal)
if ipal < 9:
results.append(int(pal) + 1)
else:
results.append(11) # for 9 next palindrome will be 11
else:
pal = list(pal)
pl = l = mid - 1
pr = r = mid + 1
flag = 'n' # represents left and right half of input string are same
while pl >= 0:
if pal[pl] > pal[pr]:
flag = 'r' # 123483489 in this case pal[pl] = 4 and pal[pr] = 3 so we just need to copy left half in right half
break # 123484321 will be the answer
elif pal[pl] < pal[pr]:
flag = 'm' # 123487489 in this case pal[pl] = 4 and pal[pr] = 9 so copying left half in right half will make number smaller
break # in this case we need to take left half increment by 1 and the copy in right half 123494321 will be the anwere
else:
pl = pl -1
pr = pr + 1
if flag == 'm' or flag == 'n': # increment left half by one and copy in right half
if pal[mid] != '9': # if mid element is < 9 the we can simply increment the mid number only and copy left in right half
pal[mid] = str(int(pal[mid]) + 1)
while r < palen:
pal[r] = pal[l]
r = r + 1
l = l - 1
results.append(''.join(pal))
else: # if mid element is 9 this will effect entire left half because of carry
pal[mid] = '0' # we need to take care of large inputs so we can not just directly add 1 in left half
pl = l
while pal[l] == '9':
pal[l] = '0'
l = l - 1
if l >= 0:
pal[l] = str(int(pal[l]) + 1)
while r < palen:
pal[r] = pal[pl]
r = r + 1
pl = pl - 1
if l < 0:
pal[0] = '1'
pal[palen - 1] = '01'
results.append(''.join(pal))
else:
while r < palen: # when flag is 'r'
pal[r] = pal[l]
r = r + 1
l = l - 1
results.append(''.join(pal))
else: # even length almost similar concept here with flags having similar significance as in case of odd length input
pal = list(pal)
pr = r = mid
pl = l = mid - 1
flag = 'n'
while pl >= 0:
if pal[pl] > pal[pr]:
flag = 'r'
break
elif pal[pl] < pal[pr]:
flag = 'm'
break
else:
pl = pl -1
pr = pr + 1
if flag == 'r':
while r < palen:
pal[r] = pal[l]
r = r + 1
l = l - 1
results.append(''.join(pal))
else:
if pal[l] != '9':
pal[l] = str(int(pal[l]) + 1)
while r < palen:
pal[r] = pal[l]
r = r + 1
l = l - 1
results.append(''.join(pal))
else:
pal[mid] = '0'
pl = l
while pal[l] == '9':
pal[l] = '0'
l = l - 1
if l >= 0:
pal[l] = str(int(pal[l]) + 1)
while r < palen:
pal[r] = pal[pl]
r = r + 1
pl = pl - 1
if l < 0:
pal[0] = '1'
pal[palen - 1] = '01'
results.append(''.join(pal))
for xx in results:
print(xx)
We can find next palindrome easily like below.
private void findNextPalindrom(int i) {
i++;
while (!checkPalindrom(i)) {
i++;
}
Log.e(TAG, "findNextPalindrom:next palindrom is===" + i);
}
private boolean checkPalindrom(int num) {
int temp = num;
int rev = 0;
while (num > 0) {
int rem = num % 10;
rev = rev * 10 + rem;
num = num / 10;
}
return temp == rev;
}
Simple codes and test output:
class NextPalin
{
public static void main( String[] args )
{
try {
int[] a = {2, 23, 88, 234, 432, 464, 7887, 7657, 34567, 99874, 7779222, 2569981, 3346990, 229999, 2299999 };
for( int i=0; i<a.length; i++)
{
int add = findNextPalin(a[i]);
System.out.println( a[i] + " + " + add + " = " + (a[i]+add) );
}
}
catch( Exception e ){}
}
static int findNextPalin( int a ) throws Exception
{
if( a < 0 ) throw new Exception();
if( a < 10 ) return a;
int count = 0, reverse = 0, temp = a;
while( temp > 0 ){
reverse = reverse*10 + temp%10;
count++;
temp /= 10;
}
//compare 'half' value
int halfcount = count/2;
int base = (int)Math.pow(10, halfcount );
int reverseHalfValue = reverse % base;
int currentHalfValue = a % base;
if( reverseHalfValue == currentHalfValue ) return 0;
if( reverseHalfValue > currentHalfValue ) return (reverseHalfValue - currentHalfValue);
if( (((a-currentHalfValue)/base)%10) == 9 ){
//cases like 12945 or 1995
int newValue = a-currentHalfValue + base*10;
int diff = findNextPalin(newValue);
return base*10 - currentHalfValue + diff;
}
else{
return (base - currentHalfValue + reverseHalfValue );
}
}
}
$ java NextPalin
2 + 2 = 4
23 + 9 = 32
88 + 0 = 88
234 + 8 = 242
432 + 2 = 434
464 + 0 = 464
7887 + 0 = 7887
7657 + 10 = 7667
34567 + 76 = 34643
99874 + 25 = 99899
7779222 + 555 = 7779777
2569981 + 9771 = 2579752
3346990 + 443 = 3347433
229999 + 9933 = 239932
2299999 + 9033 = 2309032