Accessing index values before and after symbol from input - java

I am trying to take the input and if there is an # symbol in the input then it finds the maximum of the integers before and after the # symbol. The maximum part I have no problem with but I do not know how to access and find the values before and after the # symbol.
import java.util.Scanner;
public class Max_Min {
public static void main(String[] args) {
//gets keyboard
Scanner keyboard = new Scanner(System.in);
//puts input into string
String inputString = keyboard.nextLine();
//splits string between characters
String[] splitInput = inputString.split("");
for (String s : splitInput) {
if(s.equals("#")){
//computes the maximum of the two integers before and after the #
}
}
//close keyboard
keyboard.close();
I did do a search to find something simliar (and im sure there is something) but could not find anything. If someone could help that would be great!

Try with this:
for (int i = 0; i < splitInput.length; i++){
if (splitInput[i].equals("#") && i != 0 && i != splitInput.length -1){
int max = Math.max(Integer.parseInt(splitInput[i - 1]), Integer.parseInt(splitInput[i + 1]));
}
//...
}

You could try:
String[] splitInput = inputString.split("#");
which would split your string at the #s.
Then you can do a iteration over your splitInput array and do a .length on each index.

You have written the simple for loop, with which you can only access the string, but not its index in the array. If you had the index, you could write:
int possibleMax = Integer.parseInt(splitInput[i - 1]) + Integer.parseInt(splitInput[i + 1]);
To get the index, there are two ways:
for (int i = 0; i < splitInput.length; i++) {
String s = splitInput[i];
...
}
Or:
int i = 0;
for (String s : splitInput) {
…
i++;
}
I don't like either version because both are more complicated than absolutely necessary, in terms of written code. If you would use Kotlin instead of Java, it would be:
splitInput.forEachIndexed { i, s ->
…
}
In Java this could be written:
forEachIndexed(
splitInput,
(i, s) -> …
);
The problem in Java is that the code inside the … cannot update the variables of the enclosing method. I'm not sure whether this will ever change. It would be possible but needs a lot of work by the language committee.

A simple way to do this would be
String input = "12#23";
String [] arr = input.split("#");
if (arr.length == 2) {
System.out.println("Max is "+Math.max(Integer.valueOf(arr[0]),Integer.valueOf(arr[1])));
}

Related

Count the numbers of numeric value in a given string

Java program to accept a string and count total numeric values.
public class Test2{
public static void main(String[] args){
String str = "I was 2 years old in 2002";
int count = 0, i;
for(i = 0; i < str.length(); i++){
if(str.charAt(i) >= 48 && str.charAt(i) <= 57){
count++;
// while(str.charAt(i) >= 48 && str.charAt(i) <= 57)
// i++;
}
}
System.out.println("Output: " +count);
}
}
Output = 5
After uncommenting the two lines written inside while loop -
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 25
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:48)
at java.base/java.lang.String.charAt(String.java:712)
at Test2.main(Test2.java:9)
The output should be 2, because there are two numeric values - 2 and 2002
I have commented on the two lines in the above code, after uncommenting the code, the same logic works perfectly in C++.
An alternative to #DarkMatter´s answer using Pattern:
public static void main(String[] args) {
String str = "I was 2 years old in 2002";
long count = Pattern.compile("\\d+").matcher(str).results().count();
System.out.println(count);
}
You are checking individual charters so it counts every digit (as you probably realize). Java String has some nice tools to help you here. You could split the line into words and check each against a regular expression using String.matches():
String str = "I was 2 years old in 2002";
int count = 0;
for(String s : str.split(" ")) {
if(s.matches("[0-9]*")) {
count++;
}
}
System.out.println(count);
You can do the same thing (almost) with a stream:
String str = "I was 2 years old in 2002";
long count = Arrays.stream(str.split(" "))
.filter(s -> s.matches("[0-9]*")).count();
System.out.println(count);
In C, strings end in an ASCII NUL character (well, in basic C, strings don't exist, it's a library bolt-on, but most bolt-ons have NUL terminated strings). In java, that's not how it works.
The reason that your code is not working in java, but it is in C, is that you just keep going until you hit a non-digit character in that inner while loop. That means if the string ends in a digit (which yours does), your code asks the string: Give me the character at (one position beyond its length). In C that works; that's ASCII NUL, and thus your inner loop ends, as that's not a digit.
In java it doesn't, because you can't ask for a character beyond the end of a string.
You can 'fix' your code as pasted by also adding a check that i is still below length: if (i < str.length() && str.charAt(i).... ).
As the other answers showed you, there are more java idiomatic ways to solve this problem too, and probably the strategies shown in the other answers is what your average java coder would most likely do if faced with this problem. But there's nothing particularly wrong with your C-esque solution, once you add the 'check length' fix.
below code will input String from user and return the number of occurrences of numeric values as count.
import java.util.Scanner;
public class NumberCountingString
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String str = in.nextLine();
int count = 0, i;
int size = str.length(); // will only get size once instead of using in loop which will always get size before comparing
for(i = 0; i < size; i++)
{
if(Character.isDigit(str.charAt(i))) //if char is digit count++
{
count++;
for (int j = i; j < size; ) //inner loop to check if next characters are also digits
{
if(Character.isDigit(str.charAt(j))) // if yes skip next char
{
i++;
j=i;
}
else{ //break inner loop
break;
}
}
}
}
System.out.println("Output: " +count);
}
}
There are many options in Java as already shared by others. Below is very similar to your existing code and gives your desired output:
public static void main(String[] args) {
String str = "I was 2 years old in 2002";
String[] splittedString = str.split(" ");
int count = 0, i;
for (i = 0; i < splittedString.length; i++) {
if (StringUtils.isNumeric(splittedString[i])) {
count++;
}
}
System.out.println("Output: " + count);
}
You can split this string into an array of words, then filter those words where codePoints of the characters match digits, i. e. allMatch (Character::isDigit), and count these words:
String str = "I was 2 years old in 2002";
long count = Arrays
// split string into an array of words
.stream(str.split("\\s+"))
// for each word check the code points of the
// characters, whether they are digits or not.
.filter(w -> w.codePoints()
.mapToObj(ch -> (char) ch)
.allMatch(Character::isDigit))
.count();
System.out.println(count); // 2
See also: Transform String to byte then to int

NumberFormatException when trying to use parseInt()and trim() does not fix it

Hi I am trying to solve a Kata(coding practice exercise) in CodeWars which is called "Your order, please" (there is a BIG chance that my code won't solve it but I am really just trying to get rid of the error..and there's a link to the exercise at the end in case you want to check it out)
Either way what the Kata basically says is that you will be given a String such as
"4of Fo1r pe6ople g3ood th5e the2"
and you have to order the words by getting the int and returning in the correct order so
"Fo1r the2 g3ood 4of th5e pe6ople"
Now what I coded is supposed to go through each element and get the number to then order it, so I tried to use parseInt and it did not work. I read on another article that trim() would get rid of...
java.lang.NumberFormatException: For input string: "4of" //trim did not fix it
I am not sure whether I did not implement trim() correctly or parseInt() or what is wrong, any help would be very much appreciated and thank you for taking your time to read this. Without further ado here's the code.
public class Kata {
public static String order(String words) {
String[] unordered = words.split(" ");
String[] order = new String[unordered.length];
System.out.println(unordered.length);
for(int i = 0; i < unordered.length; i++){
int correctIndex = (Integer.parseInt(unordered[i].trim())) -1;
order[correctIndex] = unordered[i];
System.out.println(unordered[i]);
}
return "I will return order concatenated";
}
public static void main(String[] args) {
System.out.println(order("4of Fo1r pe6ople g3ood th5e the2"));
}
}
And the error... (6 is the output before it)
6
Exception in thread "main" java.lang.NumberFormatException: For input string: "4of"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:652)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at Kata.order(Kata.java:8)
at Kata.main(Kata.java:17)
https://www.codewars.com/kata/55c45be3b2079eccff00010f/train/java
(the link to the Kata)
4of is not an integer string and therefore, you can not parse it into an int. You can replace its non-digit characters (\D) with "" and then you can parse it to an int. Learn more about regex patterns from the documentation of java.util.regex.Pattern.
The problem can be solved in the following simple steps:
Split the sentence on space (which you have already done).
Create an int[] original and populate it with embedded numeric values from the resulting, String[] unordered.
Create a clone of original[] and sort the same. Let's say this clone is int[] order.
Populate a String[] ordered based on order[].
Join the elements of ordered[] on space.
Demo:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
String words = "4of Fo1r pe6ople g3ood th5e the2";
String[] unordered = words.split(" ");
String[] ordered = new String[unordered.length];
int[] original = new int[unordered.length];
// Populate order with embedded numeric values
for (int i = 0; i < unordered.length; i++) {
original[i] = Integer.parseInt(unordered[i].replaceAll("\\D", ""));
}
// Create a clone of original[] and sort it
int[] order = original.clone();
Arrays.sort(order);
// Populate ordered[] based on order[]
for (int i = 0; i < order.length; i++) {
for (int j = 0; j < original.length; j++) {
if (order[i] == original[j]) {
ordered[i] = unordered[j];
break;
}
}
}
// Join the elements of ordered[] on space
String result = String.join(" ", ordered);
System.out.println(result);
}
}
Output:
Fo1r the2 g3ood 4of th5e pe6ople
Just remove all non-numeric characters (by using regex replacement) and then parse the resulting value to an integer.
for (int i = 0; i < unordered.length; i++){
String wordNum = unordered[i].trim().replaceAll("\\D+", "");
int correctIndex = (Integer.parseInt(wordNum)) - 1;
order[correctIndex] = unordered[i];
}
NumberFormatException is thrown when
The input string provided might be null. Example-
Integer.parseInt(null);
The input string might be empty. Example-
Integer.parseInt("");
The input string might be having trailing space. Example-
Integer.parseInt("123 ");
The input string might be having a leading space. Example-
Integer.parseInt(" 123");
The input string may be alphanumeric.Example-
Long.parseLong("b2");
There are other reasons also. You are trying to pass unordered[i] in parseInt.
int correctIndex = (Integer.parseInt(unordered[i].trim())) -1;
It is an alphanumeric String. So the compiler gives NumberFormatException.
Try using this function to calculate the index instead.
//Method to find the correctIndex
static int findIndex(String s)
{
char ch;
//Access all the characters of the String and the find the digit
for (int i = 0;i < s.length();i++)
{
ch = s.charAt(i);
if (Character.isDigit(ch))
{
return ch-49; //Convert the character to index
}
}
return -1;
}

Replace the Indexes without Loop

My Question is :
First I have String variable of 1000 character, and I have another set of String variable of 1000 character
1] In First Set of Variable contains "1110000XXXXX0001111...." like this and so on, till 1000
2] In The second Set of Variable contains "1110000101010001111..." like this and so on till 1000
3] I need to get the position of X in first Variable and replace the Value of similar position from the second variable
For ex : 1st Variable of data "000XXX000X0"
2nd Variable of data "00011000010"
The X should be replaced by the values which is in the position in 2nd set of data.
NOTE : TO BE DONE WITHOUT LOOP
because if we put loop its runs 1000 times in a loop and 'X' may be anywhere in 1000 characters in the String
For ex: 1 Record 1000 Times
if 100K Records means 1000*100K (PERFORMANCE FAILS)
So need solution for it.
Kindly Help me out with this.
My Code is :
String sInputStr="0X11XXXXX000000000000000000000000000000000000000000000000X000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011";
String sDbStr="0111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011";
int iLength=sInputStr.length();
for(int i=0;i<iLength;i++){
if(sInputStr.charAt(i)=='X'){
}else{
if(i>sDbStr.length()){
break;
}else{
sChar[i] = sInputStr.charAt(i);
}
}
}//End of For
sVal=String.valueOf(sChar);
System.out.println("sVal == " +sVal);
Help Me friends
All you need is something like this
class FirstApp {
public static void main(String[] args) {
String sDbStr="0111111110000001234000000000000011";
StringBuilder sNewStr= new StringBuilder("011111111000000XXXX00000000000001112");
String findStr = "X";
int lastIndex = 0;
System.out.println("Starting");
long startTime = System.currentTimeMillis();
String result = replaceValues("X", sDbStr, sNewStr);
long endTime = System.currentTimeMillis();
System.out.println("Result");
System.out.println(result);
System.out.println(String.valueOf(endTime-startTime));
}
public static String replaceValues(String toReplace, String fromStr, StringBuilder toStr) {
int lastIndex = toStr.indexOf(toReplace);
if(lastIndex != -1){
toStr.replace(lastIndex,lastIndex+1,Character.toString(fromStr.charAt(lastIndex)));
System.out.println(toStr);
return replaceValues(toReplace, fromStr, toStr);
} else {
return toStr.toString();
}
}
}
sample result:
Starting
0111111110000001XXX00000000000001112
01111111100000012XX00000000000001112
011111111000000123X00000000000001112
011111111000000123400000000000001112
Result
011111111000000123400000000000001112
UPDATE Updated solution to ensure less execution time using stringBuilder and recursion
If X point to one value, like as mentioned X replace by 1. Go for string.replaceAll function.
ie.
String oriString="000XXX000X0";
String replaceOne=oriString.replace('X','1');
System.out.println(replaceOne);
If I understood the problem correctly then you want to replace the values of X in your first array with the values from seconds array at the same positions. For Example, array1: 000XXX000 & array2: 100101001. Then array1 should finally be 000101000.
Here is a simple code snippet to achieve this:
char[] arr1 = sInputStr.toCharArray();
char[] arr2 = sDbStr.toCharArray();
for(int i = 0; i < arr1.size(); i++)
if(arr1[i] == 'X')
arr1[i] == arr2[i];
The idea is to search for the index of the occurrence of the character say 'X' and copy all the characters from second string into the first as long as we find 'X'. Repeat the process till the last occurrence of 'X'.
public class Test
{
public static void main(String args[])
{
String s1 = "0X11XXXXX000000000000000000000000000000000000000000000000X000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011";
String s2= "0111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011";
char a[] = s1.toCharArray();
int i = s1.indexOf('X', 0);
while(i!=-1)
{
while(a[i] == 'X'){
a[i] = s2.charAt(i);
i++;
}
i = s1.indexOf('X',i+1);
}
s1 = new String(a);
System.out.println("result: "+s1);
}
}

Compare content of two text files and split words java

I know this question has been already asked several times but I can't find the way to apply it on my code.
So my propose is the following:
I have two files griechenland_test.txt and outagain5.txt . I want to read them and then get which percentage of outagain5.txt is inside the other file.
Outagain5 has input like that:
mit dem 542824
und die 517126
And Griechenland is an normal article from Wikipedia about that topic (so like normal text, without freqeuncy Counts).
1. Problem
- How can I split the input in bigramms? Like every two words, but always with the one before? So if I have words A, B, C, D --> get AB, BC, CD ?
I have this:
while ((sCurrentLine = in.readLine()) != null) {
// System.out.println(sCurrentLine);
arr = sCurrentLine.split(" ");
for (int i = 0; i < arr.length; i++) {
if (null == hash.get(arr[i])) {
hash.put(arr[i], 1);
} else {
int x = hash.get(arr[i]) + 1;
hash.put(arr[i], x);
}
}
Then I read the other file with this code ( I just add the word, and not the number (I split it with 4 spaces, so the two words are at h[0])).
for (String line = br.readLine(); line != null; line = br.readLine()) {
String h[] = line.split(" ");
words.add(h[0]);
}
2. Problem
Now I make the comparsion between the String x in hash and the String s in words. I have put the else System out.print to get which words are not contained in outagain5.txt, but there are several words printed out which ARE contained in outagain5.txt. I don't understand why :D
So I think that the comparsion doesn't work well or maybe this will be solved will fix the first problem.
ArrayList<String> words = new ArrayList<String>();
ArrayList<String> neuS = new ArrayList<String>();
ArrayList<Long> neuZ = new ArrayList<Long>();
for (String x : hash.keySet()) {
summe = summe + hash.get(x);
long neu = hash.get(x);
for (String s : words) {
if (x.equals(s)) {
neuS.add(x);
neuZ.add(neu);
disc = disc + 1;
} else {
System.out.println(x);
break;
}
}
}
Hope I made my question clear, thanks a lot!!
public static List<String> ngrams(int n, String str) {
List<String> ngrams = new ArrayList<String>();
String[] words = str.split(" ");
for (int i = 0; i < words.length - n + 1; i++)
ngrams.add(concat(words, i, i+n));
return ngrams;
}
public static String concat(String[] words, int start, int end) {
StringBuilder sb = new StringBuilder();
for (int i = start; i < end; i++)
sb.append((i > start ? " " : "") + words[i]);
return sb.toString();
}
It is much easier to use the generic "n-gram" approach so you can split every 2 or 3 words if you want. Here is the link I used to grab the code from: I have used this exact code almost any time I need to split words in the (AB), (BC), (CD) format. NGram Sequence.
If I recall, String has a method titled split(regex, count) that will split the item according to a specific point and you can tell it how many times to do it.
I am referencing this JavaDoc https://docs.oracle.com/javase/6/docs/api/java/lang/String.html#split(java.lang.String, int).
And I guess for running comparison between two text files I would recommend having your code read both of them, populated two unique arrays and then try to run comparisons between the two strings each time. Hope I helped.

Splitting a string into multiple int form using indexOf()

This is my first post so go easy on me. This IS a homework question, but I have spent about 7 hours working through various means to complete this goal and have had no success. I am building various methods for an assignment, and I need to figure out how to split a String into several int variables.
Ex: given the String "100 200 300" I need to change it to three int of 100, 200, 300. I have to use indexOf(), and cannot use split() or arrays.
String scores="100 200 300";
int n=scores.indexOf(" ");
String sub=scores.substring(0,n);
Integer.parseInt(sub);
This lets me get the first string "100" and parse it. However, I do not know how to continue the code so it will get the next ones. For my method, I will need the new int variables for later arguments.
EDIT: I think I need to use a for loop: something like:
for(int i=0; i<=scores.length; i++)
{//I do not know what to put here}
Joe, indexOf() is overloaded, check out this version:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(int,%20int)
You need two things:
a loop;
being able to run indexOf() from where it left off (hint: read the Javadoc).
public static void main(String[] args) {
String scores = "100 200 300";
ArrayList<Integer> numbers = new ArrayList<Integer>();
int n = 0;
while (n != -1) {
String sub = "";
n = scores.indexOf(" ");
if (n != -1) {
sub = scores.substring(0, n);
scores = scores.substring((n + 1));
} else {
sub = scores;
}
numbers.add(Integer.parseInt(sub));
}
for (int i : numbers) {
System.out.println("" + i);
}
}
Try something like this to loop through and add numbers to arraylist. The arraylist numbers will contain all your numbers.
try this:
String scores="100 200 300";
int offset = 0;
int space;
int score;
scores = scores.trim(); //clean the string
do
{
space= scores.indexOf(" ", offset);
if(space > -1)
{
score = Integer.parseInt(scores.substring(offset , space));
}
else
{
score = Integer.parseInt(scores.substring(offset));
}
System.out.println(score);
offset = space + 1;
}while(space > -1);
Your 'n' variable is the important part. You get your first String by slicing from 0 to 'n', so your next string starts not at 0, but at
n + " ".size()
Ok, so here is what I have come up with:
Since I needed to compare the newly parsed ints with a different variable, as well as ensure that the amount of ints was equal to a different variable, I created this while loop:
public boolean isValid()
{
int index=0;
int initialindex=0;
int ntotal=0;
int ncount=0;
boolean flag=false;
while (index!=-1)
{
index=scores.indexOf(" ");
String temp=scores.substring(initialindex,index);
int num=Integer.parseInt(temp);
ntotal+=num;
ncount++;
initialindex=index;
}
if (ntotal==total && ncount==count)
{
flag=true;
}
return flag;
}

Categories