I am currently taking Programming 1 and learning Java. Here is my assignment...
Ask user to enter a number and then in a loop, find any 2 numbers that they are the same and next to each other. And then display the number in the loop. For example, if user enters 133455662, the program displays 356. For simplicity, assume user never will enter all three numbers the same and next to each other
Here is the code I've come up with, except I keep getting an error...
public static void main(String[] args){
String num = "";
String result = "";
System.out.println("Enter a number");
Scanner s = new Scanner(System.in);
num = s.next();
int len = num.length();
for(int n = 0;n<len;n++){
char c = num.charAt(n);
char c2 = num.charAt(n+1);
if(c == c2){
result = result + c;
}
}
System.out.println(num);
}
This is the error I get...
run: Enter a number 001123455 Exception in thread "main"
java.lang.StringIndexOutOfBoundsException: String index out of range:
9 at java.lang.String.charAt(String.java:658) at
CS120_Labs.Homework09_C.main(Homework09_C.java:18)
C:\Users\Fletcher\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53:
Java returned: 1 BUILD FAILED (total time: 6 seconds)
Thanks again for anyone that can help!
Exception said that StringIndexOutOfBoundsException, so you need two changes to make it work:
Add "-1" to fix error "for (int n = 0; n < len - 1; n++) {"
And also at the end of the program you need change from "num" to "result" System.out.println(result);
public static void main(String[] args) {
String num = "";
String result = "";
System.out.println("Enter a number");
Scanner s = new Scanner(System.in);
num = s.next();
int len = num.length();
for (int n = 0; n < len - 1; n++) {
char c = num.charAt(n);
char c2 = num.charAt(n + 1);
if (c == c2) {
result = result + c;
}
}
System.out.println(result);
}
I think all you need to do is to change your for line like (updated to len-1):
for(int n = 0; n<len-1; n++){
...
}
Change your for loop as
for(int n = 0; n < len - 1; n++)
since you are looking up the character at index n and len+1 in the for-loop body, you should loop from 0 to len-1
In addition to the other answers here that just "give" you the solution, I wanted to add:
This is a common problem when you first start out using structures that are "0" indexed. For example, if we have the letters A-I:
0 1 2 3 4 5 6 7 8
A B C D E F G H I
There are 9 letters there, so length() will return 9. The problem is, the letter at the first position isn't 1, it's 0. If in a loop you count all the way up to 9, the last iteration of the loop's charAt line will say "Take the character at position 9" but 9 is out of range of available positions, hence the exception String index out of range: 9.
This can happen anytime you are referencing an object in a structure that has positional indexes. When you see an exception like this, the first thing to check is why did my code try to access an index that didn't exist. In this case, the answer is the upper bound of the for loop. There are other possibilities; for example, your index variable (in this case i) is modified inside the loop, or if the lower bound is negative.
Related
I want to...
create an asterisk triangle, using Java, that matches the length of whatever number (Between 1-50) the user enters.
Details
The first line would always start with an asterisk.
The next line would increment by one asterisk until it matches the
user's input.
The following lines would then decrement until it is back to one
asterisk.
For instance, if the user was to enter 3, then the output would have one asterisk on the first line, two asterisks on the second line, three asterisks on the third line, and then revert back to two asterisks on the following line before ending with an asterisk on the last line.
What I've tried so far
I am required to use nested for loops. So far, I tried to test it out using this practice example I made below. I was only able to create on output of the numbers. I also have some concepts of outputting asterisk triangles. How can I apply the concept of this code to follow along the user's input number?
import java.util.Scanner;
public class Program
{
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int count, index = 0, value, number;
System.out.println("This program creates a pattern of numbers " );
System.out.println("Based on a number you enter." );
System.out.println("Please enter a positive integer. " );
count = keyboard.nextInt();
value = count;
for (index = 1; index <= count; index++)
{
for (number = value; number >= 1; number--)
{
System.out.println(number);
}
value--;
System.out.println();
}
}
}
Here's how i would proceed
write a method printAsterisks that takes an int N as parameter and writes a line of N asterisks. You wil need a for loop to do so.
call printAsterisks in a for loop that counts from 1 to COUNT
call printAsterisks in a second loop that counts down from COUNT-1 to 1
That should do the trick.
Also, as a side note, you should close your scanner. The easy way to do so is enclose ot in a try-with-resource like so :
try (Scanner keyboard = new Scanner(System.in);) {
// your code here
}
Let us know the version of the program taht works (or the question you still have) :)
HTH
Here is what you want:
public class Asterisk {
private static final String ASTERISK = "*";
private static final String SPACE = "";
private static int LENGTH;
public static void main(String[] args) {
try{
readLength();
for (int i=1; i<=LENGTH; i++) {
if (i == LENGTH) {
for (int j=LENGTH; j>=1; j--) {
drawLine(j);
}
break;
}
drawLine(i);
}
}catch (Exception e) {
System.out.println("You must enter a number between 1 and 50.");
}
}
static void readLength(){
System.out.println("Enter asterisk's length (1-50)");
LENGTH = Integer.parseInt(System.console().readLine());
if (LENGTH<=0 || LENGTH>50)
throw new NumberFormatException();
}
static void drawLine(int asterisks){
StringBuilder line = new StringBuilder();
int spacesLeft = getLeftSpaceCount(asterisks);
int spacesRight = getRightSpaceCount(asterisks);
for (int i=0; i<spacesLeft; i++) {
line.append(SPACE);
}
for (int i=0; i<asterisks; i++) {
line.append(ASTERISK);
}
for (int i=0; i<spacesRight; i++) {
line.append(SPACE);
}
System.out.println(line.toString()+"\n");
}
static int getLeftSpaceCount(int asterisks){
int spaces = LENGTH - asterisks;
int mod = spaces%2;
return spaces/2 + mod;
}
static int getRightSpaceCount(int asterisks){
int spaces = LENGTH - asterisks;
return spaces/2;
}
}
I am required to use nested for loops
Yes, the main logic lies there...
for (int i=1; i<=LENGTH; i++) {
if (i == LENGTH) {
for (int j=LENGTH; j>=1; j--) {
drawLine(j);
}
break;
}
drawLine(i);
}
The triangle using 5 as input.
*
**
***
****
*****
****
***
**
*
Tip:
There is an easier way to get input from the user usingSystem.console().readLine().
In regards to the printing part, I wanted to clean up the answers a little:
int input = 3; //just an example, you can hook in user input I'm sure!
for (int i = 1; i < (input * 2); i++) {
int amount = i > input ? i / 2 : i;
for (int a = 0; a < amount; a++)
System.out.print("*");
}
System.out.println();
}
For our loop conditions, a little explanation:
i < (input * 2): since i starts at 1 we can consider a few cases. If we have an input of 1 we need 1 row. input 2, 3 rows. 4: 5 rows. In short the relation of length to row count is row count = (length * 2) - 1, so I additionally offset by 1 by starting at 1 instead of 0.
i > input ? i / 2 : i: this is called a ternary statement, it's basically an if statement where you can get the value in the form boolean/if ? value_if_true : value_if_false. So if the row count is bigger than your requested length (more than halfway), the length gets divided by 2.
Additionally everything in that loop could be one line:
System.out.println(new String(new char[i > input ? i / 2 : i]).replace('\0', '*'));
And yeah, technically with a IntStream we could make this whole thing a one-line, though at that point I would be breaking out newlines for clarity
Keep in mind, I wouldn't call this the "beginner's solution", but hopefully it can intrigue you into learning about some other helpful little things about programming, for instance why it was I replaced \0 in my one-line example.
I'm trying to make a Java program that uses the input value from a user to calculate and list the products of two numbers up to the entered number. Like if a user enters 2, the program should calculate the products between the two numbers (1 *1, 1*2, 2*1, 2*2) stores the products in a two-dimensional array, and list the products. I'm not sure that I totally understand arrays and so I feel as though my code is problem not right in many instances, can someone please tell me what I should do to my current code to make it work properly. Thanks in advance! :)
import java.util.Scanner;
public class ProductTable {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String inputString;
char letter = 'y';
// Prompt the user to enter an integer
while(letter != 'q') {
System.out.print("Enter a positive integer: ");
int integer = input.nextInt();
// Create an two-dimensional array to store products
int[][] m = new int[integer][3];
for (int j = 1; j <= m.length; j++) {
m[j][0] = input.nextInt();
m[j][1] = input.nextInt();
m[j][2] = input.nextInt();
}
// Display the number title
System.out.print(" ");
for (int j = 1; j <= m.length; j++)
System.out.print(" " + j);
System.out.println("\n--- ");
// Display table body
for (int i = 1; i <= m.length + 1; i++) {
System.out.print(i);
for (int j = 1; j <= m.length + 1; i++) {
System.out.printf("%4d", i * j);
}
System.out.println();
}
// Prompt the user to either continue or quit
System.out.print("Enter q to quit or any other key to continue: ");
String character = input.nextLine();
inputString = input.nextLine();
letter = inputString.charAt(0);
}
}
}
You can achieve your multiplication table by iterating over 2 counter variables as you already did in your output
// Display table body
// loops running out of bounds (until m.length + 1 instead of m.length-1)
for (int i = 1; i <= m.length + 1; i++) {
System.out.print(i);
for (int j = 1; j <= m.length + 1; i++) { // missed to increment j here
System.out.printf("%4d", i * j);
}
System.out.println();
}
Arrays should be based on 0, that means an array with 3 fields has the indexes 0, 1, 2. So the last index is length-1. Your condition <=m.length+1 runs out of bounds. index<length will work since 2 is less than 3, but not 3 less than 3.
You have also a typo: In the inner loop you are doing an increment of i instead of j, so the loop will run infinite.
Try to create an outer and inner loop as you did, but with start index 0 and end condition index<inputValue. Calculate multiTable[index1][index2] = (1+index1)*(1+index2).
Then do a similar loop and print the array fields. You don't need to use an array, you could output directly as you did. But you wanted to practice handling arrays.
Since you want to learn and understand, I don't like just to write the code. imagine an array with 3 fields having the indexes 0, 1, 2:
index 0 | 1 | 2
value 1 | 2 | 3
Now you would check the length at first, that's 3. You start with 0 and count while the counter does not reach the length since the zero based index is 1 below our natural order (0,1,2 vs. 1,2,3). That is the case as long the index is below the length, meaning index<length.
Try this logic (pseudo code). To simplify the problem we include the 0 in our product table. So we get 0*0, 0*1, 0*2... Doing so, we do not have to ignore index 0 or to calculate between index 0 should represent value 1.
maxNumber = userInput()
outer loop idx1 from 0 to maxNumber
inner loop idx2 from 0 to maxNumber
array[idx1][idx2] = (idx1) * (idx2)
end loop
end loop
Do the same to dump your generated array to screen.
First get it running. Afterwards you could try to alter the logic, so that it shows you only numbers from 1 to max.
hello # all i have this probleme i have two arraylist ta,ta1
ta is an 1D arraylist contain many string objects in every frame i got only one object i want to forme a new ArrayList ta1 witch take two or more object colectted from ta in n=2 case we got
1with2 2with3 3with4 ....
example i have n=2;
ta [aa,bb,cc,dd]
ta1 will be [aabb,bbcc,ccdd]
i have tried with this
String m = "";
String h = "";
int e = 0;
for (int i = 0; i <= ta.size(); i++) {
int n = Integer.parseInt(tt.getText());
while (n > 0) {
String t = (ta.get(e + i));
m = m + t;
e++;
n--;
}
ta1.add(m);
}
t3.setText(ta1.toString());
but its giving me that error in the title
tanks for your help in advance
First of all i<=ta.size() is wrong, since the valid indices of ta go from 0 to ta.size()-1.
Second of all, in your while loop you assume that e+i is a valid index in ta, which is also an assumption you can't make without testing first that e+i<ta.size().
First you should move
int n=Integer.parseInt(tt.getText());
to be before the for loop.
This way, changing
for (int i=0;i<=ta.size();i++)
to
for (int i=0;i<=ta.size()-n;i++)
will ensure that e+i<ta.size().
You should also reset the relevant variables in the correct place. I think this should work :
int n = Integer.parseInt(tt.getText());
for (int i=0;i<=ta.size()-n;i++){
int c = n;
String m = "";
int e = 0 ;
while(c>0){
String t=(ta.get(e+i));
m=m+t;
e++;
c--;
}
ta1.add(m);
}
t3.setText(ta1.toString());
for (int i=0;i<=ta.size();i++){
ArrayList is a 0 based index collection. That means that you go from 0 to size - 1. At the moment, you're going from 0 to size, which is causing the IndexOutOfBoundsException.
I'm not allowed to use methods from any class except String and IO Class
So my code snippet is:
String line = reader.readLine();
while (line != null) {
String[] elements = line.split(",");
// Array could be too big if there are multiple occurances of
// the same number
// Array length + 1 because I can't use the 0 and with a input line of
// 1,2,3 for example would be the length 3 but I would have the
// numbers 0,1,2 in the Array as my index.
String[][] placeholderMatrix = new String[elements.length+1][elements.length+1];
for(int i = 0; i < elements.length-1; i++){
placeholderMatrix[(int)elements[i]][(int)elements[i+1]] = 1;
}
line = reader.readLine();
}
In the File I'm getting are only numbers like that: 1,2,3,4,5,8,7,4
So in my splitted String Array are only Numbers but now if I want to use them as my index for my Matrix(placeholderMatrix)
My problem is in my for loop where I want to use them as my Index I can't use them because it is a String Array. Normally I would use Integer.parseInt but I'm not allowed to :/
Any ideas on how I can implement them as my Index? and any Idea how I can get the perfect length of my Matrix? Because If I get the following numbers: 1,2,2,2,3 My Matrix should only have the numbers:
0 1 2 3
1
2
3
But if I'm using elements.length+1 for the length of my Matrix I would get the numbers 0 1 2 3 4 5
Hope you could understand my problem. Sorry for my bad english and Thanks in advance.
Edit: SO i got another problem with that. If I implement the method(parseInt) of Dici and am using it in the line "placeholderMatrix[parse(elements[i])][parse(elements[i+1])] = 1;" I'm getting the error ArrayOutOfBounce because my defined Array is just the length of my splitted String Array elements. But if I define it with Integer.MAX_VALUE as my length I get a memory error because it is too big. Any ideas?
Edit2: My Task:
I have to take a row of Numbers seperated by ",". (I will split it with the String split method to get only the numbers) Now I have to create a Matrix(2 dimensional Array) and look for the number at the index i of my new String Array and the number at the index i + 1 and have to take the first Number as my column and th second as my row (or vice versa) and implement at that point a 1. Now are my Numbers I will get from 1 to Integer.MAX_VALUE so I would have to create such a big Matrix but this isn't possible because I get the MemoryError.
Error: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at Test.main(Test.java:29)
To understand what I have to do: http://de.wikipedia.org/wiki/Adjazenzmatrix the image at the right but for numbers from to Integer.MAX_VALUE so my 2D Array has to be defined with the length of Integer.MAX_VALUE?
Edit:
So Dici asked for an example:
My Sequence could be: 1,2,5,4
So my Matrix should be:
Hope this is what you wanted Dici
But the numbers I can get from the sequence are 1 to Integer.MAX_VALUE
For converting strings to integers, you can simply implement your own integer parser, it is not complicated. You can start with this and improve it if needed.
public int parseInt(String s) {
int n = 0;
int pow = 1;
for (int i=s.length() - 1 ; i>=0 ; i--) {
String si = String.valueOf(s.charAt(i);
if (si.matches("[0-9]")) {
n += pow*(s.charAt(i) - '0');
pow *= 10;
} else if (si.matches("+|-") && i == 0)
n *= s.charAt(i) == '+' ? 1 : -1;
else
throw new NumberFormatException();
}
return n;
}
Then, I'll handle the second part of your problem. If Integer.MAX_VALuE is one of your input values, you cannot possibly allocate an Integer.MAX_VALUE x Integer.MAX_VALUE matrix. What you need to do is assign contiguous ids to your input values and record the ids in a map so that you can access easily the index of the matrix corresponding to one node value. Here is an example to get you to understand :
public void someMethod() {
int id = 0;
Map<Integer,Integer> idMap = new HashMap<>();
String[] split = reader.readLine().split(",");
int [] nodes = new int[split.length];
for (int i=0 ; i<nodes.length ; i++) {
nodes[i] = parseInt(split[i]);
if (!idMap.containsKey(nodes[i]))
idMap.put(nodes[i],id++);
}
// the map is now constructed, it should probably be stored in an attribute
int[][] placeholderMatrix = new int[nodes.length][nodes.length];
for(int i = 0; i < nodes.length; i++){
if (i > 0) placeholderMatrix[idMap.get(nodes[i])][idMap.get(nodes[i-1])] = 1;
if (i < nodes.length-1) placeholderMatrix[idMap.get(nodes[i])][idMap.get(nodes[i+1])] = 1;
}
}
There are other ways to do it, let me know if this solution is ok
You could do something like:
String keyword = "1,2,3,4,5,8,7,4";//input line from file
String replacedKeyword = keyword.replaceAll("[^\\d]", "");//except numbers replace all. Assuming one digit numbers only.
String[][] placeholderMatrix = new String[replacedKeyword.length()+1][replacedKeyword.length()+1];
char keys[] = replacedKeyword.toCharArray();
for (int i = 0; i<keys.length - 1; i++) {
placeholderMatrix[keys[i] - '0'][keys[i + 1] -'0'] = "1";
}
I couldn't really understand what you want exactly. but, if that going to help a simple method to convert String number to int:
int toInt(String number) {
int num = 0;
for (int i=0; i<number.length(); i++) {
num = num*10 + (number.charAt(i)-'0');
}
return num;
}
alright so im making a program that prints out how many times the numbers 0-9 were input, its supposed to go on forever, until the user types a negative number, then its gonna stop the program and print out the result, heres my code so far:
import java.util.Scanner;
public class opg33 {
public static void main(String args[]) {
System.out.println(1 + ":" + "\t" + "Integer 0-9");
Scanner keyboard = new Scanner(System.in);
int[] a = new int[10];
int counter = 0;
int input;
input = keyboard.nextInt();
boolean exit = true;
while (exit == true) {
counter++;
System.out.println((counter + 1) + ":" + "\t" + "Integer 0-9");
if (input > -1 && input < 10) {
a[input]++;
}
input = keyboard.nextInt();
if (input < 0) {
exit = false;
for (int i = 0; i < a.length; i++) {
System.out.print(i + ":");
for (int n = 0; n < a[i]; n++)
System.out.print("x");
System.out.println();
}
}
}
}
}
as you can see this program works perfectly fine, just as I wanted it to! the only question I have, is, how can I make it print out vertically like a bar graph (columns), instead of horizontally? thanks in advance!
You mean something like...?
1: Integer 0-9
1
2: Integer 0-9
1
3: Integer 0-9
2
4: Integer 0-9
2
5: Integer 0-9
2
6: Integer 0-9
3
7: Integer 0-9
3
8: Integer 0-9
7
9: Integer 0-9
8
10: Integer 0-9
-1
x
x x x
x x x x x
0 1 2 3 4 5 6 7 8 9
The first thing you need to do is determine the max height of the chart...
// Calculate the required height...
/*
All this loop does, is loops through the array "a"
and finds the maximum value contained within,
this is the largest number of times the user
entered that value
The loop itself is just an enhanced "for-next-loop",
that is, it's a short cutted way of saying...
for (int index = 0; index < a.length; index++) {
int value = a[index];
...
}
*/
int maxFrequency = 0;
for (int value : a) {
// This is a really simply way to calculate the max value within
// range, it just says, return me the value which is the larger
// of two...
maxFrequency = Math.max(value, maxFrequency);
}
Next, you need to print each row of the chart, starting at the top and moving to the bottom. For each column, you need to determine if it has a value to be displayed within that row...
// This builds each row
for (int row = maxFrequency; row > 0; row--) {
// This is used instead of String concatenation (String + String)
// This is the preferred mechanism for doing String concatenation
// in loops as it uses less memory and will generally be faster...
StringBuilder sb = new StringBuilder(30);
// We need to inspect each value in the array to determine
// if we need to display something...
// The basic idea is, we will only start displaying "x"
// when the value in the array >= the row number...
for (int value : a) {
// This just appends each column value as
// required, prefixing and suffixing it with spaces
sb.append(" ");
if (value >= row) {
sb.append("x");
} else {
sb.append(" ");
}
sb.append(" ");
}
// Print the row...
System.out.println(sb.toString());
}
And finally, you need to print the footer...
StringBuilder sb = new StringBuilder(30);
for (int i = 0; i < a.length; i++) {
sb.append(" ").
append(i).
append(" ");
}
System.out.println(sb.toString());
The hows and why of StringBuilder
A book could be written on this subject, so the information provided here is just an overview...
StringBuilder should be used, especially, when concatenating Strings in loops, basically because it reduces the number of temporary, short lived objects that are created and makes the process more efficient.
Normally the Java compiler will convert String concatenation to use StringBuilder internally, but because of the nature of loops, can't do so. In your case, it's probably not all that important, but in long running programs which might iterate through the loop, hundreds, thousands or even millions of time, it becomes a performance bottleneck, so it is a good habit to form.
Internally, a StringBuilder is a self managed char array, this is not particular important, but it's nice to know. When you use .append, the StringBuilder is taking the content, making space for it within it's internal buffer and writing out the content to it. It might sound like that's introducing it's own overheads and to a certain extent it is (you can do things to imittergate these), but it's less then having to run a garbage collection cycle...
toString simply then converts the char array to a String object...
You can find more information at The StringBuilder Class