This Java program does a simple computation and it is suppose to output the numerical value of 123+1
(The output should be 124.) (Ignore the last "+" string.)
I got an error inside the if statement:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
I did a printout for arrayz[i-1] and arrayz[i+1] and it seems to printout 123 and 1 receptively, which is correct. So, I'm not sure what's wrong.
String math = "123+1+";
String arrayz[]={"123","+","1","+"};
double total =0.0;
int i=0;
while(i<=(math.length()-1)) //don't bother with the last char
{ i++;
if(arrayz[i].equals("+"))
{
total = Double.parseDouble((String)arrayz[i-1]) + Double.parseDouble((String)arrayz[i+1]);
}
}
System.out.println(total);
while(i<=(math.length()-1))
math length is 6 and and in side loop your array length is 4
You might want to write
while(i<=(arrayz.length-1))
Since you are using the index i with the array arrayz, you must use arrayz.length instead of math.length()
Edit
This should work:
public static void main(String[] args)
{
String math = "123+1+";
String arrayz[] = { "123", "+", "1", "+" };
double total = 0.0;
int i = 0;
// arrayz.length - 2 -> because you are accessing "arrayz[i + 1]",
// arrayz.length - 1 would be OK if the maximum index you were using were "arrayz[i] "
while (i <= (arrayz.length - 2)) //don't bother with the last char
{
if (arrayz[i].equals("+")) {
total = Double.parseDouble((String) arrayz[i - 1]) + Double.parseDouble((String) arrayz[i + 1]);
}
i++; // Increment at the end of the loop
}
System.out.println(total);
}
You are looping over the string math, at the same time accessing elements of arrayz inside your loop, and thinking that they have the same elements and the same length.
What I suggest you, is to use instead of math String (you can omit it in this case but I assume you can't in general for some criteria), you can use an array of type String, so that 123 in your example would be the first element arrayz[0].
Related
I'm a beginner in java and this code was used in a book I'm reading, however I can't seem to figure out how it works.
The code:
public class NumberTriangleWhile {
public static void main(String[] args) {
int number = 0;
String output = "";
while (number < 10) {
output = output + number;
System.out.println(output);
number++;
}
}
}
The output:
0
01
012
0123
01234
012345
0123456
01234567
012345678
0123456789
I don't understand why each number is printed and then somehow stored and reused in the next line, can someone explain this please?
output is a string variable. When you add something to it like this:
output = output + number;
It does not add the numerical value of the number, but instead just joins the number with the original string. For example, if output was originally 1 and number is 2, the above line will change output to 12, not 3.
The loop keeps looping until number is 10. In the first iteration, output changed from an empty string to 0. In the second iteration (number has now increased to 1), output changed to 01 (the original 0 joined with the current value of number - 1). In the third iteration, number is incremented to 2. 2 is then added to the end of output to form 012. This carries on until number is 10.
The misconception you have might be that you think output becomes empty after you print it. It does not. It will still hold the same value.
In every step inside while loop, output added with number, in Java adding something with String will result in String for example:
String str = "a" + 2;
results in str="a2";.
If we start our loop, in first step number = 0 and output="" hence output = "" + 0 that make output = "0" in second run number=1 hence output = "0" (Old output value) + 1 that make output = "01" and so on
The string output is defined outside of the while loop. It can be read from and written to inside of the while loop and its contents will be consistent in the next iteration.
If output would be defined inside of the while loop, for example:
while ( number < 10) {
String output = "";
output += number;
}
then your output would just be (with new line after each number)
0
1
2
3
4
5
6
7
8
9
Since the new number is consistent throughout each iteration of the while loop, it is "stored" as you say
Each number is getting printed because its getting concatenated.
When number=0,
And you are storing the value of number into the output as:
Output=output+number
Then the number which is an integer gets stored as a string in the output
Each time the loop runs the new incremented number gets concatenated with the previous value in the string output.
That's why all numbers are getting printed each time.
make this change in your code and you'll get your output
public static void main(String[] args)
{
int number=0;
String output="";
while(number <10)
{
output=output+number;
System.out.println(output);
number++;
output="";
}
}
I'm currently stuck on a problem from CodeAbbey. I don't want an answer to the entire thing.
This is the meat of the question:
Input data will have:
initial integer number in the first line;
one or more lines describing operations, in form sign value where sign is either + or * and value is an integer;
last line in the same form, but with sign % instead and number by which the result should be divided to get the remainder.
Answer should give remainder of the result of all operations applied sequentially (starting with initial number) divided by the last number.
My problem is with the logic. So far I realize there is an operator, a space and then a number. To get the number I thought of using
char c = src.charAt(2);
and to get the operator I'd use the same thing. Then I'd just use a bunch of if-else statements to figure out the rest. But how do I do this in the large scale? How do I read all of those numbers in and do it for every one of them? A nudge on the right direction would help.
import java.util.Scanner;
public class Challenge14 {
static Scanner in = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("Enter Your first number: ");
int x = in.nextInt();
for (int i = 0; i < 7; i++) {
String[] s = new String[i];
s = in.nextLine();
}
}
}
One of the more helpful classes for this problem is the Scanner.
The Scanner documentation is located at:
https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
The Scanner can be set to read from a String, File, or Input Stream.
The Scanner has several useful methods, including:
hasNext(), which lets you know if there are any other operators or numbers to pick up
next(), which will read the next token as a String
nextInt(), which will read the next token as an int
You can use the scanner to pick up the first number, then use some sort of loop to perform operations on that number until there are no more operations to perform.
Assuming that the input is from a file, what you want to do is this:
Read the first line in as a number
Split the input on each other line on whitespace, so you're left with something that can be interpreted as an operator, and something that can be interpreted as a number
Perform the operations and accumulate your result
The file portion is likely what you're struggling with. The answer below addresses that. I leave the rest as an exercise for the reader.
public class Accumulator {
private int result;
public void readFile(String filename) {
try(Scanner scan = new Scanner(new File(filename)) {
// Unconditionally read the first line as a number
result += Integer.parseInt(scan.nextLine());
//Now, we need to read in each other line remaining.
while(scan.hasNextLine()) {
String[] contents = scan.nextLine().split();
int number = Integer.parseInt(contents[1]);
// The operator is in contents[0]
performArithmeticWith(contents[0], number);
}
} catch(IOException e) {
e.printStackTrace();
}
}
public void performArithmeticWith(String operator, int number) {
switch(operator) {
case "+":
break;
// etc
}
}
}
My problem is with the logic. So far I realize there is an operator, a space and then a number.
There are several options in Java to separate the operator and the operand.
You can use the String.split() method:
String[] token input.split(" ");
//token[0] will be your operator
//token[1] will be your number
You can also use the indexOf() method:
int idx = input.indexOf(" ");
String opr = input.substring(0, idx); //your operator
String num = input.substring(idx+1); //your number
This is my approach.
Assumption is that you will get all the values as String array (Which
I believe is much easy compare to making a scalable solution).
Here's my code. You can support additional operators easily and the sequence of operator does not matter.
package com.stack.overflow.test;
import java.math.BigDecimal;
public class Calculator {
public static void main(String[] args) {
String[] values = {"5", "+", "3", "*", "7", "+", "10", "*", "2", "*", "3", "+", "1", "%", "11"};
new Calculator().calculate(values);
}
public void calculate(String[] inputs) {
BigDecimal result = null;
for(int i = 0; i < inputs.length-2;) {
String left = inputs[i];
String operator = inputs[++i];
String right = inputs[++i];
System.out.println("left : "+ left);
System.out.println("operator : "+ operator);
System.out.println("right : "+ right);
result = Operator.instanceOf(operator).apply(new BigDecimal(left), new BigDecimal(right));
inputs[i] = result.toString();
System.out.println("Result :: "+ result);
}
}
}
enum Operator {
ADD("+") {
BigDecimal apply(BigDecimal left, BigDecimal right) {
return left.add(right);
}
},
MULTIPLY("*"){
BigDecimal apply(BigDecimal left, BigDecimal right) {
return left.multiply(right);
}
},
REMAINDER("%"){
BigDecimal apply(BigDecimal left, BigDecimal right) {
return left.remainder(right);
}
};
private String symbol;
Operator(String symbol) {
this.symbol = symbol;
}
public static Operator instanceOf(String givenSymbol) {
for(Operator operator : Operator.values()) {
if(operator.symbol.equals(givenSymbol)) {
return operator;
}
} throw new RuntimeException("Operator not supported : "+givenSymbol);
}
abstract BigDecimal apply(BigDecimal left, BigDecimal right);
}
Result
left : 5
operator : +
right : 3
Result :: 8
left : 8
operator : *
right : 7
Result :: 56
left : 56
operator : +
right : 10
Result :: 66
left : 66
operator : *
right : 2
Result :: 132
left : 132
operator : *
right : 3
Result :: 396
left : 396
operator : +
right : 1
Result :: 397
left : 397
operator : %
right : 11
Result :: 1
The input data contains a number at the first line. Then an operation and a number delimited by a space on each consecutive line. Here is one approach to read in the data.
First, read the data line by line, until there are no more lines. Since there is only one element on the first line, read it and convert it to an integer (it looks like all data is integers). A Scanner can be used to read the data line by line. The two useful methods here are:
public boolean hasNextLine() - Returns true if there is another line in the input of this scanner.
public String nextLine() - Advances this scanner past the current line and returns the input that was skipped.
For each line after that, read it, and split it based on the white space using String[] splited = str.split("\\s+");. Then process the string, and read the next line. Note that split, splits based on white space by default and "\\s+" is there just for explicitness.
This question already has answers here:
Memory efficient power set algorithm
(5 answers)
Closed 8 years ago.
I'm trying to find every possible anagram of a string in Java - By this I mean that if I have a 4 character long word I want all the possible 3 character long words derived from it, all the 2 character long and all the 1 character long. The most straightforward way I tought of is to use two nested for loops and iterare over the string. This is my code as of now:
private ArrayList<String> subsets(String word){
ArrayList<String> s = new ArrayList<String>();
int length = word.length();
for (int c=0; c<length; c++){
for (int i=0; i<length-c; i++){
String sub = word.substring(c, c+i+1);
System.out.println(sub);
//if (!s.contains(sub) && sub!=null)
s.add(sub);
}
}
//java.util.Collections.sort(s, new MyComparator());
//System.out.println(s.toString());
return s;
}
My problem is that it works for 3 letter words, fun yelds this result (Don't mind the ordering, the word is processed so that I have a string with the letters in alphabetical order):
f
fn
fnu
n
nu
u
But when I try 4 letter words, it leaves something out, as in catq gives me:
a
ac
acq
acqt
c
cq
cqt
q
qt
t
i.e., I don't see the 3 character long word act - which is the one I'm looking for when testing this method. I can't understand what the problem is, and it's most likely a logical error I'm making when creating the substrings. If anyone can help me out, please don't give me the code for it but rather the reasoning behind your solution. This is a piece of coursework and I need to come up with the code on my own.
EDIT: to clear something out, for me acq, qca, caq, aqc, cqa, qac, etc. are the same thing - To make it even clearer, what happens is that the string gets sorted in alphabetical order, so all those permutations should come up as one unique result, acq. So, I don't need all the permutations of a string, but rather, given a 4 character long string, all the 3 character long ones that I can derive from it - that means taking out one character at a time and returning that string as a result, doing that for every character in the original string.
I hope I have made my problem a bit clearer
It's working fine, you just misspelled "caqt" as "acqt" in your tests/input.
(The issue is probably that you're sorting your input. If you want substrings, you have to leave the input unsorted.)
After your edits: see Generating all permutations of a given string Then just sort the individual letters, and put them in a set.
Ok, as you've already devised your own solution, I'll give you my take on it. Firstly, consider how big your result list is going to be. You're essentially taking each letter in turn, and either including it or not. 2 possibilities for each letter, gives you 2^n total results, where n is the number of letters. This of course includes the case where you don't use any letter, and end up with an empty string.
Next, if you enumerate every possibility with a 0 for 'include this letter' and a 1 for don't include it, taking your 'fnu' example you end up with:
000 - ''
001 - 'u'
010 - 'n'
011 - 'nu'
100 - 'f'
101 - 'fu' (no offense intended)
110 - 'fn'
111 - 'fnu'.
Clearly, these are just binary numbers, and you can derive a function that given any number from 0-7 and the three letter input, will calculate the corresponding subset.
It's fairly easy to do in java.. don't have a java compiler to hand, but this should be approximately correct:
public string getSubSet(string input, int index) {
// Should check that index >=0 and < 2^input.length here.
// Should also check that input.length <= 31.
string returnValue = "";
for (int i = 0; i < input.length; i++) {
if (i & (1 << i) != 0) // 1 << i is the equivalent of 2^i
returnValue += input[i];
}
return returnValue;
}
Then, if you need to you can just do a loop that calls this function, like this:
for (i = 1; i < (1 << input.length); i++)
getSubSet(input, i); // this doesn't do anything, but you can add it to a list, or output it as desired.
Note I started from 1 instead of 0- this is because the result at index 0 will be the empty string. Incidentally, this actually does the least significant bit first, so your output list would be 'f', 'n', 'fn', 'u', 'fu', 'nu', 'fnu', but the order didn't seem important.
This is the method I came up with, seems like it's working
private void subsets(String word, ArrayList<String> subset){
if(word.length() == 1){
subset.add(word);
return;
}
else {
String firstChar = word.substring(0,1);
word = word.substring(1);
subsets(word, subset);
int size = subset.size();
for (int i = 0; i < size; i++){
String temp = firstChar + subset.get(i);
subset.add(temp);
}
subset.add(firstChar);
return;
}
}
What I do is check if the word is bigger than one character, otherwise I'll add the character alone to the ArrayList and start the recursive process. If it is bigger, I save the first character and make a recursive call with the rest of the String. What happens is that the whole string gets sliced in characters saved in the recursive stack, until I hit the point where my word has become of length 1, only one character remaining.
When that happens, as I said at the start, the character gets added to the List, now the recursion starts and it looks at the size of the array, in the first iteration is 1, and then with a for loop adds the character saved in the stack for the previous call concatenated with every element in the ArrayList. Then it adds the character on its own and unwinds the recursion again.
I.E., with the word funthis happens:
f saved
List empty
recursive call(un)
-
u saved
List empty
recursive call(n)
-
n.length == 1
List = [n]
return
-
list.size=1
temp = u + list[0]
List = [n, un]
add the character saved in the stack on its own
List = [n, un, u]
return
-
list.size=3
temp = f + list[0]
List = [n, un, u, fn]
temp = f + list[1]
List = [n, un, u, fn, fun]
temp = f + list[2]
List = [n, un, u, fn, fun, fu]
add the character saved in the stack on its own
List = [n, un, u, fn, fun, fu, f]
return
I have been as clear as possible, I hope this clarifies what was my initial problem and how to solve it.
This is working code:
public static void main(String[] args) {
String input = "abcde";
Set<String> returnList = permutations(input);
System.out.println(returnList);
}
private static Set<String> permutations(String input) {
if (input.length() == 1) {
Set<String> a = new TreeSet<>();
a.add(input);
return a;
}
Set<String> returnSet = new TreeSet<>();
for (int i = 0; i < input.length(); i++) {
String prefix = input.substring(i, i + 1);
Set<String> permutations = permutations(input.substring(i + 1));
returnSet.add(prefix);
returnSet.addAll(permutations);
Iterator<String> it = permutations.iterator();
while (it.hasNext()) {
returnSet.add(prefix + it.next());
}
}
return returnSet;
}
How would I remove the chars from the data in this file so I could sum up the numbers?
Alice Jones,80,90,100,95,75,85,90,100,90,92
Bob Manfred,98,89,87,89,9,98,7,89,98,78
I want to do this so for every line it will remove all the chars but not ints.
The following code might be useful to you, try running it once,
public static void main(String ar[])
{
String s = "kasdkasd,1,2,3,4,5,6,7,8,9,10";
int sum=0;
String[] spl = s.split(",");
for(int i=0;i<spl.length;i++)
{
try{
int x = Integer.parseInt(spl[i]);
sum = sum + x;
}
catch(NumberFormatException e)
{
System.out.println("error parsing "+spl[i]);
System.out.println("\n the stack of the exception");
e.printStackTrace();
System.out.println("\n");
}
}
System.out.println("The sum of the numbers in the string : "+ sum);
}
even the String of the form "abcd,1,2,3,asdas,12,34,asd" would give you sum of the numbers
You need to split each line into a String array and parse the numbers starting from index 1
String[] arr = line.split(",");
for(int i = 1; i < arr.length; i++) {
int n = Integer.parseInt(arr[i]);
...
try this:
String input = "Name,2,1,3,4,5,10,100";
String[] strings = input.split(",");
int result=0;
for (int i = 1; i < strings.length; i++)
{
result += Integer.parseInt(strings[i]);
}
You can make use of the split method of course, supplying "," as the parameter, but that's not all.
The trick is to put each text file's line into an ArrayList. Once you have that, move forwars the Pseudocode:
1) Put each line of the text file inside an ArrayList
2) For each line, Split to an array by using ","
3) If the Array's size is bigger than 1, it means there are numbers to be summed up, else only the name lies on the array and you should continue to the next line
4) So the size is bigger than 1, iterate thru the strings inside this String[] array generated by the Split function, from 1 to < Size (this will exclude the name string itself)
5) use Integer.parseInt( iterated number as String ) and sum it up
There you go
Number Format Exception would occur if the string is not a number but you are putting each line into an ArrayList and excluding the name so there should be no problem :)
Well, if you know that it's a CSV file, in this exact format, you could read the line, execute string.split(',') and then disregard the first returned string in the array of results. See Evgenly's answer.
Edit: here's the complete program:
class Foo {
static String input = "Name,2,1,3,4,5,10,100";
public static void main(String[] args) {
String[] strings = input.split(",");
int result=0;
for (int i = 1; i < strings.length; i++)
{
result += Integer.parseInt(strings[i]);
}
System.out.println(result);
}
}
(wow, I never wrote a program before that didn't import anything.)
And here's the output:
125
If you're not interesting in parsing the file, but just want to remove the first field; then split it, disregard the first field, and then rejoin the remaining fields.
String[] fields = line.split(',');
StringBuilder sb = new StringBuilder(fields[1]);
for (int i=2; i < fields.length; ++i)
sb.append(',').append(fields[i]);
line = sb.toString();
You could also use a Pattern (regular expression):
line = line.replaceFirst("[^,]*,", "");
Of course, this assumes that the first field contains no commas. If it does, things get more complicated. I assume the commas are escaped somehow.
There are a couple of CsvReader/Writers that might me helpful to you for handling CSV data. Apart from that:
I'm not sure if you are summing up rows? columns? both? in any case create an array of the target sum counters int[] sums(or just one int sum)
Read one row, then process it either using split(a bit heavy, but clear) or by parsing the line into numbers yourself (likely to generate less garbage and work faster).
Add numbers to counters
Continue until end of file
Loading the whole file before starting to process is a not a good idea as you are doing 2 bad things:
Stuffing the file into memory, if it's a large file you'll run out of memory (very bad)
Iterating over the data 2 times instead of one (probably not the end of the world)
Suppose, format of the string is fixed.
String s = "Alice Jones,80,90,100,95,75,85,90,100,90,92";
At first, I would get rid of characters
Matcher matcher = Pattern.compile("(\\d+,)+\\d+").matcher(s);
int sum = 0;
After getting string of integers, separated by a comma, I would split them into array of Strings, parse it into integer value and sum ints:
if (matcher.find()){
for (String ele: matcher.group(0).split(",")){
sum+= Integer.parseInt(ele);
}
}
System.out.println(sum);
I was working on the recursive code to print all possible output strings for an input sequence. For simplification I am going to shorten the problem. I have a String[] array. I want to print all possible combinations of words from [0] to [N] considering only one character from a String at a time. Example: String[] a = {"abc", "def", "ghi"} I should be printing adg, adh, adi, aeg.. etc
Here is my recursive code:
void printLetters(String[] list, int count, String result)
{
if(list == null)
return;
if(count > list.length-1)
{
System.out.println(result);
return;
}
for(int i = 0; i<list[count].length(); i++)
{
printLetters(list, count++, result + list[count].charAt(i) + "");
}
}
My code is running into an infinite loop as I am getting a StackOverflowError. Can someone point out my mistake?
The problem is that you are post-incrementing here:
printLetters(list, count++, result + list[count].charAt(i) + "");
So the recursive call occurs first, then the increment, which practically means you keep calling the method with the same value of count. Use this instead:
printLetters(list, count + 1, result + list[count].charAt(i) + "");
And are you sure you want to increment count? Because when the recursive call returns you will have count + 1 also in the "parent method", which I don't think is what you need.