This question already has answers here:
String Comparison in Java
(8 answers)
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 3 years ago.
I am supposed to write sequential/linear search on a String array. I am very close to finishing, but part of the assignment confuses me. It says to compare the target item with successive element of the list until the target matches or target is less than the current element of the array. How can a String be more or less than another element when there is no numerical value? Maybe I'm just not thinking about it correctly. Here is my program so far:
public class SequentialSearchString {
public static boolean sequential (String[] numbers){
//Set the target item to an arbitrary String that should return true.
String T1 = "Frank";
for (int i = 0; i < numbers.length; i++){
if (numbers[i] == T1){
return true;
}
if (numbers[i] != T1){
numbers[i] = numbers[i+1];
}
}
return false;
}
public static boolean sequential2 (String[] numbers){
//Set the target key to String that should return false.
String T2 = "Ian";
for (int i = 0; i < numbers.length; i++){
if (numbers[i] == T2){
return true;
}
if (numbers[i] != T2){
numbers[i] = numbers[i+1];
}
}
return false;
}
public static void main(String[] args) {
//Create a list of 8 Strings.
String [] numbers =
{"Ada", "Ben", "Carol", "Dave", "Ed", "Frank", "Gerri", "Helen", "Iggy", "Joan"};
//If the first target item (T1) is found, return Succuss. If not, return failure.
if (sequential(numbers) == true){
System.out.println("Success. 'T1' was found");
}
else {
System.out.println("Failure. 'T1' was not found");
}
//If the second target item (T2) is found, return Succuss. If not, return failure.
if (sequential2(numbers) == true){
System.out.println("Success. 'T2' was found");
}
else {
System.out.println("Failure. 'T2' was not found");
}
}
}
The first method works fine, but I appear to be having issues with searching for elements that are not in the list. Here is the error message I get after running the program:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
at SequentialSearchString.sequential2(SequentialSearchString.java:32)
at SequentialSearchString.main(SequentialSearchString.java:50)
Success. 'T1' was found
Any help understanding the assignment and fixing the exception would be much appreciated.
numbers[i] = numbers[i+1];
Is likely to cause your ArrayIndexOutOfBoundsException.
Your clause checks i < numbers.length. So you set the bounds. However if i == numbers.length - 1 then you will try to access i+1 which is larger then your array so it is out of bounds.
For example: numbers.length is 4. So i can be
3. With i+1 you try to access numbers[4] which would be the fifth position as arrays start with 0 and numbers[3] would be the last position.
The ArrayIndexOutOfBoundsException is due to the fact you use:
for (int i = 0; i < numbers.length; i++)
and latter:
numbers[i] = numbers[i+1];
When i equals numbers.length-1 (last iteration), i+1 equals numbers.length. Then you try to read numbers[numbers.length] which is wrong (valid index is from 0 to numbers.length-1).
You've got to use :
for(int i=0;i<numbers.length-1;i++)
to prevent the exception. Now, I'm not sure it would solve your whole problem, but the Exception certainly.
Related
I'm trying to get all of the indexes of a Boolean array to be printed out where its element is true. The end goal is to be able to find a prime number of the indexes (where I change each index number that isn't prime to false in the array) then print out only what is left of the prime numbers of the indexes of the array.
The very first step I'm just trying to do is at least to get some integer index to print out, but nothing seems to be working and I don't know what is wrong.
public class PriNum{
private boolean[] array;
public PriNum(int max){
if (max > 2){ //I don't have any problems with this if statement
throw new IllegalArgumentException();
}
else{
array = new boolean[max];
for(int i = 0; i < max; i++){
if(i == 0 || i == 1){ //Automatically makes 0 and 1 false
//because they are not prime
array[i] = false;
}
else{
array[i] = true;
}
}
toString(); //I know for sure the code gets to here
//because it prints out a string I have
// there, but not the index
}
}
public String toString(){
String s = "test"; //this only prints test so I can see if
//the code gets here, otherwise it would just be ""
for (int i = 0; i < array.length; i++){
if(array[i] == true){
s = s + i; //Initially I tried to have the indexes returned
//to be printed and separated by a comma,
//but nothing comes out at all, save for "test"
}
}
return s;
}
}
EDIT: Included is the driver class that's requesting the print of the class PriNum
class Driver{
public static void main(String [] args){
PriNum theprime = null;
try{
theprime = new PriNum(50);
}
catch (IllegalArgumentException oops){
System.out.println("Max must be at least 2.");
}
System.out.println(theprime);
}
}
I tried running this, and the first change that needs to happen is to set this argument:
if(max < 2)
Then, if I'm reading this correctly: 0 and 1 are false. Every index after that is true. The output is fine as I see it. Just all the numbers crunched as a continuous list.
To get a better output, put a space between indexes:
if(array[i] == true){
s = s + " " + i;
}
You may even just output to screen directly as
if(array[i])
System.out.print( i );
numbers is initialized without declaration, array is declared but not initialized anywhere in your code. You have also a syntax error after array[i] = true, should be curly brace...
When i have a problem with the code im writing, i usually handle it like a story. Each command is a sentence in a story. The sentences needs to make sense in order for the story to be complete/right.
So im learning java from scratch now with the MOOC course at Helsinki University. I got somewhat stuck at exercise 68. The program is suppose to compare integer values of a list(array) together with user input. What i programmed is a method that return true if the user input number is already on the list, and false if its not.
What I said about story at the start: The commented out code is my initial code. This did not past the last test but in my head both the commented out code and the other code say basically the same
Error message (from last test):
"Answer wrong when parameter was list [0, 7, 9, -1, 13, 8, -1] and value 8 expected: false but was: true"
public static boolean moreThanOnce(ArrayList<Integer> list, int searched)
// if (list.size()==1) {return false;}
//
// for (int i = 0; i < list.size();i++ ){
// if (list.contains(searched))
//
// {
//
// return true; }
//
// }
//return false;
//
int counter = 0;
for (int num : list) {
if (searched == num) {
counter++;
}
}
if (counter >= 2){
return true;
} else {
return false;
}
}
I understand that there is something wrong, just cant seem to figure it out. Do you see why the last code would be accepted, but not the first (commented out one) ?
If any use, the rest of the code (not my work) is this:
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(3);
list.add(2);
list.add(7);
list.add(2);
System.out.println("Type a number: ");
int number = Integer.parseInt(reader.nextLine());
if (moreThanOnce(list, number)) {
System.out.println(number + " appears more than once.");
} else {
System.out.println(number + " does not appear more than once. ");
}
}
}
Code that is commented out guaranties only that if true there is at least one of occurance in array, maybe there are more but not guaranted. If function returns false thes may be 1 or no occurance.
Reason: If arrary os bigger than 1 it does not mean that there are 2 or more occurances of value you search for.
Posible solution: Add counter like uncommented code.
Your first algorithm has a few flaws, first you test for a length of one explicitly. Not null, and not an empty List. Second, you should prefer the List interface to the ArrayList explicit type. And finally, you need to consider the sublist offset by one of the current position when you call contains (clearly the list contains at least the current value).
I think you wanted something like
public static boolean moreThanOnce(List<Integer> list, int searched) {
if (list == null || list.size() < 2) {
return false;
}
int len = list.size();
for (int i = 0; i < len - 1; i++) {
if (list.get(i).equals(searched)
&& list.subList(i + 1, list.size()).contains(searched)) {
return true;
}
}
return false;
}
And, we can express that as generic method. Like,
public static <T> boolean moreThanOnce(List<T> list, T searched) {
if (list == null || list.size() < 2) {
return false;
}
int len = list.size();
for (int i = 0; i < len - 1; i++) {
if (list.get(i).equals(searched)
&& list.subList(i + 1, list.size()).contains(searched)) {
return true;
}
}
return false;
}
or, if you're using Java 8+, use a Stream and filter and then count like
public static <T> boolean moreThanOnce(List<T> list, T searched) {
if (list == null || list.size() < 2) {
return false;
}
return list.stream().filter(v -> v.equals(searched)).count() > 1;
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
Currently having difficulty with Selection Sort and Bubble Sort codes.
The selection sort is used to sort out student ID in ascending order and the bubble sort is used to sort out last names in ascending order. The program compiles but crashes upon choosing choice 10 or 11.
My array is declared as follows:
student[] list = new student[100]; //my array
This is the code that I have for selection sort and bubble sort. I am using an array with methods:
if (choice == 10) { // Dissplay the sorted array by student id
SortArrayBySelection(list);
System.out.println("Sorted studentid are:");
for (int i =0; i< studentNumber; i++)
{
System.out.println(list[i]);
}
}
if (choice == 11){ // Display the sorted array by family name
BubbleSort(list);
System.out.println("The sorted names are:");
for(int i = 0; i < studentNumber; i++)
{
System.out.println(list[i].Getfamilyname());
}
}
} while (choice != 1);
}
public static void SortArrayBySelection(student[] arrayToSort){ // Function to sort out the array on sutdentid
for(int i = 0; i < arrayToSort.length-1; ++i)
{
int minIndex = i;
int studentid3 = arrayToSort[i].Getstudentid();
int studentid2 = arrayToSort[minIndex].Getstudentid();
for(int j = i + 1; j <arrayToSort.length; ++j)
{
int studentid1 = arrayToSort[j].Getstudentid();
if(studentid1 < studentid2)
{
minIndex = j;
}
}
int temp = studentid3;
studentid3 = studentid2;
studentid2 = temp;
}
}
public static void BubbleSort(student[] arraySort){
String t;
for(int i = 0; i<arraySort.length; i++){
for(int j=0; j<arraySort.length-1;j++){
String str1 = arraySort[j].Getfamilyname();
String str2 = arraySort[j+1].Getfamilyname();
if(str1.compareTo(str2)<0){
t = str1;
str1 = str2;
str2 = t;
}
}
}
}
Any suggestions would be appreciated! thank you
Errors:
Exception in thread "main" java.lang.NullPointerException
at client.Client.SortArrayBySelection(Client.java:270)
at client.Client.main(Client.java:232)
Exception in thread "main" java.lang.NullPointerException
at client.Client.BubbleSort(Client.java:288)
at client.Client.main(Client.java:246)
As you have not mentioned line numbers in your code, also the Student class and the code where you are preparing the student[] list = new student[100]. So, as far as i can see the code from following lines you can get the java.lang.NullPointerException
Your list length will be always 100 as you are creating it with that value. So if it something dynamic values which you are preparing at runtime then it will be better if you use ArrayList<student> list=new ArrayList<student>(); and add the values using list.add(yourObject);.
Exception in thread "main" java.lang.NullPointerException
at client.Client.SortArrayBySelection(Client.java:270)
at client.Client.main(Client.java:232)
For this error you are calling SortArrayBySelection method and the lines which may end up in the above errors are
int studentid3 = arrayToSort[i].Getstudentid();
int studentid2 = arrayToSort[minIndex].Getstudentid();
int studentid1 = arrayToSort[j].Getstudentid();
Reason for the error :
You don't have the values present at the given index and as you are creating an array of length 100 where you put only let say 10-15 values then it will always have no values in other location. But your for-loop will go to 100 index position in which after 10-15 index you will always get null by calling the getters.
Same reason is for your other method as well.
Whenever I try to run the code I get IndexOutOfBoundsException. I have tried numerous of ways fixing it but none of them have helped. The method should add a new String element "****" into ArrayList before every String which's length is equal to 4. In this case, it must add "****" before "5555".
Where could be the problem?
import java.util.ArrayList;
public class Main {
public static ArrayList<String> markLength4(ArrayList<String> list) {
int sum = 0;
for ( int i = 0; i < list.size(); i++) {
if (list.get(i).length() == 4) {
list.add(list.indexOf(i), "****");
}
}
return list;
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("ddddddddddddd");
list.add("fffffffffffff");
list.add("5555fdgdfg");
list.add("5555");
list.add("5555");
System.out.println(markLength4(list));
}
}
list.indexOf(i) will return -1, since i doesn't appear in your list. Therefore adding an element at the -1 position will throw an exception.
If you change list.add(list.indexOf(i), "****") to list.add(i, "****");, you'll get an infinite loop that will end with OutOfMemoryError, since the newly added String also has a length() of 4, so another String will be added on the next iteration, and so on.
i is not in your arraylist - it is a list of String, not Integer. That means that list.indexOf(i) == -1.
From your description, I think you mean:
list.add(i, "****");
but you will also need to increment i, e.g.
list.add(i++, "****");
to avoid the infinite loop that Eran mentions.
Or, of course, you can iterate the list backwards, and avoid the infinite loop/need to change the loop variable inside the loop body:
for ( int i = list.size() - 1; i >= 0; i--)
{
if (list.get(i).length() == 4)
{
list.add(i, "****");
}
}
import java.util.ArrayList;
public class Test {
public static ArrayList<String> markLength4(ArrayList<String> list) {
int sum = 0;
for (int i = 0; i < list.size(); i++) {
if (list.get(i).length() == 4) {
list.add(i++, "****");
}
}
return list;
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("ddddddddddddd");
list.add("fffffffffffff");
list.add("5555fdgdfg");
list.add("5555");
list.add("5555");
list = markLength4(list);
for (String x : list) {
System.out.println(x);
}
}
}
You'll loop forever this way, because there's 4-lengthened strings forward and you keep adding...
You can solve this by looping from the end, but you'll have to be careful with your index(you should add and increment the index to avoid that)
After Editing list.add(i++,"****"); the code should work just fine.
Notable
If you want to add before use i++;.
If you want to add after your match use ++i;.
list.indexOf(i) is not present in the list . It will produce -1
-1 is not available in ArrayList
Replace the Line
list.add(list.indexOf(i), "****");
with the following line
list.set(i, "****");
It replace the existing content of the List with new element in the index of i with new element i.e (****)
list.indexOf(i) where i is an int and therefore not in your list will throw your error as stated in comments (index -1).
use either of the following:
list.add("str") to add a String to the end of the list
OR
list.set(i, "****") which will set the value at a given index to this new string.
In the markLength4 method, by adding the element in the for loop you keep adding Strings and increasing the list size. You need a flag that tells the index and then ends the loop. You can try something like that
public static ArrayList<String> markLength4(ArrayList<String> list) {
int i = 0;
boolean found = false;
int pos = 0;
while(i < list.size() && !found){
if (list.get(i).length() == 4) {
found = true;
pos = i;
}
i++;
}
list.add(pos, "****");
return list;
}
Basically what I want to do is to check on each element in an array of int, if all elements are of the same value.
I create int array as below to pass to the method for comparing each array element, it return boolean true even tough the elements are not all the same values.
Int[] denominator = {3,3,4,3};
boolean compare;
compare = bruteforce(denominator);
public static boolean bruteforce(int[] input) {
int compare =0;
int count =0;
for (int i = 0; i < input.length; i++) {
compare = input[i];
while(count<input.length){
if(input[i+1]==compare){
return true;
}
i++;
count++;
}//end while
}//end for
return false;
}//end method
I suppose the method above will loop for and keep compare for each element of the array.
When I print out the output, it showed that it only loop once, the return the boolean as true.
I really lost the clue what could be wrong in my code.
Perhaps I just overlook of some silly mistakes.
Try,
Integer[] array = {12,12,12,12};
Set<Integer> set = new HashSet<Integer>(Arrays.asList(array));
System.out.println(set.size()==1?"Contents of Array are Same":"Contents of Array are NOT same");
Explanation:
Add the array to a set and check the size os set , if it is 1 the contents are same else not.
You only need one loop and should return false as quickly as possible where applicable (i.e. when you encounter an element that doesn't match the first).
You also need to account for the edge cases that the input array is null or has one element.
Try something like this, which I minimally adapted from the code you provided...
public class BruteForceTest {
public static boolean bruteforce(int[] input) {
// NOTE: Cover the edge cases that the input array is null or has one element.
if (input == null || input.length == 1)
return true; // NOTE: Returning true for null is debatable, but I leave that to you.
int compare = input[0]; // NOTE: Compare to the first element of the input array.
// NOTE: Check from the second element through the end of the input array.
for (int i = 1; i < input.length; i++) {
if (input[i] != compare)
return false;
}
return true;
}
public static void main(String[] args) {
int[] denominator = {3,3,4,3};
boolean compare = bruteforce(denominator);
// FORNOW: console output to see where the first check landed
System.out.print("{3,3,4,3}:\t");
if (compare)
System.out.println("Yup!");
else
System.out.println("Nope!");
// NOTE: a second array to check - that we expect to return true
int[] denominator2 = {2,2};
boolean compare2 = bruteforce(denominator2);
System.out.print("{2,2}:\t\t");
if (compare2)
System.out.println("Yup!");
else
System.out.println("Nope!");
/*
* NOTE: edge cases to account for as noted below
*/
// array with one element
int[] denominator3 = {2};
System.out.print("{2}:\t\t");
if (bruteforce(denominator3))
System.out.println("Yup!");
else
System.out.println("Nope!");
// null array
System.out.print("null:\t\t");
if (bruteforce(null))
System.out.println("Yup!");
else
System.out.println("Nope!");
}
}
...and outputs:
{3,3,4,3}: Nope!
{2,2}: Yup!
{2}: Yup!
null: Yup!
If an array elements are equal you only need to compare the first element with the rest so a better solution to your problem is the following:
public static boolean bruteforce(int[] input) {
for(int i = 1; i < input.length; i++) {
if(input[0] != input[i]) return false;
}
return true;
}
You don't need more than one loop for this trivial algorithm. hope this helps.
If all elements are the same value, why not use only one for loop to test the next value in the array? If it is not, return false.
If you want to check if all elements are of same value then you can do it in a simpler way,
int arr = {3,4,5,6};
int value = arr[0];
flag notEqual = false;
for(int i=1;i < arr.length; i++){
if(!arr[i] == value){
notEqual = true;
break;
}
}
if(notEqual){
System.out.println("All values not same");
}else{
System.out.println("All values same);
}
Right now, you are not checking if "all the elements are of the same value". You are ending the function and returning true whenever (the first time) two elements are equal to each other.
Why not set the boolean value to true and return false whenever you have two elements that are not equal to each other? That way you can keep most of what you have already.
if(input[i+1]!=compare) return false;
public class Answer {
public static void main(String[] args)
{
boolean compare = false;
int count = 0;
int[] denominator = { 3, 3, 4, 3 };
for (int i = 0; i < denominator.length; i++)
{
if(denominator[0] != denominator[i])
{
count++;
}
}
if(count > 0)
{
compare = false;
} else
{
compare = true;
}
System.out.println(compare);
}
}
One mistake that I noticed right of the bat was that you declared your array as Int[], which is not a java keyword it is in fact int[]. This code checks your array and returns false if the array possesses values that are not equal to each other. If the array possesses values that are equal to each other the program returns true.
If you're interested in testing array equality (as opposed to writing out this test yourself), then you can use Arrays.equals(theArray, theOtherArray).