Java Issue with replace spaces using regex - java

This is for a fraction class. When i test the fraction class with a string like "2/4" I get the following exception:
java.lang.NumberFormatException: For input string: "".
I think it has something to do with the sStringTo method when trying to replace spaces.
public class Util{
static int findGCF(int a, int b){
a = Math.abs(a);
b = Math.abs(b);
while(a != b){
if (a>b) a = a-b; else b = b-a;
}
return (a);
}
static Fraction sIntTo(String s){ //"2"
int n = Integer.parseInt(s);
return new Fraction(n);
}
static Fraction sFractionTo(String s){ //"2/3"
s = s.trim();
int posSlash = s.indexOf("/");
int n = Integer.parseInt(s.substring(0,posSlash));
int m = Integer.parseInt(s.substring(posSlash + 1));
return new Fraction(n,m);
}
static Fraction sMixTo(String s){
s =s.trim();
int posB = s.indexOf(" ");
int posSlash = s.indexOf("/");
int w = Integer.parseInt(s.substring(0,posB));
int t = Integer.parseInt(s.substring(posB+1, posSlash));
int b = Integer.parseInt(s.substring(posSlash+1));
return new Fraction(w*b+t,b);
}
static Fraction sDecTo(String s){
s = s.trim();
int i = s.indexOf(".");
String sub = s.substring(i+1);
String sNoPeriod = s.substring(0,i) + sub;
int top = Integer.parseInt(sNoPeriod);
int bot = 1;
for(int j = 0; j<sub.length(); j++) bot = bot*10;
return new Fraction(top,bot);
}
static Fraction divFraction(Fraction f, Fraction g){
return new Fraction (f.num * g.den, f.den * g.num);
}
static Fraction addFraction(Fraction f, Fraction g){
return new Fraction (f.num * g.den + f.den * g.num, f.den*g.den);
}
static Fraction sStringTo(String s){
s=s.trim();
s= s.replaceAll("\\s*/\\S*", "/");// remove 0 or more blanks before & after slash
s = s.replaceAll("\\s+", " "); // all blanks to be one blank: 2 1/2
int posB = s.indexOf(" ");
int posSlash = s.indexOf("/");
int posPed = s.indexOf(".");
Fraction ans = null;
if(posB>-1){
if (posSlash>posB) { ans = sMixTo(s);}
}else{
if (posPed == -1 && posSlash == -1) ans = sIntTo(s); //integer only
else{
if(posSlash == -1) ans = sDecTo(s);// decimal only
else{
//with slash "2.1/2 2.1/2.1
Fraction f = sStringTo(s.substring(0,posSlash));
Fraction g = sStringTo(s.substring(posSlash+1));
ans = divFraction(f,g);
}
}
}
return ans;
}//sStringTo()
The problematic stack trace is:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:662)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at Util.sIntTo(Util.java:17)
at Util.sStringTo(Util.java:75)
at Util.sStringTo(Util.java:81)
at Fraction.<init>(Fraction.java:31)
at Test.main(Test.java:6)

It looks like you are passing a string containing only whitespace into sIntTo(). You should consider just removing all whitespace, rather than just reducing it to a single space. Consider changing s = s.replaceAll("\\s+", " "); to s = s.replaceAll("\\s+", "");.

I figured out the problem. It was a syntax error on my part.

Related

Affine Cypher in Java

I'm an Engineering Student and I'm stuck on this part of the Affine Cypher.
import java.util.Scanner;
public class abcd {
public static int a, b;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter key(a,b): ");
a = sc.nextInt();
b = sc.nextInt();
Scanner hj = new Scanner(System.in);
System.out.print("Enter String: ");
String word = hj.nextLine();
sc.close();
hj.close();
System.out.println("Cyphered text: " + cypher(word));
System.out.println("Decyphered text: " + decypher(cypher(word)));
}
public static String cypher(String plaintext) {
String CT = "";
for (int i = 0; i < plaintext.length(); i++) {
char x = plaintext.charAt(i);
int val = (char)x-97;
int C = ((a* val + b)%26);
char n = (char) (C + 97);
CT = CT + n;
}
return CT;
}
public static int inv (int a, int b) {
a=a%b;
for (int x = 1; x<26; x++) {
if ((a*x)%26==1) {
return x;
}
}
return 1;
}
public static String decypher(String cyphertext) {
String t = "";
for (int i = 0; i<cyphertext.length(); i++) {
char x = cyphertext.charAt(i);
int val = (char)x - 97;
int D = ((inv(a, 26)*(val-b))%26);
char n = (char)(D + 97);
t = t + n;
}return t;
}
}
The cyphered text shows the desired output but the deciphered text doesn't match the original text.
Here is my console input and output:
Enter key(a,b):
7
2
Enter String: hello
Cyphered text: zebbw
Decyphered text: heRRo
I was expecting the deciphered text to match the original text since that is what it was supposed to do.
As Joachim Sauer and Tan Yu Hau Sean suggest, % does things you may not expect on negative numbers. If a is negative, a%b will be a number between -b and 0.
If you add a method like this
public static int mod(int a, int b) {
return (a%b+b)%b;
}
and replace your instances of % with calls to it, e.g.:
int C = mod(a* val + b,26);
things will work a lot better.

Getting Numberformat exception with unknown source. How to fix this

How to fix this issue?
java.lang.NumberFormatException: at java.lang.NumberFormatException.forInputString(Unknown Source)
I am doing some example problem and my code is working fine for the first string and digit. (Commented one)
But when change the new string and digit (Current one) I am getting this error :
java.lang.NumberFormatException: For input string: "299858953917872714814599237991174513476623756395992135212546127959342974628712329595771672911914471"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at java.lang.Long.parseLong(Unknown Source)
at com.codejam.q1.problems.maxResult.removeDigit(maxResult.java:21)
at com.codejam.q1.problems.maxResult.main(maxResult.java:10)
Here is my code. Anywhere I am missing something ?
public class maxResult {
public static void main(String[] args) {
//String str = "1231";
String str = "2998589353917872714814599237991174513476623756395992135212546127959342974628712329595771672911914471";
//char digit = '1';
char digit = '3';
System.out.println(removeDigit(str,digit));
}
public static String removeDigit(String number, char digit) {
long result = 0;
for(int i = 0; i<number.length(); i++) {
char num = number.charAt(i);
if(num == digit) {
String myStr = number.substring(0, i) + number.substring(i + 1);
try{
long myNum = Long.parseLong(myStr);
if(myNum > result) {
result = myNum;
}
}
catch (NumberFormatException ex){
ex.printStackTrace();
}
}
}
String s = String.valueOf(result);
return s;
}
}
Even though I change int to long but no change in result.
Your number is too big for a long value. The maximum long value is 9,223,372,036,854,775,807. You can use BigInteger, which essentially has no limit.
Using long
long result = 0;
// ...
long myNum = Long.parseLong(myStr);
if(myNum > result) {
result = myNum;
}
// ...
String s = String.valueOf(result);
return s;
Using BigInteger
import java.math.BigInteger;
// ...
BigInteger result = BigInteger.ZERO;
// ...
BigInteger myNum = new BigInteger(myStr);
result = myNum.max(result);
// ...
return result.toString();
The number is too long for a long. Longs go from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,808.
Try doing this :
public static String removeDigit(String number, char digit) {
double temp = 0;
String result="";
for(int i = 0; i<number.length(); i++) {
char num = number.charAt(i);
if(num == digit) {
String myStr = number.substring(0, i) + number.substring(i + 1);
try{
double myNum = Double.parseDouble(myStr);
if(myNum > temp) {
temp = myNum;
result=myStr;
}
}
catch (NumberFormatException ex){
ex.printStackTrace();
}
}
}
return result;
}
The problem you get is that you are exceeding the limit of the int and the long. Let us see the limits of some number storing types and then use the best one:
Type
Size
Value
Exceeds
int
32 bit
-2,147,483,648 to 2,147,483,647
Yes
long
64 bit
-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
Yes
float
32 bit
3.40282347 x 1038 to 1.40239846 x 10-45
Yes
double
64 bit
1.7976931348623157 x 10308 to 4.9406564584124654 x 10-324
Yes
BigInteger
32 bit
2^64billion
No
Here, we find that BigInteger is the class we need to use. So, instead of using a long or int for it, use BigInteger. To know more about BigInteger, visit here.
Also to know how to use a big integers refer to the answer here
You can use BigDecimal instead of long.
public class Application {
public static void main(String[] args) {
//String str = "1231";
String str = "2998589353917872714814599237991174513476623756395992135212546127959342974628712329595771672911914471";
//char digit = '1';
char digit = '3';
System.out.println(removeDigit(str,digit));
}
public static BigDecimal removeDigit(String number, char digit) {
BigDecimal result = BigDecimal.ZERO;
for(int i = 0; i<number.length(); i++) {
char num = number.charAt(i);
if(num == digit) {
String myStr = number.substring(0, i) + number.substring(i + 1);
try{
BigDecimal myNum = new BigDecimal(myStr);
if(myNum.compareTo(result)>0) {
result = myNum;
}
}
catch (NumberFormatException ex){
ex.printStackTrace();
}
}
}
return result;
}
}

Best way to print 2 doubles with same exponent

How to best print 2 float numbers in scientific-notation but with same exponent?
eg: I'd like to print numbers like this:
1.234e-6
11.234e-6
And I would like some function to detect automatically best exponent - that is smaller number always start at first decimal digit and bigger number prints how it must with same exponent.
eg: 0.1 and 100 would print
1.000e-1
1000.000e-1
But even when I ask explicitly for 2 decimal places String.format("%2.3e",11.234e-6) I got 1.123e-5
So far I come up with code bellow. It works as I want. But as you can see it is not exactly short or swift... It would be great if someone would point to some Java native functions which helps me to do it more elegant...
public static String repeat(int count, String with) {
if(count<0){
return "";
}
if(count>1e5){
return "";
}
return new String(new char[count]).replace("\0", with);
}
public static String getFormattedDouble(double num,int posInt,int posFrac){
if(num == 0) return "0"; // correct 0 value to be print only with one 0
String sInt = repeat(posInt,"0");
String sFrac = repeat(posFrac,"0");
String sSing = num<0 ? "" : "+";
DecimalFormat form = new DecimalFormat(sSing+sInt+"."+sFrac+"E0");
String s = form.format(num);
s = s.replace("E","e"); // I really thing capital E looks ugly
return s;
}
public static String[] get2doublesSameExp(double a, double b){
String[] s = new String[2];
int expA;
if(a == 0) expA = 0;
else expA = (int)Math.floor(Math.log10(Math.abs(a)));
int expB;
if(b == 0) expB = 0;
else expB = (int)Math.floor(Math.log10(Math.abs(b)));
double expDif = Math.abs((double)expA-(double)expB);
int fractPos = 3;
if(expDif > 4) fractPos = 1; // too big exponent difference reduce fraction digits
if(expDif > 6){
// too big exponent difference print it normally it will be nicer
s[0] = String.format("%1.3e",a);
s[1] = String.format("%1.3e",b);
return s;
}
int minExp = Math.min(expA,expB) - 1;
s[0] = getFormattedDouble(a, expA - minExp, fractPos );
s[1] = getFormattedDouble(b, expB - minExp, fractPos );
// just text right justification
String rightJust = repeat((int)expDif," ");
int justIdx = expA < expB ? 0 : 1;
s[justIdx] = rightJust + s[justIdx];
return s;
}
String[] s = get2doublesSameExp(1.234e-6,11.234e-6);

how to convert a string value to integer without using Integer.parseInt()?

I have this input like
String s = "6" , ss="99 , sss = "99999";
i need to store these values in an int reference variable ,
without using Integer.parseInt
any suggestion ? , no full code , just the hints ??
What about Scanner?
int a=new Scanner(s).nextInt();
Without util.
public static int parseInt(String s)
{
int ans=0;
for(int i=s.length()-1;i>=0;i--)
{
ans+=(s.charAt(i)-'0');
ans*=10;
}
return ans/10;
}
public class MyStringToNumber {
public static int convert_String_To_Number(String numStr){
char ch[] = numStr.toCharArray();
int sum = 0;
//get ascii value for zero
int zeroAscii = (int)'0';
for(char c:ch){
int tmpAscii = (int)c;
sum = (sum*10)+(tmpAscii-zeroAscii);
}
return sum;
}
public static void main(String a[]){
System.out.println("\"3256\" == "+convert_String_To_Number("3256"));
System.out.println("\"76289\" == "+convert_String_To_Number("76289"));
System.out.println("\"90087\" == "+convert_String_To_Number("90087"));
}
}
See more at this URL.
Try to get each char from the string and then the value of each char. 0 has a value of 48 so
char c = '9';
int i = c - 48;
Now i = 9. After that you only need to multiply this value with the appropriate power of 10 and add it to the total
public class ConvertIntoInt {
public static void main(String []args) {
String numStr = "3256";
char ch[] = numStr.toCharArray();
int sum = 0;
// Get ASCII value for zero
int zeroAscii = (int)'0';
for (char c:ch) {
int tmpAscii = (int)c;
System.out.println("Temp Ascii:" + tmpAscii);
sum = (sum * 10) + (tmpAscii - zeroAscii);
System.out.println(sum);
}
System.out.println(sum);
}
}

Testing for palindrome using loops going wrong

What this program is trying to do is go through numbers starting at "000000" going all the way up to "999999" and trying to find numbers which are palindromes. (eg: 0000000000).
I am having trouble with reversing the string and creating a valid result. The system adds the next 4 numbers creating a length 10 string.
import java.util.Arrays;
public class TestPalindrome{
public static void main(String []args){
int[] intArray = new int[6];
String[] strArray = new String[99];
String nextString;
int count = 0;
int nextnum;
int thisnum;
String thisString = "";
String s = "000000";
nextString = s;
do {
for(int i=0;i<6;i++) {
intArray[i] = Integer.parseInt(String.valueOf(nextString.charAt(i)));
}
int pos1 = intArray[5];
int pos2 = intArray[4]*10;
int pos3 = intArray[3]*100;
int pos4 = intArray[2]*1000;
int pos5 = intArray[1]*10000;
int pos6 = intArray[0]*100000;
nextnum = (pos1 + 1) + pos2 + pos3 + pos4 + pos5 + pos6;
thisnum = pos1 + pos2 + pos3 + pos4 + pos5 + pos6;
// If any of below values = 10, then number is not used
int d7 = ((4*intArray[0])+(10*intArray[1])+(9*intArray[2])+(2*intArray[3])+intArray[4]+(7*intArray[5])) % 11;
int d8 = ((7*intArray[0])+(8*intArray[1])+(7*intArray[2])+(intArray[3])+9*intArray[4]+(6*intArray[5])) % 11;
int d9 = ((9*intArray[0])+(intArray[1])+(7*intArray[2])+(8*intArray[3])+7*intArray[4]+(7*intArray[5])) % 11;
int d10 = ((intArray[0])+(2*intArray[1])+(9*intArray[2])+(10*intArray[3])+4*intArray[4]+(intArray[5])) % 11;
if (d7==10) { }
else if (d8==10) { }
else if (d9==10) { }
else if (d10==10) { }
else {
String s7 = Integer.toString(d7);
String s8 = Integer.toString(d8);
String s9 = Integer.toString(d9);
String s10 = Integer.toString(d10);
thisString = String.format("%06d", thisnum);
String concat = thisString + s7 + s8 + s9 + s10;
StringBuilder input = new StringBuilder(concat);
StringBuilder value = input.reverse();
if( value == input){
System.out.println("" + concat);
strArray[count] = concat;
count = count+1;
}
else {}
}
nextString = String.format("%06d", nextnum);
}
while (nextnum < 1000000 && nextnum > 000000);{
}
}
}
The problem is that it displays all numbers and not just palindromes. Any help is very welcomed.
I would simply put the numbers into strings. Then reverse the string and see if it equals the original.
String originalString = "110011";
String newString = new StringBuilder(originalString ).reverse().toString();
if (originalString.equals(newString )) {
//Is a palindrome
}
Note: Consider how you want to handle leading zeros. "11" is a palindrome, but if you need 4 values then "0011" is not.
One funny way is to use just one for-loop :
public static void main(String [] args){
for(String s = "000000"; !s.equals("1000000"); s = String.format("%06d",Integer.parseInt(s)+1)){
if(new StringBuilder(s).reverse().toString().equals(s))
System.out.println(s);
}
}

Categories

Resources