java.lang.NumberFormatException for input string - java

I'm creating a program which makes the given input string into number so that input will be coded. But I'm running into a NumberFormatException as soon as the input string gets too long. I can't see how I can fix this.
Note that I have to get substrings from the given string input, turn them into numericValues then get the sum of these two strings as an answer.
Code:
public class Puzzle {
private static char[] letters = {'a','b','c','d','e','f','g','h','i', 'j','k','l','m','n','o','p','q','r','s',
't','u','v','w','x','y','z'};
private static String input;
private static String delimiters = "\\s+|\\+|//+|=";
public static void main(String[]args)
{
input = "youuu + are = gay"; //as soon as the substrings before = sign are
//longer than 5 characters the exception occurs
System.out.println(putValues(input));
}
//method to put numeric values for substring from input
#SuppressWarnings("static-access")
public static long putValues(String input)
{
Integer count = 0;
long answer = 0;
String first="";
String second = "";
StringBuffer sb = new StringBuffer(input);
int wordCounter = Countwords();
String[] words = countLetters();
System.out.println(input);
if(input.isEmpty())
{
System.out.println("Sisestage mingi s6na");
}
if(wordCounter == -1 ||countLetters().length < 1){
return -1;
}
for(Character s : input.toCharArray())
{
for(Character c : letters)
{
if(s.equals(c))
{
count = c.getNumericValue(c);
System.out.print(s.toUpperCase(s) +"="+ count + ", ");
}
}
if(words[0].contains(s.toString()))
{
count = count - 1;
count = s.getNumericValue(s);
//System.out.println(count);
first += count.toString();
}
if(words[3].contains(s.toString())){
count = s.getNumericValue(s);
second += count.toString();
}
}
try {
answer = Integer.parseInt(first) + Integer.parseInt(second);
} catch(NumberFormatException ex)
{
System.out.println(ex);
}
System.out.println("\n" + first + " + " + second + " = " + answer);
return answer;
}
public static int Countwords()
{
String[] countWords = input.split(" ");
int counter = countWords.length - 2;
if(counter == 0) {
System.out.println("Sisend puudu!");
return -1;
}
if(counter > 1 && counter < 3) {
System.out.println("3 sõna peab olema");
return -1;
}
if(counter > 3) {
System.out.println("3 sõna max!");
return -1;
}
return counter;
}
//method which splits input String and returns it as an Array so i can put numeric values after in the
//putValue method
public static String[] countLetters()
{
int counter = 0;
String[] words = input.split(delimiters);
for(int i = 0; i < words.length;i++) {
counter = words[i].length();
if(words[i].length() > 18) {
System.out.println("Yhe s6na maksimaalne pikkus on 18 t2hem2rki ");
}
}
return words;
}

Integers in Java (as in many languages) are limited by a minimum and maximum value.
More information on this can be found here: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
You could give a meaningful error in the catch-block
You did not enter a valid 32-bit Integer value.
Or you could switch to something like a BigDecimal which can hold bigger values: https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html
(watch out: BigDecimal works very different from a normal int, so read the documentation wisely, and Google for examples if necessary)
EDIT: you can parse it to Long as well, if you want that: Long.parseLong(INPUT, 10);. That way you extend the limit to 64-bit.

Related

Is there any way to count integer elements in text file?

So I have a text file as :
and I want to count the number of integers in the first row.
// e.g. The first row : 3 12 1 8 5 8 1 2 1 4 --> 10
Can I do that with a stream or for statement or another way?
I tried with for and it didn't work for me and I couldn't find any useful solution. Please, help me.
public class Egyszamjatek {
public static void main(String[] args) throws IOException {
List<String> game = Files.readAllLines(Paths.get("egyszamjatek.txt"));
ArrayList<OneGame> games = new ArrayList<>();
for (String game1 : game) {
String[] split = game1.split(" ");
int rounds = Integer.parseInt(split[0]) + Integer.parseInt(split[1]) + Integer.parseInt(split[2])
+ Integer.parseInt(split[3]) + Integer.parseInt(split[4]) + Integer.parseInt(split[5])
+ Integer.parseInt(split[6]) + Integer.parseInt(split[7]) + Integer.parseInt(split[8])
+ Integer.parseInt(split[9]);
String names = split[10];
games.add(new OneGame(rounds, names));
}
System.out.println("3.feladat: number of players : " + game.stream().count());
System.out.println("4. feladat: number of rounds: " );
}
static class OneGame {
int rounds;
String names;
public OneGame(int rounds, String names) {
this.rounds = rounds;
this.names = names;
}
}
}
solution with for loop
String firstLine = "3 12 1 8 5 8 1 2 1 4";
String[] splits = firstLine.split(" ");
int count = 0 ;
for(String intStr:splits){
try {
int i = Integer.parseInt(intStr);
count++;
}catch (NumberFormatException e){
e.printStackTrace();
}
}
System.out.println(count);
You could do something like:
List<OneGame> games = Files.lines(Paths.get("egyszamjatek.txt")) // Stream<String> each line as a single String
.map(g -> {
String[] split = g.split(" ");
int rounds = (int) Arrays.stream(split)
.filter(a -> isInteger(a)) // filter only integers
.count(); // count how many integers e.g. 10 in your first line
return new OneGame(rounds, split[rounds]); // create an instance with count and name
}).collect(Collectors.toList()); // collect to list
where isInteger(a) is a util that you can use from this answer. Its implementation would be :
public static boolean isInteger(String str) {
if (str == null) {
return false;
}
if (str.isEmpty()) {
return false;
}
int i = 0;
if (str.charAt(0) == '-') {
if (str.length() == 1) {
return false;
}
i = 1;
}
for (; i < str.length(); i++) {
char c = str.charAt(i);
if (c < '0' || c > '9') {
return false;
}
}
return true;
}
Note: the code relies on certain assumptions for e.g. the integer values for the number of rounds would supersede the name of the game and hence uses split[rounds] to access the name.

Append string after nth occurrence of a string

I have a string s to which I want to append another string s1 at the specified position.
String s = "17.4755,2.0585,23.6489,12.0045";
String s1=",,,,"
Now I want to add the string s1 after the n-th occurrence of "," character.
I have just started learning Java.
You can use the following method:
public String insert(int n, String original, String other) {
int index = original.indexOf(',');
while(--n > 0 && index != -1) {
index = original.indexOf(',', index + 1);
}
if(index == -1) {
return original;
} else {
return original.substring(0, index) + other + original.substring(index);
}
}
Working with Strings directly is not worth the trouble.
One easy way would be to turn your String into a List and manipulate that.
public void test() {
String s = "17.4755,2.0585,23.6489,12.0045";
// Split s into parts.
String[] parts = s.split(",");
// Convert it to a list so we can insert.
List<String> list = new ArrayList<>(Arrays.asList(parts));
// Inset 3 blank fields at position 2.
for (int i = 0; i < 3; i++) {
list.add(2,"");
}
// Create my new string.
String changed = list.stream().collect(Collectors.joining(","));
System.out.println(changed);
}
Prints:
17.4755,2.0585,,,,23.6489,12.0045
I think this is what you want
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = "17.4755,2.0585,23.6489,12.0045";
String s1=",,,,";
System.out.println("Enter Nth Occurrence");
try {
int n = scanner.nextInt();
long totalOccurrence = 0;
if (n != 0) {
totalOccurrence = s.chars().filter(num -> num == ',').count();
if (totalOccurrence < n) {
System.out.println("String s have only " + totalOccurrence + " symbol \",\"");
} else {
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ',') {
count++;
if (count == n) {
String resultString = s.substring(0, i) + s1 + s.substring(i, s.length());
System.out.println(resultString);
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Wrong input");
}
}
}
Output :
1. Enter Nth Occurrence
5
String s have only 3 symbol ","
2. Enter Nth Occurrence
2
17.4755,2.0585,,,,,23.6489,12.0045

Single character instance from string

i was wondering how can i create a method where i can get the single instance from a string and give it a numericValue for example, if theres a String a = "Hello what the hell" there are 4 l characters and i want to give a substring from the String a which is Hello and give it numeric values. Right now in my program it gets all the character instances from string so the substring hello would get number values from the substring hell too because it also has the same characters.
my code :
public class Puzzle {
private static char[] letters = {'a','b','c','d','e','f','g','h','i', 'j','k','l','m','n','o','p','q','r','s',
't','u','v','w','x','y','z'};
private static String input;
private static String delimiters = "\\s+|\\+|//+|=";
public static void main(String[]args)
{
input = "help + me = please";
System.out.println(putValues(input));
}
//method to put numeric values for substring from input
#SuppressWarnings("static-access")
public static long putValues(String input)
{
Integer count;
long answer = 0;
String first="";
String second = "";
StringBuffer sb = new StringBuffer(input);
int wordCounter = Countwords();
String[] words = countLetters();
System.out.println(input);
if(input.isEmpty())
{
System.out.println("Sisestage mingi s6na");
}
if(wordCounter == -1 ||countLetters().length < 1){
return -1;
}
for(Character s : input.toCharArray())
{
for(Character c : letters)
{
if(s.equals(c))
{
count = c.getNumericValue(c) - 9;
System.out.print(s.toUpperCase(s) +"="+ count + ", ");
}
}
if(words[0].contains(s.toString()))
{
count = s.getNumericValue(s);
//System.out.println(count);
first += count.toString();
}
if(words[3].contains(s.toString())){
count = s.getNumericValue(s);
second += count.toString();
}
}
try {
answer = Long.parseLong(first)+ Long.parseLong(second);
} catch(NumberFormatException ex)
{
System.out.println(ex);
}
System.out.println("\n" + first + " + " + second + " = " + answer);
return answer;
}
public static int Countwords()
{
String[] countWords = input.split(" ");
int counter = countWords.length - 2;
if(counter == 0) {
System.out.println("Sisend puudu!");
return -1;
}
if(counter > 1 && counter < 3) {
System.out.println("3 sõna peab olema");
return -1;
}
if(counter > 3) {
System.out.println("3 sõna max!");
return -1;
}
return counter;
}
//method which splits input String and returns it as an Array so i can put numeric values after in the
//putValue method
public static String[] countLetters()
{
int counter = 0;
String[] words = input.split(delimiters);
for(int i = 0; i < words.length;i++) {
counter = words[i].length();
if(words[i].length() > 18) {
System.out.println("One word can only be less than 18 chars");
}
}
return words;
}
Program has to solve the word puzzles where you have to guess which digit corresponds to which letter to make a given equality valid. Each letter must correspond to a different decimal digit, and leading zeros are not allowed in the numbers.
For example, the puzzle SEND+MORE=MONEY has exactly one solution: S=9, E=5, N=6, D=7, M=1, O=0, R=8, Y=2, giving 9567+1085=10652.
import java.util.ArrayList;
public class main {
private static String ChangeString;
private static String[] ArrayA;
private static String a;
private static int wordnumber;
private static String temp;
public static void main(String[] args) {
// TODO Auto-generated method stub
a = "hello what the hell";
wordnumber = 0;
identifyint(a,wordnumber);
}
public static void identifyint (String a, int WhichWord){
ChangeString = a.split(" ")[WhichWord];
ArrayA = a.split(" ");
replaceword();
ArrayA[wordnumber] = ChangeString;
//System.out.print(ArrayA[wordnumber]);
a = "";
for(int i = 0; i<ArrayA.length;i++){
if(i==wordnumber){
a = a.concat(temp+ " ");
}
else{
a = a.concat(ArrayA[i]+" ");
}
}
System.out.print(a);
}
public static void replaceword(){
temp = "";
Character arr[] = new Character[ChangeString.length()];
for(int i = 0; i<ChangeString.length();i++){
arr[i] = ChangeString.charAt(i);
Integer k = arr[i].getNumericValue(arr[i])-9;
temp = temp.concat(""+k);
}
a = temp;
}
}
Change wordnumber to the word you want to replace each time. If this is not what you have asked for, please explain your question in more detail.

Counting Letters Between the First and Last - Java

OK, so I'm doing this project that requires that I have the first and last setters of a string appear with the number of letters in between them counted, and output. I've tried repurposing some reverse a string code I had handy, but I cannot get the output to appear in my IDE.
Can anyone look over my code, and make some suggestions?
public static void main(String[] args) {
String countWord;
countWord = JOptionPane.showInputDialog(null,
"Enter the string you wish to have formatted:");
}
static String countMe(String countWord) {
int count = 1;
char first = countWord.charAt (0);
char last = countWord.charAt(-1);
StringBuilder word = new StringBuilder();
for(int i = countWord.length() - 1; i >= 0; --i)
if (countWord.charAt(i) != first ) {
if (countWord.charAt(i) != last) {
count++;
}
}
return countWord + first + count + last;
}
}
Just build it using charAt():
return "" + str.charAt(0) + (str.length() - 2) + str.charAt(str.length() - 1);
The "" at the front causes the numeric values that follow to be concatenated as Strings (instead of added arithmetically).
A slightly more terse alternative is:
return countWord.replaceAll("(.).*(.)", "$1" + (str.length() - 2) + "$2")
Once you determined the first and last chars, it is no need for unnecessary conditions. Just try this:
static String countMe(String countWord) {
char first = countWord.charAt(0);
char last = countWord.charAt(countWord.length()-1);
int count=0;
for (int i = 1; i < countWord.length()-1; i++)
{
count++;
}
return first + String.valueOf(count) + last;
}
Or, if it is not mandatory to use for loop, you can make it simple as this
static String countMe(String countWord) {
char first = countWord.charAt(0);
char last = countWord.charAt(countWord.length()-1);
int count = countWord.substring(1, countWord.length()-1).length();
return first + String.valueOf(count) + last;
}
You could use the string.length() method to obtain the total length of the string. Your code would be something like:
int totalLength = countWord.length();
int betweenLength = totalLength - 2; // This gives the count of characters between first and last letters
char first = countWord.charAt(0);
char last = countWord.charAt(str.length() - 1);
String answer = first + betweenLength + last;
import javax.swing.JOptionPane;
public class Main{
public static void main(String[] args) {
String countWord;
countWord = JOptionPane.showInputDialog(null,
"Enter the word you wish to have formatted:");
JOptionPane.showMessageDialog(null, countMe(countWord));
}
static String countMe(String countWord) {
int count = 0;
String first = String.valueOf(countWord.charAt(0));
String last = String.valueOf(countWord.charAt(countWord.length() - 1));
for(int i = 1; i < countWord.length() - 1; i++) {
if (String.valueOf(countWord.charAt(i)) != first ) {
count++;
}
}
return first + count + last;
}
}

Compression algorithm in java

My goal is to write a program that compresses a string, for example:
input: hellooopppppp!
output:he2l3o6p!
Here is the code I have so far, but there are errors.
When I have the input: hellooo
my code outputs: hel2l3o
instead of: he213o
the 2 is being printed in the wrong spot, but I cannot figure out how to fix this.
Also, with an input of: hello
my code outputs: hel2l
instead of: he2lo
It skips the last letter in this case all together, and the 2 is also in the wrong place, an error from my first example.
Any help is much appreciated. Thanks so much!
public class compressionTime
{
public static void main(String [] args)
{
System.out.println ("Enter a string");
//read in user input
String userString = IO.readString();
//store length of string
int length = userString.length();
System.out.println(length);
int count;
String result = "";
for (int i=1; i<=length; i++)
{
char a = userString.charAt(i-1);
count = 1;
if (i-2 >= 0)
{
while (i<=length && userString.charAt(i-1) == userString.charAt(i-2))
{
count++;
i++;
}
System.out.print(count);
}
if (count==1)
result = result.concat(Character.toString(a));
else
result = result.concat(Integer.toString(count).concat(Character.toString(a)));
}
IO.outputStringAnswer(result);
}
}
I would
count from 0 as that is how indexes work in Java. Your code will be simpler.
would compare the current char to the next one. This will avoid printing the first character.
wouldn't compress ll as 2l as it is no smaller. Only sequences of at least 3 will help.
try to detect if a number 3 to 9 has been used and at least print an error.
use the debugger to step through the code to understand what it is doing and why it doesn't do what you think it should.
I am doing it this way. Very simple:
public static void compressString (String string) {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < string.length(); i++) {
int count = 1;
while (i + 1 < string.length()
&& string.charAt(i) == string.charAt(i + 1)) {
count++;
i++;
}
if (count > 1) {
stringBuffer.append(count);
}
stringBuffer.append(string.charAt(i));
}
System.out.println("Compressed string: " + stringBuffer);
}
You can accomplish this using a nested for loops and do something simial to:
count = 0;
String results = "";
for(int i=0;i<userString.length();){
char begin = userString.charAt(i);
//System.out.println("begin is: "+begin);
for(int j=i+1; j<userString.length();j++){
char next = userString.charAt(j);
//System.out.println("next is: "+next);
if(begin == next){
count++;
}
else{
System.out.println("Breaking");
break;
}
}
i+= count+1;
if(count>0){
String add = begin + "";
int tempcount = count +1;
results+= tempcount + add;
}
else{
results+= begin;
}
count=0;
}
System.out.println(results);
I tested this output with Hello and the result was He2lo
also tested with hellooopppppp result he2l3o6p
If you don't understand how this works, you should learn regular expressions.
public String rleEncodeString(String in) {
StringBuilder out = new StringBuilder();
Pattern p = Pattern.compile("((\\w)\\2*)");
Matcher m = p.matcher(in);
while(m.find()) {
if(m.group(1).length() > 1) {
out.append(m.group(1).length());
}
out.append(m.group(2));
}
return out.toString();
}
Try something like this:
public static void main(String[] args) {
System.out.println("Enter a string:");
Scanner IO = new Scanner(System.in);
// read in user input
String userString = IO.nextLine() + "-";
int length = userString.length();
int count = 0;
String result = "";
char new_char;
for (int i = 0; i < length; i++) {
new_char = userString.charAt(i);
count++;
if (new_char != userString.charAt(i + 1)) {
if (count != 1) {
result = result.concat(Integer.toString(count + 1));
}
result = result.concat(Character.toString(new_char));
count = 0;
}
if (userString.charAt(i + 1) == '-')
break;
}
System.out.println(result);
}
The problem is that your code checks if the previous letter, not the next, is the same as the current.
Your for loops basically goes through each letter in the string, and if it is the same as the previous letter, it figures out how many of that letter there is and puts that number into the result string. However, for a word like "hello", it will check 'e' and 'l' (and notice that they are preceded by 'h' and 'e', receptively) and think that there is no repeat. It will then get to the next 'l', and then see that it is the same as the previous letter. It will put '2' in the result, but too late, resulting in "hel2l" instead of "he2lo".
To clean up and fix your code, I recommend the following to replace your for loop:
int count = 1;
String result = "";
for(int i=0;i<length;i++) {
if(i < userString.length()-1 && userString.charAt(i) == userString.charAt(i+1))
count++;
else {
if(count == 1)
result += userString.charAt(i);
else {
result = result + count + userString.charAt(i);
count = 1;
}
}
}
Comment if you need me to explain some of the changes. Some are necessary, others optional.
Here is the solution for the problem with better time complexity:
public static void compressString (String string) {
LinkedHashSet<String> charMap = new LinkedHashSet<String>();
HashMap<String, Integer> countMap = new HashMap<String, Integer>();
int count;
String key;
for (int i = 0; i < string.length(); i++) {
key = new String(string.charAt(i) + "");
charMap.add(key);
if(countMap.containsKey(key)) {
count = countMap.get(key);
countMap.put(key, count + 1);
}
else {
countMap.put(key, 1);
}
}
Iterator<String> iterator = charMap.iterator();
String resultStr = "";
while (iterator.hasNext()) {
key = iterator.next();
count = countMap.get(key);
if(count > 1) {
resultStr = resultStr + count + key;
}
else{
resultStr = resultStr + key;
}
}
System.out.println(resultStr);
}

Categories