Translating My C++ Base64 Code to Java Not working - java

I'm trying to port my C++ code to Java but I'm having a hard time. The Java part isn't working but the C++ part is.
I get:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: 6 at
java.lang.AbstractStringBuilder.substring(AbstractStringBuilder.java:870)
at java.lang.StringBuilder.substring(StringBuilder.java:72) at
Foo.Encryption.EncodeB64(Encryption.java:57) at
Foo.Main.main(Main.java:9) Java Result: 1
That line points to: System.out.println(Base64Chars.charAt(BinToDecStr(Binaries.substring(0, 6))));
C++ Code (Works 100% of the time):
#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <windows.h>
#include <cmath>
const std::string Base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string DecToBinStr(int Num, int Padding)
{
int Bin = 0, Pos = 1;
std::stringstream SS;
while (Num > 0)
{
Bin += (Num % 2) * Pos;
Num /= 2;
Pos *= 10;
}
SS.fill('0');
SS.width(Padding);
SS << Bin;
return SS.str();
}
int BinToDecStr(std::string BinNumber)
{
int Dec = 0;
int Bin = strtol(BinNumber.c_str(), NULL, 10);
for (int I = 0; Bin > 0; I++)
{
if(Bin % 10 == 1)
{
Dec += (1 << I);
}
Bin /= 10;
}
return Dec;
}
std::string EncodeB64X(std::string StringToEncode)
{
std::string Binaries, Result;
std::size_t STE_Size = StringToEncode.size();
if(STE_Size)
{
for (std::size_t I = 0; I < STE_Size; I++)
Binaries += DecToBinStr(int(StringToEncode[I]), 8);
while(Binaries.size())
{
Result += Base64Chars[BinToDecStr(Binaries.substr(0, 6))];
Binaries.erase(0, 6);
}
}
return Result;
}
std::string DecodeB64X(std::string StringToEncode)
{
std::string Binaries, Result;
std::size_t STE_Size = StringToEncode.size();
if(STE_Size)
{
for (std::size_t I = 0; I < STE_Size - 1; I++)
Binaries += DecToBinStr(Base64Chars.find(StringToEncode[I]), 6);
Binaries += DecToBinStr(Base64Chars.find(StringToEncode[STE_Size - 1]), 8 - ((STE_Size - 1) * 6) % 8);
while(Binaries.size())
{
Result += char(BinToDecStr(Binaries.substr(0, 8)));
Binaries.erase(0, 8);
}
}
return Result;
}
int main()
{
std::string F = EncodeB64X("Just Testing");
std::cout<<F;
}
Now I tried to translate this to java but it doesn't work :S.
This is the java code:
public class BaseEncoder
{
private static final String Base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
boolean IsBase64(byte C) {
return (Character.isDigit(C) || (C == '+') || (C == '/') || Character.isAlphabetic(C));
}
private String PadLeft(String s, int n) {
StringBuilder SBuff = new StringBuilder();
for (int I = n - s.length(); I > 0; --I) {
SBuff.append('0');
}
SBuff.append(s);
return SBuff.toString();
}
private int BinToDecStr(String BinNumber) {
int Dec = 0;
int Bin = Integer.parseInt(BinNumber);
for (int I = 0; Bin > 0; ++I) {
if(Bin % 10 == 1) {
Dec += (1 << I);
}
Bin /= 10;
}
return Dec;
}
private String DecToBinStr(int Num, int Padding) {
int Bin = 0, Pos = 1;
String SS = new String();
while (Num > 0) {
Bin += (Num % 2) * Pos;
Num /= 2;
Pos *= 10;
}
SS = PadLeft(SS, Padding);
SS += Bin;
return SS;
}
String EncodeB64(String StringToEncode)
{
String Result = new String();
StringBuilder Binaries = new StringBuilder();
int STE_Size = StringToEncode.length();
if (STE_Size > 0) {
for (int I = 0; I < STE_Size; ++I) {
Binaries.append(DecToBinStr(StringToEncode.charAt(I), 8));
}
while(Binaries.length() > 0) {
System.out.println(Base64Chars.charAt(BinToDecStr(Binaries.substring(0, 6))));
Result += Base64Chars.charAt(BinToDecStr(Binaries.substring(0, 6)));
Binaries.delete(0, 6);
}
}
return Result;
}
String DecodeB64(String StringToEncode)
{
String Result = new String();
StringBuilder Binaries = new StringBuilder();
int STE_Size = StringToEncode.length();
if(STE_Size > 0) {
for (int I = 0; I < STE_Size - 1; I++) {
Binaries.append(DecToBinStr(Base64Chars.indexOf(StringToEncode.charAt(I)), 6));
}
Binaries.append(DecToBinStr(Base64Chars.indexOf(StringToEncode.charAt(STE_Size - 1)), 8 - ((STE_Size - 1) * 6) % 8));
while(Binaries.length() > 0) {
Result += (char)BinToDecStr(Binaries.substring(0, 8));
Binaries.delete(0, 8);
}
}
return Result;
}
}
Any idea what I'm doing wrong in Java?

substr(0,n) in std::string will return less than n characters if n is bigger than the length of the string. In Java, substring in such a situation will raise an exception. You need to make sure n isn't longer than the length of the string (something like str.substring(0, Math.min(6, str.length())).

Related

static string weird behavior Diamond Star Pattern problem

I'm trying to solve this problem given a number 5, we display:
*
*****
*********
*****
*
And so on. So you give it a number and it format it for you like above. I tried to solve it using this code bellow and I can't see where the problem is in my code.
public class Exe01 {
public static String space = "";//global space var
public static String ast = "";//global * var
public static String adjustAst(int numOfAst) {
Exe01.ast = "";
for (int i = numOfAst; i > 0; i--) {
Exe01.ast+="*";
}
return Exe01.ast;
}
public static String adjustSpaces(int numOfSpaces) {
Exe01.space = "";
for (int i = numOfSpaces; i > 0; i--) {
Exe01.space = Exe01.space + " ";
}
return Exe01.space;
}
public static void showAst(int num) {
if (num <= 0 || num % 2 == 0)
System.out.println("arg to the function need to be positive and odd");
else if (num == 1)
System.out.println("*");
else {
int mid = (int) (num / 2);
int numberOfSpaces = num - 1;
for (int i = 0; i < num; i++) {
int k = 0;
if (i < mid) {
k = k * 2 + 1;
System.out.println(Exe01.adjustSpaces(numberOfSpaces) + Exe01.adjustAst(k));
numberOfSpaces = numberOfSpaces - 2;
} else if (i == mid) {
numberOfSpaces = 0;
k = k * 2 + 1;
System.out.println(Exe01.adjustSpaces(numberOfSpaces) + Exe01.adjustAst(k));
numberOfSpaces = numberOfSpaces + 2;
} else {
k = k - 4;
System.out.println(Exe01.adjustSpaces(numberOfSpaces) + Exe01.adjustAst(k));
numberOfSpaces = numberOfSpaces + 2;
}
}
}
}
public static void main(String args[]) {
Exe01.showAst(5);
}
}
At compilation time it gives me this:
*
*
*

Find the maximum product of two non overlapping palindromic subsequences

I am trying to find the maximum product of two non overlapping palindromic sub-sequences of string s that we'll refer to as a and b. I came up with below code but it's not giving correct output:
public static int max(String s) {
int[][] dp = new int[s.length()][s.length()];
for (int i = s.length() - 1; i >= 0; i--) {
dp[i][i] = 1;
for (int j = i+1; j < s.length(); j++) {
if (s.charAt(i) == s.charAt(j)) {
dp[i][j] = dp[i+1][j-1] + 2;
} else {
dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);
}
}
}
return dp[0][s.length()-1];
}
For input string "acdapmpomp", we can choose a = "aca" and b ="pmpmp" to get a maximal product of score 3 * 5 = 15. But my program gives output as 5.
Firstly you should traverse the dp table to find out the length of longest palindromic subsequences using bottom up approach, then you can calculate the max product by multiplying dp[i][j] with dp[j+1][n-1] : Given below is the code in C++;
int longestPalindromicSubsequenceProduct(string x){
int n = x.size();
vector<vector<int>> dp(n,vector<int>(n,0));
for(int i=0;i<n;i++){
dp[i][i] = 1;
}
for(int k=1;k<n;k++){
for(int i=0;i<n-k;i++){
int j = i + k;
if(x[i]==x[j]){
dp[i][j] = 2 + dp[i+1][j-1];
} else{
dp[i][j] = max(dp[i][j-1],dp[i+1][j]);
}
}
}
int maxProd = 0;
for(int i=0;i<n;i++){
for(int j=0;j<n-1;j++){
maxProd = max(maxProd,dp[i][j]*dp[j+1][n-1]);
}
}
return maxProd;
}
int multiplyPalindrome(string s) {
int n=s.size(),m=0;
vector<vector<int>> dp(n, vector<int> (n));
for(int i=0;i<n;i++) dp[i][i]=1;
for (int cl=2; cl<=n; cl++) {
for (int i=0; i<n-cl+1; i++){
int j = i+cl-1;
if (s[i] == s[j] && cl == 2) dp[i][j] = 2;
else if (s[i] == s[j]) dp[i][j] = dp[i+1][j-1] + 2;
else dp[i][j] = max(dp[i][j-1], dp[i+1][j]);
}
}
for(int i=0;i<n-1;i++){
m = max( m, dp[0][i]*dp[i+1][n-1] );
}
return m;
}
int palSize(string &s, int mask) {
int p1 = 0, p2 = s.size(), res = 0;
while (p1 <= p2) {
if ((mask & (1 << p1)) == 0)
++p1;
else if ((mask & (1 << p2)) == 0)
--p2;
else if (s[p1] != s[p2])
return 0;
else
res += 1 + (p1++ != p2--);
}
return res;
}
int maxProduct(string s) {
int mask[4096] = {}, res = 0;
for (int m = 1; m < (1 << s.size()); ++m)
mask[m] = palSize(s, m);
for (int m1 = 1; m1 < (1 << s.size()); ++m1)
if (mask[m1])
for (int m2 = 1; m2 < (1 << s.size()); ++m2)
if ((m1 & m2) == 0)
res = max(res, mask[m1] * mask[m2]);
return res;
}
You can loop through all non-overlapping palindromic subsequences and return the maximum value.
public int longestPalindromicSubsequenceProduct(String str) {
int maxProduct = 0;
for (int k = 0; k < str.length(); k++) {
String left = str.substring(0, k);
String right = str.substring(k);
int currProduct = longestPalindromicSubsequence(left) * longestPalindromicSubsequence(right);
maxProduct = Math.max(maxProduct, currProduct);
}
return maxProduct;
}
private int longestPalindromicSubsequence(String org) {
String rev = new StringBuilder(org).reverse().toString();
return longestCommonSubsequence(org, rev);
}
private int longestCommonSubsequence(String str1, String str2) {
int rows = str1.length();
int cols = str2.length();
int[][] dp = new int[rows + 1][cols + 1];
for (int r = 1; r <= rows; r++) {
for (int c = 1; c <= cols; c++) {
if (str1.charAt(r - 1) == str2.charAt(c - 1)) dp[r][c] = 1 + dp[r - 1][c - 1];
else dp[r][c] = Math.max(dp[r - 1][c], dp[r][c - 1]);
}
}
return dp[rows][cols];
}
Your algorithm returns the maximum length of a palyndrome, not the maximum of the product of two lengths.
UPDATE
Here's a possible solution:
public static int max(String s) {
int max = 0;
for (int i = 1; i < s.length()-1; ++i) {
String p1 = bestPalyndrome(s, 0, i);
String p2 = bestPalyndrome(s, i, s.length());
int prod = p1.length()*p2.length();
if (prod > max) {
System.out.println(p1 + " " + p2 + " -> " + prod);
max = prod;
}
}
return max;
}
private static String bestPalyndrome(String s, int start, int end) {
if (start >= end) {
return "";
} else if (end-start == 1) {
return s.substring(start, end);
} else if (s.charAt(start) == s.charAt(end-1)) {
return s.charAt(start) + bestPalyndrome(s, start+1, end-1)
+ s.charAt(end-1);
} else {
String s1 = bestPalyndrome(s, start, end-1);
String s2 = bestPalyndrome(s, start+1, end);
return s2.length() > s1.length() ? s2 : s1;
}
}

Need help translating java program to C

This program does the division for very large numbers (i need it just up to 1000 digits). because no data type can handle very large numbers we use arrays.
I'm trying to translate this Java program to C. I have done some of it but having troubles converting strings to a C compatible data type. remember we need to take numbers as string then convert to int.
the biggest challenge seems to be String, StringBuilder and append. i have no idea how to translate these.
having most trouble with:
if (len1 < len2) return new String[]{"0", n1};
StringBuilder digits = new StringBuilder();
String n3 = n1.substring(0, len2);
Java code:
import java.io.*;
import java.util.*;
class BigDiv
{
public static void main(String[] args)
{
String n1 = "30";
String n2 = "2";
String[] results = Divide(n1, n2);
System.out.println("Quotient is : " + results[0]);
System.out.println("Remainder is : " + results[1]);
}
static String[] Divide(String n1, String n2)
{
Boolean negative = false;
if (n1.charAt(0) == '-' ^ n2.charAt(0) == '-') negative = true;
if (n1.charAt(0) == '-') n1 = n1.substring(1);
if (n2.charAt(0) == '-') n2 = n2.substring(1);
if (n1.equals("0") && n2.equals("0"))
{
return new String[] {"Not a number", "0"};
}
if (n2.equals("0"))
{
if (!negative) return new String[] {"Infinity", "0"};
return new String[] {"-Infinity", "0"};
}
int len1 = n1.length();
int len2 = n2.length();
if (len1 < len2) return new String[]{"0", n1};
StringBuilder digits = new StringBuilder();
String n3 = n1.substring(0, len2);
int len3 = len2;
String n4;
int quotient;
int index = len2 - 1;
while(true)
{
quotient = 0;
while(true)
{
n4 = Subtract(n3, n2);
if (n4 == "-1")
{
break;
}
quotient++;
//System.out.println(quotient);
if (n4 == "0")
{
n3 = "0";
break;
}
n3 = n4;
}
if (digits.toString().equals("0"))
{
digits.setCharAt(0, (char)(quotient + 48));
}
else
{
digits.append((char)(quotient + 48));
}
if (index < len1 - 1)
{
index++;
if (n3.equals("0")) n3 = "";
n3 += n1.charAt(index);
len3 = n3.length();
}
else
{
String result = new String(digits);
if (negative)
{
if (!result.equals("0")) result = "-" + result;
if (!n3.equals("0")) n3 = "-" + n3;
}
return new String[]{result, n3};
}
}
}
static String Subtract(String n1, String n2)
{
int len1 = n1.length();
int len2 = n2.length();
if (len1 < len2) return "-1";
int max = Math.max(len1, len2);
int[] ia1 = new int[max];
int[] ia2 = new int[max];
int[] ia3 = new int[max];
for(int i = max - len1; i < max; i++) ia1[i] = n1.charAt(i + len1 - max) - 48;
for(int i = max - len2; i < max; i++) ia2[i] = n2.charAt(i + len2 - max) - 48;
int diff = 0;
int carry = 0;
for(int i = max - 1; i >= 0; i--)
{
diff = ia1[i] - ia2[i] - carry;
carry = 0;
if (diff < 0)
{
diff += 10;
carry = 1;
}
ia3[i] = diff;
}
if (carry == 1) return "-1";
// find first non-zero element of array ia3
int first = -1;
for (int i = 0; i < max; i++)
{
if (ia3[i] != 0)
{
first = i;
break;
}
}
if (first == -1) first = max - 1;
char[] c3 = new char[max - first];
for(int i = first; i < max; i++) c3[i - first] = (char)(ia3[i] + 48);
//System.out.println("c IS : " + c3[0]);
return new String(c3);
}
my C code so far: (in divide function there is a check for NaN and Negative numbers which i don't really need. also i should not use VLA.)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int Divide(char n1[], char n2[]);
int Subtract(char n1[], char n2[]);
int main()
{
char n1[] = "30";
char n2[] = "2";
char results[] = Divide(n1, n2);
printf("Quotient is : %d", results[0]);
printf("Remainder is : %d", results[1]);
}
int Divide(char n1[], char n2[])
{
/*Boolean negative = false;
if (n1[0] == '-' ^ n2[0] == '-') negative = true;
if (n1[0] == '-') n1 = n1.substring(1);
if (n2[0] == '-') n2 = n2.substring(1);
if (n1.equals("0") && n2.equals("0"))
{
return new String[] {"Not a number", "0"};
}
if (n2.equals("0"))
{
if (!negative) return new String[] {"Infinity", "0"};
return new String[] {"-Infinity", "0"};
}*/
int len1 = strlen(n1);
int len2 = strlen(n2);
if (len1 < len2) return new String[]{"0", n1};
StringBuilder digits = new StringBuilder();
String n3 = n1.substring(0, len2);
int len3 = len2;
String n4;
int quotient;
int index = len2 - 1;
while(true)
{
quotient = 0;
while(true)
{
n4 = Subtract(n3, n2);
if (n4 == "-1")
{
break;
}
quotient++;
if (n4 == "0")
{
n3 = "0";
break;
}
n3 = n4;
}
if (digits.toString().equals("0"))
{
digits.setCharAt(0, (char)(quotient + 48));
}
else
{
digits.append((char)(quotient + 48));
}
if (index < len1 - 1)
{
index++;
if (n3.equals("0")) n3 = "";
n3 += n1[index];
len3 = n3.length();
}
else
{
String result = new String(digits);
if (negative)
{
if (!result.equals("0")) result = "-" + result;
if (!n3.equals("0")) n3 = "-" + n3;
}
return new String[]{result, n3};
}
}
}
int Subtract(char n1[], char n2[])
{
int len1 = n1.length();
int len2 = n2.length();
if (len1 < len2) return "-1";
int max;
if(len1>len2) max = len1;
else if(len2>len1) max = len2;
else max = len1;
int ia1[max];
int ia2[max];
int ia3[max];
for(int i = max - len1; i < max; i++) ia1[i] = n1[i + len1 - max] - 48;
for(int i = max - len2; i < max; i++) ia2[i] = n2[i + len2 - max] - 48;
int diff = 0;
int carry = 0;
for(int i = max - 1; i >= 0; i--)
{
diff = ia1[i] - ia2[i] - carry;
carry = 0;
if (diff < 0)
{
diff += 10;
carry = 1;
}
ia3[i] = diff;
}
if (carry == 1) return "-1";
// find first non-zero element of array ia3
int first = -1;
for (int i = 0; i < max; i++)
{
if (ia3[i] != 0)
{
first = i;
break;
}
}
if (first == -1) first = max - 1;
char c3[max - first];
for(int i = first; i < max; i++) c3[i - first] = (char)(ia3[i] + 48);
return new String(c3);
}
Strings in C are simply sequences of characters terminated by a 0-valued byte. There is no dedicated string type; they are stored as arrays of char, and operators such as =, +, and == are not defined for arrays.
To assign strings, use the strcpy library function. To append strings to each other, you use the strcat library function. To compare strings, use strcmp.
You must do your own memory management; C will not automatically allocate more memory as you extend a string, nor will it do any automatic garbage collection when there are no more references to that memory, meaning you must explicitly deallocate any dynamically allocated memory. Use malloc or calloc to allocate memory, realloc to allocate or extend a buffer that's been allocated with malloc, calloc, or realloc, and free to deallocate memory that was allocated with malloc, calloc, or realloc.
malloc does not initialize the dynamically-allocated memory; calloc will initialize it to all-bits-0.
Here's some sample C code that will allocate, assign, append, compare, and deallocate a string:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define INITIAL_SIZE 20
int main( void )
{
/**
* Allocate space to store a string; the +1 is to make sure
* we have space for the 0 terminator.
*/
char *str1 = calloc( INITIAL_SIZE+1, sizeof *str1 );
size_t str1size = INITIAL_SIZE + 1;
/**
* str2 will point to a string literal; literals are stored as
* arrays of char such that they are allocated at program startup
* and held until the program terminates. String literals may
* not be modified, so we're declaring the pointer as const char *.
*/
const char *str2 = " of the Emergency Broadcast System";
/**
* Copy a string to that buffer
*/
strcpy( str1, "This is a test" );
/**
* Extend the buffer to hold more stuff; typical strategy is
* to double the buffer size each time. For this particular
* example this loop should only run once.
*/
while ( strlen( str1 ) + strlen( str2 ) > str1size)
{
char *tmp = realloc( str1, 2 * str1size );
if ( !tmp )
{
// realloc failed, for this example we treat it as a fatal error
exit( -1 );
}
str1 = tmp;
str1size *= 2;
}
/**
* Append to the buffer
*/
strcat( str1, str2 );
// do something interesting with str1 here
/**
* Deallocate the buffer
*/
free( str1 );
return 0;
}
You must make sure your target buffer is large enough to hold whatever you're writing to it. C doesn't do bounds checking on array accesses, and it won't throw an exception if you try to read or write outside of the array bounds (unless you're trying to access protected memory, but that's a system exception, not a language exception).

readHexInteger from java to nodejs

Got this code in java :
public static int readHexInteger(ChannelBuffer buf, int length) {
int result = 0;
for (int i = 0; i < length / 2; i++) {
int b = buf.readUnsignedByte();
result *= 10;
result += b >>> 4;
result *= 10;
result += b & 0x0f;
}
if (length % 2 == 1) {
int b = buf.getUnsignedByte(buf.readerIndex());
result *= 10;
result += b >>> 4;
}
return result;
}
I'm trying to code the same thing but with nodejs.
Is there any java/nodejs hacker in the room ?
Thanks in advance !

Reverse Integer leetcode -- how to handle overflow

The problem is:
Reverse digits of an integer.
Example1: x = 123, return 321
Example2: x = -123, return -321
Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases?
Throw an exception? Good, but what if throwing an exception is not an option? You would then have to re-design the function (ie, add an extra parameter).
The solution from the website I search is:
public class Solution {
public static int reverse(int x) {
int ret = 0;
boolean zero = false;
while (!zero) {
ret = ret * 10 + (x % 10);
x /= 10;
if(x == 0){
zero = true;
}
}
return ret;
}
public static void main(String[] args) {
int s = 1000000003;
System.out.println(reverse(s));
}
}
However when s = 1000000003, the console prints -1294967295 instead of 3000000001. So this solution still does not solve the overflow problem if we cannot use exception. Any help here?(Although there is a hint: add an extra parameter, I still cannot figure out what parameter I should add)
There's no need for any data type other than int.
Just make sure when there's an operation that increases a number, reversing the operation should give you the previous number. Otherwise, there's overflow.
public int reverse(int x) {
int y = 0;
while(x != 0) {
int yy = y*10 + x%10;
if ((yy - x%10)/10 != y) return 0;
else y = yy;
x = x/10;
}
return y;
}
Above most of the answers having a trivial problem is that the int variable possibly might overflow. You can try this : x = -2147483648 as parameter.
There has an easy way to solve the problem. Convert x to long, and check if the result >= Integer.MAX_VALUE, otherwise return 0.
The solution passed all test cases on https://leetcode.com/problems/reverse-integer/
This is a java version.
public int reverse(int x) {
long k = x;
boolean isNegtive = false;
if(k < 0){
k = 0 - k;
isNegtive = true;
}
long result = 0;
while(k != 0){
result *= 10;
result += k % 10;
k /= 10;
}
if(result > Integer.MAX_VALUE) return 0;
return isNegtive ? 0 - ((int)result) : (int)result;
}
C# version
public int Reverse(int x)
{
long value = 0;
bool negative = x < 0;
long y = x;
y = Math.Abs(y);
while (y > 0)
{
value *= 10;
value += y % 10;
y /= 10;
}
if(value > int.MaxValue)
{
return int.MaxValue;
}
int ret = (int)value;
if (negative)
{
return 0 - ret;
}
else
{
return ret;
}
}
Python version
def reverse(self, x):
isNegative = x < 0
ret = 0
x = abs(x)
while x > 0:
ret *= 10
ret += x % 10
x /= 10
if ret > 1<<31:
return 0
if isNegative:
return 0 - ret
else:
return ret
This java code handles the overflow condition:
public int reverse(int x) {
long reverse = 0;
while( x != 0 ) {
reverse = reverse * 10 + x % 10;
x = x/10;
}
if(reverse > Integer.MAX_VALUE || reverse < Integer.MIN_VALUE) {
return 0;
} else {
return (int) reverse;
}
}
This is an old question, but anyway let me have a go at it too! I just solved it on leetcode. With this check, you never hit the overflow/ underflow in either direction, and I think the code is more concise than all the listed codes. It passes all test cases.
public int reverse(int x) {
int y = 0;
while(x != 0) {
if(y > Integer.MAX_VALUE/10 || y < Integer.MIN_VALUE/10) return 0;
y *= 10;
y += x % 10;
x /= 10;
}
return y;
}
you can try this code using strings in java
class Solution {
public int reverse(int x) {
int n = Math.abs(x);
String num = Integer.toString(n);
StringBuilder sb = new StringBuilder(num);
sb.reverse();
String sb1;
sb1 = sb.toString();
int foo;
try {
foo = Integer.parseInt(sb1);
}
catch (NumberFormatException e){
foo = 0;
}
if(x < 0){
foo *= -1;
}
return foo;
}
}
My soluton for this problem is to convert integer inputed to c-string, then everthing will be easy.
class Solution {
public:
int reverse(int x) {
char str[11];
bool isNegative = false;
int i;
int ret = 0;
if ( x < 0 ) {
isNegative = true;
x = -x;
}
i = 0;
while ( x != 0 ) {
str[i++] = x % 10 + '0';
x = x / 10;
}
str[i] = '\0';
if ( (isNegative && strlen(str) == 10 && strcmp(str, "2147483648") > 0) || (!isNegative && strlen(str) == 10 && strcmp(str, "2147483647") > 0) ) {
cout << "Out of range!" << endl;
throw new exception();
}
i = 0;
int strLen = (int)strlen(str);
while ( str[i] != '\0' ) {
ret += ((str[i] - '0') * pow(10.0, strLen - 1 - i));
i++;
}
return (isNegative ? -ret : ret);
}
};
This works:
public class Solution {
public int reverse(int x) {
long tmp = Math.abs((long)x);
long res = 0;
while(tmp >= 10){
res += tmp%10;
res*=10;
tmp=tmp/10;
}
res+=tmp;
if(x<0){
res = -res;
}
return (res>Integer.MAX_VALUE||res<Integer.MIN_VALUE)? 0: (int)res;
}
}
I tried to improve the performance a bit but all I could come up with was this:
public class Solution {
public int reverse(int x) {
long tmp = x;
long res = 0;
if(x>0){
while(tmp >= 10){
res += tmp%10;
res*=10;
tmp=tmp/10;
}
}
else{
while(tmp <= -10){
res += tmp%10;
res*=10;
tmp=tmp/10;
}
}
res+=tmp;
return (res>Integer.MAX_VALUE||res<Integer.MIN_VALUE)? 0: (int)res;
}
}
Its C# equivalent runs 5% faster than the 1st version on my machine, but their server says it is slower, which can't be - I got rid of extra function call here, otherwise it is essentially the same. It places me between 60-30% depending on the language (C# or Java). Maybe their benchmarking code is not very good - if you submit several times - resulting times vary a lot.
Solution In Swift 4.0 (in reference to problem from https://leetcode.com/problems/reverse-integer/description/)
func reverse(_ x : Int) -> Int {
var stringConversion = String(x)
var negativeCharacter = false
var finalreversedString = String()
let signedInt = 2147483647 //Max for Int 32
let unSignedInt = -2147483647 // Min for Int 32
if stringConversion.contains("-"){
stringConversion.removeFirst()
negativeCharacter = true
}
var reversedString = String(stringConversion.reversed())
if reversedString.first == "0" {
reversedString.removeFirst()
}
if negativeCharacter {
finalreversedString = "-\(reversedString)"
} else {
finalreversedString = reversedString
}
return (x == 0 || Int(finalreversedString)! > signedInt || Int(finalreversedString)! < unSignedInt) ? 0 : Int(finalreversedString)!
}
Last night, i have tried this same problem and i have found a simple solution in python, which is given below, here after checking the number type positive or negative, though i have tried in different section for both of them, i have convert the negative number into positive and before returning the reverse number, i had converted the number into negative.
For handling overflow, i have just simply checked with the upper limit of our 32-bit signed number and lower limit of the number, and it accepted my answer, thank you.
class Solution:
def reverse(self, x: int):
reverse = 0
if x > 0:
while x != 0:
remainder = x % 10
if reverse > (2147483647/10):
return 0
reverse = reverse * 10 + remainder
x = int(x / 10)
return reverse
elif x < 0:
x = x * (-1)
while x != 0:
remainder = x % 10
if reverse > ((2147483648)/10):
return 0
reverse = reverse * 10 + remainder
x = int(x / 10)
reverse = reverse * (-1)
return reverse
else:
return 0
public static int reverse(int x) {
boolean pos = x >= +0;
int y = (pos) ? x : -x;
StringBuilder sb = new StringBuilder(
String.valueOf(y));
sb.reverse();
int z = Integer.parseInt(sb.toString());
return pos ? z : -z;
}
public static void main(String[] args) {
for (int i = -10; i < 11; i++) {
System.out.printf("%d r= '%d'\n", i, reverse(i));
}
}
Outputs
-10 r= '-1'
-9 r= '-9'
-8 r= '-8'
-7 r= '-7'
-6 r= '-6'
-5 r= '-5'
-4 r= '-4'
-3 r= '-3'
-2 r= '-2'
-1 r= '-1'
0 r= '0'
1 r= '1'
2 r= '2'
3 r= '3'
4 r= '4'
5 r= '5'
6 r= '6'
7 r= '7'
8 r= '8'
9 r= '9'
10 r= '1'
Did you notice the reverse of 10 and -10? Or 20? You could just return a String, for example
public static String reverse(int x) {
boolean pos = x >= +0;
int y = (pos) ? x : -x;
StringBuilder sb = new StringBuilder(
String.valueOf(y));
sb.reverse();
if (!pos) {
sb.insert(0, '-');
}
return sb.toString();
}
public static void main(String[] args) {
for (int i = -10; i < 11; i++) {
System.out.printf("%d r= '%s'\n", i, reverse(i));
}
}
Works as I would expect.
If you are required to return a 32 bit int, and still need to know if there was an overflow perhaps you could use a flag as an extra parameter. If you were using c or c++ you could use pointers to set the flag, or in Java you can use an array (since Java objects pass by value).
Java example:
public class Solution {
public static int reverse(int x, Boolean[] overflowed) {
int ret = 0;
boolean zero = false;
boolean inputIsNegative = x < 0;
while (!zero) {
ret = ret * 10 + (x % 10);
x /= 10;
if(x == 0){
zero = true;
}
}
//Set the flag
if ( (inputIsNegative && (ret > 0)) || ((!inputIsNegative) && (ret < 0)))
overflowed[0] = new Boolean(true);
else
overflowed[0] = new Boolean(false);
return ret;
}
public static void main(String[] args) {
int s = 1000000004;
Boolean[] flag = {null};
System.out.println(s);
int n = reverse(s,flag); //reverse() will set the flag.
System.out.println(flag[0].booleanValue() ? "Error: Overflow": n );
}
}
Notice if the reversed number is too large for a 32 bit integer the flag will be set.
Hope this helps.
Use string to store the reverse and then print or use long or BigInt
public class Solution {
/**
* OVERFLOW
* #param x
* #return
*/
public int reverse(int x) {
int sign = x>0? 1: -1;
x *= sign;
int ret = 0;
while(x>0) {
ret *= 10;
if(ret<0 || x>10&&ret*10/10!=ret) // overflow
return 0;
ret += x%10;
x /= 10;
}
return ret*sign;
}
public static void main(String[] args) {
assert new Solution().reverse(-2147483412)==-2147483412;
}
}
public class Solution {
public int Reverse(int x) {
var sign = x < 0 ? -1 : 1;
var reverse = 0;
if (x == int.MinValue)
{
return 0;
}
x = Math.Abs(x);
while(x > 0)
{
var remainder = x % 10;
if (reverse > ((int.MaxValue - remainder)/10))
{
return 0;
}
reverse = (reverse*10) + remainder;
x = x/10;
}
return sign * Convert.ToInt32(reverse);
}
}
Here we will use long to handle the the over flow:
public class Solution {
public int reverse(int A) {
// use long to monitor Overflow
long result = 0;
while (A != 0) {
result = result * 10 + (A % 10);
A = A / 10;
}
if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) {
return 0;
} else {
return (int) result;
}
}
}
Well This Suitable Code in Java Can be:-
public class Solution {
public int reverse(int x) {
int r;
long s = 0;
while(x != 0)
{
r = x % 10;
s = (s * 10) + r;
x = x/10;
}
if(s >= Integer.MAX_VALUE || s <= Integer.MIN_VALUE) return 0;
else
return (int)s;
}
}
My solution without using long:
public class ReverseInteger {
public static void main(String[] args) {
int input = Integer.MAX_VALUE;
int output = reverse(input);
System.out.println(output);
}
public static int reverse(int x) {
int remainder = 0;
int result = 0;
if (x < 10 && x > -10) {
return x;
}
while (x != 0) {
remainder = x % 10;
int absResult = Math.abs(result);
int maxResultMultipliedBy10 = Integer.MAX_VALUE / 10;
if (absResult > maxResultMultipliedBy10) {
return 0;
}
int resultMultipliedBy10 = absResult * 10;
int maxRemainder = Integer.MAX_VALUE - resultMultipliedBy10;
if (remainder > maxRemainder) {
return 0;
}
result = result * 10 + remainder;
x = x / 10;
}
return result;
}
}
here is the JavaScript solution.
/**
* #param {number} x
* #return {number}
*/
var reverse = function(x) {
var stop = false;
var res = 0;
while(!stop){
res = res *10 + (x % 10);
x = parseInt(x/10);
if(x==0){
stop = true;
}
}
return (res <= 0x7fffffff && res >= -0x80000000) ? res : 0
};
Taking care if the input is negative
public int reverse(int x)
{
long result = 0;
int res;
int num = Math.abs(x);
while(num!=0)
{
int rem = num%10;
result = result *10 + rem;
num = num / 10;
}
if(result > Integer.MAX_VALUE || result < Integer.MIN_VALUE)
{
return 0;
}
else
{
res = (int)result;
return x < 0 ? -res : res;
}
}
This solution in Java will work:
class Solution {
public int reverse(int x) {
long rev = 0, remainder = 0;
long number = x;
while (number != 0) {
remainder = number % 10;
rev = rev * 10 + remainder;
number = number / 10;
}
if (rev >= Integer.MAX_VALUE || rev <= Integer.MIN_VALUE || x >= Integer.MAX_VALUE || x <= Integer.MIN_VALUE)
return 0;
else
return (int) rev;
}
}
Much simpler solution. Ensure that intermittent result does not exceed INT_MAX or get below INT_MIN
int reverse(int x) {
int y = 0;
while(x != 0) {
if ( (long)y*10 + x%10 > INT_MAX || (long)y*10 + x%10 < INT_MIN) {
std::cout << "overflow occurred" << '\n'
return 0;
}
y = y*10 + x%10;
x = x/10;
}
return y;
}
Here is the solution coded in JS(Javascript, it has passed all the 1032 test cases successfully in Leetcode for the problem (https://leetcode.com/problems/reverse-integer), also as asked in the question about the same.
/**
* #param {number} x
* #return {number}
*/
var reverse = function(x) {
let oldNum = x, newNum = 0, digits = 0, negativeNum = false;
if(oldNum < 0){
negativeNum = true;
}
let absVal = Math.abs(x);
while(absVal != 0){
let r = Math.trunc(absVal % 10);
newNum = (newNum*10) + r; digits++;
absVal = Math.floor(absVal/10);
}
if( !(newNum < Number.MAX_VALUE && newNum >= -2147483648 && newNum <= 2147483647)){
return 0;
}
return negativeNum ? -newNum :newNum;
};
Here is the solution coded in JS(Javascript, it has passed all the 1032 test cases successfully in Leetcode for the problem (https://leetcode.com/problems/reverse-integer), also as asked in the question about the same.
/**
* #param {number} x
* #return {number}
*/
var reverse = function(x) {
let oldNum = x, newNum = 0, digits = 0, negativeNum = false;
if(oldNum < 0){
negativeNum = true;
}
let absVal = Math.abs(x);
while(absVal != 0){
let r = Math.trunc(absVal % 10);
newNum = (newNum*10) + r; digits++;
absVal = Math.floor(absVal/10);
}
if( !(newNum < Number.MAX_VALUE && newNum >= -2147483648 && newNum <= 2147483647)){
return 0;
}
return negativeNum ? -newNum :newNum;
};
The earlier answer was posted by the same user (unregistered). Consider this one.
There are several good solutions posted. Here is my JS solution:
const reverse = function (x) {
const strReversed = x.toString().split("").reverse().join("");
rv =
parseInt(strReversed) > Math.pow(2, 31)
? 0
: Math.sign(x) * parseInt(strReversed);
return rv;
};
I got all 1032 cases to work in python, I don't know how to remove multiple 0's such as 100, 1000, 10000 etc thus I used my if statement multiple times lol.
class Solution:
def reverse(self, x: int) -> int:
string = ""
y = str(x)
ab = list(reversed(y))
if len(ab) > 1 and ab[0] == "0":
ab.remove("0")
if len(ab) > 1 and ab[0] == "0":
ab.remove("0")
if len(ab) > 1 and ab[0] == "0":
ab.remove("0")
if len(ab) > 1 and ab[0] == "0":
ab.remove("0")
if len(ab) > 1 and ab[0] == "0":
ab.remove("0")
if ab[-1] == "-":
ab.remove("-")
ab.insert(0, "-")
for i in ab:
string += i
if int(string) > 2**31 - 1 or int(string) < -2**31:
return 0
return string
public static int reverse(int x) {
if (x == 0) return 0;
int sum = 0;
int y = 0;
while (x != 0) {
int value = (x % 10);
x = x - value;
y = sum;
sum = (sum * 10) + value;
if(sum / 10 != y) return 0;
x = x / 10;
}
return sum;
}
Extracting the first digit and dividing x to ten until x will be equal to 0. Therefore integer will be tokenized its digits.
Every extracted value will be adding the sum value after multiplying the sum by 10. Because adding a new digit means that adding a new 10th to the sum value. Also added if block to check any corruption of data because after 9th digit data will be corrupted.
1032 / 1032 test cases passed.
Status: Accepted
Runtime: 3 ms
Memory Usage: 38 MB
Public int reverse(int A) {
int N, sum = 0;
int rem = 0;
boolean flag = false;
int max = Integer.MAX_VALUE;
int min = Integer.MIN_VALUE;
if (A < 0) {
flag = true;
A = A * -1;} // 123 // 10 1
while (A > 0) {
rem = A % 10;
if (flag == true) {
if ((min + rem) / 10 > -sum) {
return 0;}}else{
if ((max - rem) / 10 < sum) {
return 0;}}
sum = (sum * 10) + rem;
A = A / 10;}
return (flag == true) ? —sum : sum;}}
#java #Algo
def reverse(self, x: int) -> int:
if x<=-2**31 or x>=2**31-1:
return 0
else:
result = 0
number = x
number = abs(number)
while (number) > 0:
newNumber = number % 10
result = result * 10 + newNumber
number = (number // 10)
if x<0:
result = "-"+str(result)
if int(result)<=-2**31:
return 0
return result
else:
if result>=2**31-1:
return 0
return result
if __name__ == '__main__':
obj = Solution()
print(obj.reverse(1534236469))
Note that there are previous solutions that do not work for input: 1000000045
try this:
public int reverse(int A) {
int reverse=0;
int num=A;
boolean flag=false;
if(A<0)
{
num=(-1)*A;
flag=true;
}
int prevnum=0;
while(num>0)
{
int currDigit=num%10;
reverse=reverse*10+currDigit;
if((reverse-currDigit)/10!=prevnum)
return 0;
num=num/10;
prevnum=reverse;
}
if(flag==true)
reverse= reverse*-1;
return reverse;
}

Categories

Resources