Convert String to Long,No built in library - java

I wrote Java code to convert String to long. However, when dealing with overflow problem, I don't have clues how to solve it. If a number is overflowed, computer believe every number is legal in storage. How to let program, with 64bit jdk ,detect the real number is overflowed is the key problem. And I'm not allowed to use any built-in library such as parseLong or others.
public static long strTolong(String s){
//error checking
if(s == null) return 0;
s = s.trim();//remove all space character
boolean neg = false;//judge the number is negative or positive
int pos = 0 ; //index of string
long result = 0;
//check positive or negative
if(s.charAt(pos) == '-'){
neg = true;
pos++;
}else if(s.charAt(pos) == '+') pos++;
//calculate result
while(pos<s.length()){
if(s.charAt(pos) >='0' && s.charAt(pos) <='9'){
result = result*10+(s.charAt(pos) - '0');
}else
break;
pos++;
}
if(neg) result =-result;
//check overflow
if(result >Long.MAX_VALUE) {
return Long.MAX_VALUE;
}
if(result<Long.MIN_VALUE){
return Long.MIN_VALUE;
}
return result;
}
If data is larger than long.maxvalue, the result can't be stored in computer correctly.
How to solve this problem?

Your best option is probably to do a lexicographical comparison between the input and the minimum/maximum numbers before you start.
static int compare(String v1, String v2) {
boolean neg1 = v1.startsWith("-");
boolean neg2 = v2.startsWith("-");
return neg1 ? (neg2 ? -comparePositives(v1.substring(1),v2.substring(1)):-1)
: (neg2 ? 1 : comparePositives(v1, v2));
}
static int comparePositives(String v1, String v2) {
// Is one longer?
if (v1.length() != v2.length())
return v1.length() < v2.length() ? -1 : 1;
// Both empty?
if (v1.isEmpty())
return 0;
// First digit differs?
if (v1.charAt(0) != v2.charAt(0))
return v1.charAt(0) < v2.charAt(0) ? -1 : 1;
// Recurse on rest of number
return comparePositives(v1.substring(1), v2.substring(1));
}
Use it for instance as follows:
if (compare(s, ""+Long.MIN_VALUE) == -1)
throw new NumberFormatException("Input too small");
if (compare(s, ""+Long.MAX_VALUE) == 1)
throw new NumberFormatException("Input too large");
Tested here: http://ideone.com/HmMkJ3
Note that the code does not check that the input is well formed. I suggest you do such check first. (Be aware of cases like 0 and -0 etc.)

You could do the same thing that Long#parseLong would do:
throw new NumberFormatException("too long (pun intended): "+s);

I am not sure what you trying to achieve here. If String is greater than Long.MAX_VALUE means that is no more a Long value.
If your String value is withing the range of Long, you can use Long.parseLong() with out this kind of hard ways.
If you want to have huge number you can use BigDecimal easily
String max = Long.MAX_VALUE+"";
System.out.println(max);
long maxL=Long.parseLong(max)+1;
System.out.println(maxL);
BigDecimal bigDecimal=new BigDecimal(max).add(new BigDecimal("1"));
System.out.println(bigDecimal);
Out put:
9223372036854775807 // long max value
-9223372036854775808 // incorrect result in long
9223372036854775808 // BigDecimal gives you correct one
For your case you can throws an Exception if value is greater than Long.MAX_VALUE or lower than Long.MIN_VALUE

Related

Converting code python to Java that finds the minimum number of steps to get to 1

In this foobar coding question, you're supposed to return the minimum number of steps to get from the given String to the number 1. For example, with the parameter "15", the method would return 4. With the parameter 4, the method would return 2.
I've found the solution in python and was trying to convert to Java, but the Java code does not pass half of the secret tests(I do not know what[enter image description here] the test cases are) while the python code passes the tests. This is the python code:`
def solution(n):
n=int(n)
res = 0
while(n!=1):
if(n%2==0):
n=n/2
elif((n==3) or ((n+1)&n) > ((n-1)&(n-2))):
n-=1
else:
n+=1
res+=1
return res
` code passes are the cases. My question was trying to figure out what I'm doing wrong in my Java code. This is the Java code:
public static int solution(String x) {
int counter = 0;
int number = Integer.parseInt(x);
while(number != 1) {
if(number%2 == 0) {
number = number/2;
}
//else if(number == 3 || number%4 == 1) {
else if((number == 3) || ((number +1)&number) > ((number-1)&(number-2))) {
number-=1;
}
else {
number+=1;
}
counter+=1;
}
return counter;
}
`.

how to get decimal values as a new interger and traverse that integer from left to right?

I have a business case where I need to get the decimal values as a new integer and
then traverse it from left to right to evaluate.
Eg: I have a integer value int val=1345679;
square root of val is double sqrt_val=1160.03405122; //sqrt(1345679), decimal values are limit to 8 digits
Now I need decimal value(03405122) to store it into integer variable
int decimalValue=03405122;
With this decimal value I want to verify with some number which is given by business.
Let's take some number as 45.
now I have to verify decimalValue until it meets the below condition
03405122<=45 if yes just take the decimal value
if no then remove the 1st digit from left side until condition satisfiet
3405122<=45
405122<=45
05122<=45
5122<=45
122<=45
22<=45.
So, 22 is the number I have to take for further implementation.
This is the code which I have written, and give me some suggestions that If I can write in a better way.
// Extracting Decimal value
public int extractDecimal(int computeRandomNumber)
{
int _computeRandom = computeRandomNumber;
double sqrt = Math.sqrt(_computeRandom);
BigDecimal df;
df = round(sqrt, 8);
// System.out.println(df);
String sqrt_round = String.valueOf(df);
// System.out.println(sqrt_round);
int index = sqrt_round.lastIndexOf('.') + 1;
String sqrt_round_deci = sqrt_round.substring(index);
// System.out.println(sqrt_round_deci);
return Integer.parseInt(sqrt_round_deci);
}
//Comparing with the some number to find the random number
public int findRandomNumber(int value, int totalRange) {
int _val;
System.out.println("calling rec::: val:" + value);
if (value <= totalRange) {
System.out.println("Success... returing on final value:" + value);
return value;
}
String new_str = String.valueOf(value);
String final_str = new_str.substring(1);
// System.out.println("str:"+final_str);
int val = Integer.parseInt(final_str);
// System.out.println("val:"+val);
_val = findRandomNumber(val, totalRange);
return _val;
// System.out.println("Returning flag:"+flag);
}
Thanks in Advance!
As you provided a pseudo-code only question, I will be generous and provide a pseudo-code only answer:
1) Get the String value of sqrt_val
2) Use the substring() method to get only the places1 after the .
3) Loop through the length2 of said substring
4) Check on each iteration if the valueOf your String is less than your target
5a) If so, there's your result
5b) If not, get the substring starting from position 1
1 If this begins with a 0, your results may vary so I'll leave this for you to work out
2 If you use this way, be careful if your loop goes via String.length as you use a substring in the else
I am in no way convinced that this is the best solution but here's an alternative solution which doesn't use Strings.
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
// Value to be less than
BigDecimal lessThan = new BigDecimal(80);
int test = 333444;
BigDecimal bd = new BigDecimal( Math.sqrt(test) );
System.out.println(bd);
while( bd.scale() > 0 ) {
// get the fractional value and make it a whole number
BigDecimal fractionOnly = bd.divideAndRemainder(BigDecimal.ONE)[1];
fractionOnly = fractionOnly.movePointRight(fractionOnly.scale());
// do the check
System.out.println( fractionOnly + " < " + lessThan );
if ( fractionOnly.compareTo( lessThan ) < 0 ) {
System.out.println( "Yes" );
break;
}
// method kinda says it
bd = bd.movePointRight(1);
}
}
}

Format for number with floating point

I want to implement format with dynamic floating point for different length of input data in specified length for display. For example x.xxxx, xx.xxxx, xxx.xx, xxxx.x.
In other words,
if I have 1.4, I need 1.4000.
if 13.4 then I need 13.400, for every case length should be 5 digits (with no dot).
I'm using
DecimalFormat df2 = new DecimalFormat("000000");
but can't build a correct pattern. Is there any solution for this?
Thanks for helping.
The following is not production code. It doesn’t take a leading minus into account, nor very high values of the noDigits constant. But I believe you can use it as a starting point. Thanks to Mzf for inspiration.
final static int noDigits = 5;
public static String myFormat(double d) {
if (d < 0) {
throw new IllegalArgumentException("This does not work with a negative number " + d);
}
String asString = String.format(Locale.US, "%f", d);
int targetLength = noDigits;
int dotIx = asString.indexOf('.');
if (dotIx >= 0 && dotIx < noDigits) {
// include dot in result
targetLength++;
}
if (asString.length() < targetLength) { // too short
return asString + "0000000000000000000000".substring(asString.length(), targetLength);
} else if (asString.length() > targetLength) { // too long
return asString.substring(0, targetLength);
}
// correct length
return asString;
}

How to use an if function to call elements of an array

Basically, I have a variable 'prime'. It can only take values between 0 and 6. Based on its value, I want a string 'result' to be Sunday if prime is 0, Monday if 1, etc. Currently, it's coded this way:
String result = new String();
if (prime == 0)
{
result = "Sunday";
}
if (prime == 1)
{
result = "Monday";
}
if (prime == 2)
{
result = "Tuesday";
}
if (prime == 3)
{
result = "Wednesday";
}
if (prime == 4)
{
result = "Thursday";
}
if (prime == 5)
{
result = "Friday";
}
if (prime == 6)
{
result = "Saturday";
}
else
{
result = "Check your code.";
}
I'm wondering if there's a faster way to do this? I've created an array with the days of the week:
String[] days = new String[7];
days [0] = "Sunday";
days [1] = "Monday";
days [2] = "Tuesday";
days [3] = "Wednesday";
days [4] = "Thursday";
days [5] = "Friday";
days [6] = "Saturday";
How do I quickly and elegantly code it so that if the value of prime is 0, the string 'result' is the first element of the array, and so on until if prime is 6, the string 'result' is the seventh element?
You already have all the valid values stored in a simple lookup table, you just need to ensure that the requested value is within the range of available values.
The basic answer would be to do something like...
if (prime >= 0 && prime < days.length) {
result = days[prime];
} else {
result = prime + " is not within a valid range";
// Or throw an exception
}
What this does is makes sure that the prime value is within the valid range of acceptable values (0..days.length - 1), other wise it returns an error message (or you could throw an exception).
Remember, arrays are 0 indexed, hence the need to use < days.length (less then) and not <= days.length (less then or equals to)
You were close. For those saying Switch or if chains, it's overkill for this problem.
result = days[Math.abs(prime % days.length)];
The array acts like a switch statement, and the modulus operator wrapped in the Math.abs (absolute value) acts like a safety net to stay with in the valid range of the array 0-6.
Credits to #MadProgrammer for the Math.abs
From Tutorials Point
Modulus - Divides left hand operand by right hand operand and returns remainder
Why don't you use the DayOfWeek class?
import java.time.DayOfWeek;
and try this...
try {
DayOfWeek dayOfWeek = DayOfWeek.of(++prime);
System.out.println(dayOfWeek.getDisplayName(TextStyle.FULL, Locale.getDefault()));
} catch (java.time.DateTimeException ex) {
System.out.println("Invalid value for DayOfWeek");
}
Note that we have to do ++prime since your code starts in zero and the enum in one.
If you have to set Sunday as the first day (instead of Monday that is the first in the enum)... the minus method will do the trick:
DayOfWeek dayOfWeek = DayOfWeek.of(++prime).minus(1);
EDIT: advantages and disadvantages of the solution
Pros:
Don't require an object to maintain your days.
Don't use a conditional statement.
The text style and language can easily be changed.
Cons:
java 1.8 is required
You could simply do:
if (prime >= 0 && prime < days.length) result = days[prime];
else result = "Check your code."
Because prime is essentially the index of the day that you want.
You can use Enum and define yourself
public enum Week {
SUNDAY(1, "Sunday"), Monday(2, "Monday"), TUESDAY(3, "Tuesday"), WEDNESDAY(
4, "Wednesday"), THURSDAY(6, "Thursday"), FRIDAY(6, "Friday"), SATURDAY(
7, "Saturday");
private int id;
private String name;
static Map<Integer, String> map = new HashMap<Integer, String>();
static {
for (Week w : Week.values()) {
map.put(w.getId(), w.name);
}
}
private Week(int id, String name) {
this.setId(id);
this.setName(name);
}
public static String getNameById(int id) {
return map.get(id);
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
}

GOTO/Continue in Java Dynamic Programming

I have the following piece of code in Java implementing dynamic programming recursiverelatio:
public double routeCost() throws Exception {
double cost = Double.MAX_VALUE;
for (int l=i; l<=j; l++) {
if (! (customers.get(l) instanceof VehicleCustomer) )
continue;
double value = F(l,j) + (customers.get(l).distanceFrom(depot));
if (value < cost)
cost = value;
}
return cost;
}
private double F(int l, int m) {
//=========================== FIRST CASE ===========================
if (l==i && m==i) {
//System.out.println(i+","+j+","+l+","+m);
return firstCase();
}
//=========================== SECOND CASE ===========================
if (l==i && (i<m && m<=j) ) {
//System.out.println(i+","+j+","+l+","+m);
//analyses the possibility of performing all the soubtours based at heicle customert_i
return secondCase(i,m);
}
//=========================== GENERAL CASE ===========================
else {
System.out.println(i+","+j+","+l+","+m);
assert (customers.get(l) instanceof VehicleCustomer);
assert ( (i<l && l<=j) && (l<=m && m<=j) );
return Math.min(thirdCaseFirstTerm(l,m), thirdCaseSecondTerm(l,m));
}
}
private double firstCase() {
mainRoute.add(depot);
mainRoute.add(customers.get(i));
return depot.distanceFrom(customers.get(i));
}
private double secondCase(int i,int m) {
double caseValue = Double.MAX_VALUE;
int k = i;
while (k<m) {
double totalDemand=0;
for (int u=k+1; ( (u<=m) && (totalDemand<=truckCapacity) ); u++)
totalDemand += customers.get(u).getDemand();
double cost = F(i,k) + thita(i,k+1,m);
if (cost <= caseValue)
caseValue = cost;
k++;
}
return caseValue;
}
private double thirdCaseFirstTerm(int l, int m) {
double caseValue = Double.MAX_VALUE;
int k = i;
while (k<m) {
double totalDemand=0;
for (int u=k+1; ( (u<=m) && (totalDemand<=truckCapacity) ); u++)
totalDemand += customers.get(u).getDemand();
double cost = F(l,k) + thita(l,k+1,m);
if (cost <= caseValue)
caseValue = cost;
k++;
}
return caseValue;
}
private double thirdCaseSecondTerm(int l,int m) {
double caseValue = Double.MAX_VALUE;
int k = i;
for (Customer cust : customers) {
int h = customers.indexOf(cust);
if ( (!(cust instanceof VehicleCustomer)) || (h >=l)) {
continue;
}
double totalDemand=0;
for (int u=k+2; ( (u<=m) && (totalDemand<=truckCapacity) ); u++)
totalDemand += customers.get(u).getDemand();
double cost = F(h,k) + customers.get(h).distanceFrom(customers.get(l)) + thita(l,k+2,m);
if (cost < caseValue)
caseValue = cost;
}
return caseValue;
}
Method F(int,int) is invoked from the for loop in method routeCost().
I want to find a way to enforce that whenever the assertion assert (customers.get(l) instanceof VehicleCustomer);
` is not true, instead of going down to the return statement, I want to infrom the for loop from the routeCost() to continue to the next iteration. But F() has to return a value!
I know that what I'm trying to do violates almost every rule of object orientation, but I really need that.
You could throw an Exception in F() and catch it in routeCost().
This approach is much better than using assertions. They are rarely used in practice, and there's a good reason for this: exceptions are much more flexible and better suited for detecting errors, invalid input etc.
PS: When I say "rarely used", I base this statement on the fact that I saw hundreds of thousands of lines of Java code in the past years and I rarely came accross code that uses assertions.
You can return a special value like Double.NaN which you can check for with Double.isNaN(d)
You could make F() return a Double (instead of double) and return null in the case where your assert fails. Then have your outer for loop do a null check on the returned value before adding it, etc.
Why not replace the asserts with if statements? When the if-statements are true then calculate the value, otherwise return the MAX_VALUE of double. When F returns MAX_VALUE the cost will not be updated.
if (customers.get(l) instanceof VehicleCustomer) {
if ( (i<l && l<=j) && (l<=m && m<=j) ) {
return Math.min(thirdCaseFirstTerm(l,m), thirdCaseSecondTerm(l,m));
}
}
return Double.MAX_VALUE;
Use asserts during development to weed out things that should never happen in private methods. (Asserts can be switched off in production)
Throw an exception when something unexpected happens (e.g. a client of your class passes in invalid data).
However, from your question it seems you expect to get instances that are not VehicleCustomer, so asserts and exceptions are not the right approach here.
Peter Lawrey's and Jeff's answers will also work.

Categories