In my code I'm trying to go through the arraylist and see if theres any reoccurring numbers. I keep getting an error saying i have a missing return statement. Is my code correct and how do I fix this problem.
public static void main(String[] args) {
Scanner in = 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(in.nextLine());
if (moreThanOnce(list,number)) {
System.out.println(number + " appears more than once");
}
else
System.out.println(number + " number does not appear more than once");
}
public static boolean moreThanOnce(ArrayList<Integer> list , int number) {
int count = 0;
for (int i = 1; i < list.size(); i ++ ) {
if (list.get(i) == number) {
count ++;
if (count > 1) {
return true;
}
else
return false;
}
}
Just remove the else part and move the "return false" outside the for loop in your moreThanOnce method
Change to:
public static boolean moreThanOnce(ArrayList<Integer> list , int number) {
int count = 0;
for (int i = 1; i < list.size(); i ++ ) {
if (list.get(i) == number) {
count ++;
if (count > 1) {
return true;
}
}
}
return false;
}
This guarantees that a return statement (false) is sent back if either there is not a recurring number that's equal to number and if it never enters the for-loop as well. It will return true if the conditions you put is met.
public static boolean moreThanOnce(ArrayList<Integer> list , int number) {
int count = 0;
for (int i = 1; i < list.size(); i ++ ) {
if (list.get(i) == number) {
count ++;
if (count > 1) {
return true;
}
else //delete this line
return false; // delete this line
}
}
return false;//add return here
}
To solve the error, it only needs a return outside the for loop.
And I think you should delete else logic, that makes the method cannot find the number which appears more than one time correctly.
You are missing a return statement in the case of the for loop not being executed in the moreThanOnce method.
You're missing a closing brace "}" for moreThanOnce(). It has four open braces, but only three closing braces.
Most code-oriented editors will match braces for you, and help track down imbalanced braces (and parens, etc.) Figure out how to do that in your editor, as that's something you'll need throughout your programming career.
Related
I'm working on my university assignment which requires me to program an eviction algorithm. I am new to programming and have only done Python before. Below is what I have done so far. The code compiles fine but I am not getting the output that I was expected to get.
getting user input and then calling the method for no eviction:
System.out.println();
System.out.println("Cache content: ");
print_array(org_cache, size);
System.out.println("Request sequence: ");
print_array(request, count);
try {
copy_array(org_cache, cache, size);
System.out.println("no_evict");
no_evict(cache, size, request, count);
}
catch (Exception e) {
System.out.println("ERROR: no_evict");
the method:
static void no_evict(int[] cache, int c_size, int[] request, int r_size) {
int i = 0;
boolean found = false;
String result = "";
String resultHit = "";
String resultMiss = "";
for(int x = 0; x < r_size; x++) { //for loop goes through every requests
while(i < c_size || found == false) { //while loop brings a page through every cache value
if(request[x] == cache[i]){
found = true;
} else {
i += 1;
}
}
if(found == true) {
result += "h";
resultHit += "h";
} else {
result += "m";
resultMiss += "m";
x += 1; //proceeds to next value in request sequence
}
}
System.out.println(result);
System.out.println(resultHit.length() + "h " + resultMiss.length() + "m");
}
it does not output the result string but instead outputs this:
Cache content:
20 30 10 5 40
Request sequence:
20 30 10
no_evict
You will notice that your program doesn't actually exit. This is because it's stuck in an infinite loop, just as what would happen in Python.
If you run it in a debugger or hit Ctrl-\ in a console, you'll see that it's stuck in this loop:
while(i < c_size || found == false) { //while loop brings a page through every cache value
if(request[x] == cache[i]){
found = true;
} else {
i += 1;
}
}
The condition is true as long as i < c_size because you used ||, logical "or". You probably intended to use &&, so that find = true will break the loop.
PS: The Java compiler doesn't care about indenting, but humans do. Please use your editor's indenting function to make the code easier to read.
As #that other guy mentioned, you are using || instead of &&.
But you don't need the second qualifier. Just use:
i = 0;
while(i < c_size ) {
if(request[x] == cache[i]){
found = true;
break;
} else {
i += 1;
}
}
or
for ( int i=0; i < c_size; i++ ) {
if ( request[x] < cache[i] ) {
found = true;
break;
}
}
There is another problem with your algorithm: you initialise i right at the beginning but never reset it to zero.
You probably want to move the int i = 0 statement between the for and the while statement.
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;
}
I have a method that is supposed to return the smallest value of an array. The array is in the parametre of the method, so you input the values of your own choosing when you make an object of the class. This is the method I have come up with so far:
public class minsteNummer {
public minsteNummer() {
}
public int minsteNummer(Integer[] nummer) {
int minste = 0;
for(int i = 0; i< nummer.length; i++){
if(nummer[i] <= nummer.length) {
minste = i;
System.out.println("Minste nummer er " + minste);
} else if(nummer.length == 0) {
return 0;
}
}
return 0;
}
}
It does not execute the way I want it to, and I cant figure out what exacly it prints, but it is definetly not the smalles number of the array. I have tried with a while loop, but that does not work either.
Does anyone know where the fault in the code is, and how to improve it? I would also like it to just return, not print, the smalles number, but when I try to put "return minste;" in the if-statement, it says "unexpected return value".
Thanks in advance.
There are few places in your code that need attention:
As method scope is public you should always check for invalid input
Should not assign: int minste = 0; as there could be a negative number in a given array
When assign minimum number, should always compare it to the loop current number
if (minste > nummer[i]) minste = nummer[i];
Finally always return your minimum number return minste;
All together:
public static int minsteNummer(Integer[] nummer) {
if (nummer==null || nummer.length == 0) {
throw new IllegalArgumentException("Bad or empty array");
}
int minste = nummer[0];
for (int i = 1; i< nummer.length; i++){
if (minste > nummer[i]) minste = nummer[i];
}
System.out.println("Minste nummer er " + minste);
return minste;
}
It is worth to mention that you could use Java build-in functionality for such a basic task, i.e. sort array in ascending order and get first element:
public static int minsteNummer(Integer[] nummer) {
if (nummer==null || nummer.length == 0) {
throw new IllegalArgumentException("Bad or empty array");
}
Arrays.sort(nummer);
return nummer[0];
}
use streams
Integer[] arrayB = null;
OptionalInt min = Arrays.stream(arrayB).mapToInt(Integer::intValue).min();
public int minsteNummer(Integer[] nummer) {
int minste = Integer.MAX_VALUE;
for(int i = 0; i< nummer.length; i++){
if(nummer[i] < minste ) {
minste = nummer[i] ;
}
if(minste != Integer.MAX_VALUE)
return minste;
else
return 0;
}
I am having the following string and want to track the closing bracket of ROUND( ) in my string.
"=ROUND(IF(AND($BY18=2);CA18*CB18/$M$11;IF($BY18=3;CA18*CB18/$M$10;IF($BY18=4;ROUND(CA18*CB18;$M$10)/$M$9;CA18*CB18)))/$M$12;$M$11)";
public class RoundParser {
public static String parseRound(String text) {
text = text.toUpperCase();
String result;
char[] ch = text.toCharArray();
int count = -1;
String temp = "";
for (int i = 0; i < ch.length; i++) {
temp = temp + ch[i];
System.out.println(count);
if ("ROUND(".equals(temp)) {
count++;
}
if ("(".equals(temp)) {
count++;
}
if (")".equals(temp) && count > 0) {
count--;
}
if (")".equals(temp) && count == 0) {
ch[i] = '#';
}
if (!"ROUND(".startsWith(temp) || temp.length() > 5) {
temp = "";
}
}
text = String.valueOf(ch);
result = text;
return result;
}
public static void main(String[] args) {
String text = "=ROUND(IF(AND($BY18=2);CA18*CB18/$M$11;IF($BY18=3;CA18*CB18/$M$10;IF($BY18=4;ROUND(CA18*CB18;$M$10)/$M$9;CA18*CB18)))/$M$12;$M$11)";
System.out.println(parseRound(text));
}
}
However, using my parser at the moment I am getting:
=ROUND(IF(AND($BY18=2);CA18*CB18/$M$11;IF($BY18=3;CA18*CB18/$M$10;IF($BY18=4;ROUND(CA18*CB18;$M$10)/$M$9;CA18*CB18))#/$M$12;$M$11#
The output I want to get is:
=ROUND(IF(AND($BY18=2);CA18*CB18/$M$11;IF($BY18=3;CA18*CB18/$M$10;IF($BY18=4;ROUND(CA18*CB18;$M$10#/$M$9;CA18*CB18)))/$M$12;$M$11#
As you can see the not the right ) are replaced, as ;$M$11)"; and ;$M$10). I really appreciate if you have any idea how to repalce these two cases.
there are 2 approaches to this
1) if the number of opening and closing brackets are always going to be equal, then you can just track the last closing bracket by using a for loop.
2) if you are not sure about opening and closing brackets to be equal, then you can so the following-->
public class RoundParser {
public static String parseRound(String text) {
text = text.toUpperCase();
String result;
char[] ch = text.toCharArray();
int count=0,pos=0;
int c[10];
for(int i=0;i<ch.length;i++){
if(ch[i].equals("(")){
count++;
if(ch[i-1].equals("D")){
c[pos]=count; //will store the count value at every opening round
pos++;
}
}
if(ch[i].equals(")")){
count--;
for(int j=0;j<10;j++){
if(c[j]==count) //if the closing of round had been encountered
ch[i]="#";
}
}
}
text = String.valueOf(ch);
result = text;
return result;
}
public static void main(String[] args) {
String text = "=ROUND(IF(AND($BY18=2);CA18*CB18/$M$11;IF($BY18=3;CA18*CB18/$M$10;IF($BY18=4;ROUND(CA18*CB18;$M$10)/$M$9;CA18*CB18)))/$M$12;$M$11)";
System.out.println(parseRound(text));
}
}
there you go.
i think this should work.
hope this helps.
You forgot an else:
else if (")".equals(temp) && count == 0) {
That will decrement count and if then count==0, it will decrement twice.
This problem can be done recursively.
First, you use method .indexOf("ROUND(") to detect the first occurrence of round().
Then, we need to determine which is the end ')' of this round(). A simple algo will be enough :
int start = text.indexOf("ROUND(") + "ROUND(".length();
int count = 1;
int end = -1;
for(int i = start; i < text.length; i++){
if(text.charAt(i) == '('){
count++;
}else if(text.charAt(i) == ')'){
count--;
}
if(count == 0){
end = i;
break;
}
}
After you detect the start and end of the outer round(), you can use text.substring(start, end) to remove the outer round(), and continue the above function recursively, until you find all round()
For recognition of multiple ROUND(X), I suggest
TreeMap<Integer,Pair<Integer,Integer>> map = new TreeMap<>();
int count = 0;
Where we store <start_index, <init_count, end_index>>
if ("ROUND(".equals(temp))
{
map.put(i, new Pair<Integer,Integer>(count, -1));
count++;
}
if ("(".equals(temp)) count++;
if (")".equals(temp))
{
if (count <= 0)
{
count = 0;
// Error: extra closing bracket
}
else
{
count--;
}
int max_i = -1;
for (Integer index : map.keySet())
{
if (index > max_i
&& map.get(index).second() == -1
&& map.get(index).first() == count)
{
max_i = index;
}
}
if (max_i > -1) map.get(max_i).setSecond(i);
}
Here's an algorithm..
If you are not sure that the last ")" would be the one you are looking for.
Start from index 0 of the String, for each "(" you encounter, increment the count, and for each ")" decrement the count, replace the ")" with "#".
Please find below a function in my code:
private static List<String> formCrfLinesWithMentionClass(int begin, int end, String id,
List<String> mList, int mListPos, List<String> crf) {
List<String> crfLines = crf;
int yes = 0;
mListPosChanged = mListPos;
//--------------------------------------------------------------------------
for (int crfLinesMainIter = begin; crfLinesMainIter < end; ) {
System.out.println(crfLines.get(crfLinesMainIter));
//---------------------------------------------------------------------------
//the total number of attributes without orthographic features
//in a crfLine excluding the class attribute is 98
if (!crfLines.get(crfLinesMainIter).equals("") && crfLines.get(crfLinesMainIter).split("\\s").length == 98) {
//in mList parenthesis are represented by the symbol
//in crfLines parenthesis are represented by -LRB- or -RRB-
//we make a check to ensure the equality is preserved
if(val.equals(crfLines.get(crfLinesMainIter).split("\\s")[0])) {
yes = checkForConsecutivePresence(crfLinesMainIter, mList, mListPos, id, crfLines);
if (yes > 0) {
mListPosChanged += yes;
System.out.println("formCrfLinesWithMentionClass: "+mListPosChanged);
for (int crfLinesMentionIter = crfLinesMainIter;
crfLinesMentionIter < crfLinesMainIter + yes;
crfLinesMentionIter++) {
String valString = "";
if (crfLinesMentionIter == crfLinesMainIter) {
valString += crfLines.get(crfLinesMentionIter);
valString += " B";
crfLines.add(crfLinesMentionIter, valString);
}
else {
valString += crfLines.get(crfLinesMentionIter);
valString += " I";
crfLines.add(crfLinesMentionIter, valString);
}
}
crfLinesMainIter += yes;
}
else {
++crfLinesMainIter;
}
}
else {
++crfLinesMainIter;
}
}
else {
++crfLinesMainIter;
}
}
return crfLines;
}
The problem I face is as follows:
crfLines is a List collections interface.
When the for loop (between //-----) starts out, the crfLines.get(crfLinesMainIter) works fine. But once, it enters into the if and other processing is carried out on it, even though "crfLinesMainIter" changes the crfLines.get(crfLinesMainIter) seems to get a certain previous value. It does not retrieve the actual value at the index. Has anyone faced such a scenario? Would anyone be able to tell me why this occurs?
My actual question is, when does it occur that even though the indexes might be different a list.get() function still retrieves a value from before which was at another index?
For example:
List crfLines = new LinkedList<>();
if crfLinesMainIter = 2
crfLines.get(crfLinesMainIter) brings me a value say 20 and this value 20 satisfies the if loop condition. So then further processing happens. Now when the for loop executes the values of crfLinesMainIter changes to say 5. In this case, crfLines.get(5) should actually bring me a different value, but it still brings me the previous value 20.
(Not an answer.)
Reworked (more or less) for some modicum of readability:
private static List<String> formCrfLinesWithMentionClass(int begin, int end, String id, List<String> mList, int mListPos, List<String> crf) {
List<String> crfLines = crf;
mListPosChanged = mListPos;
int i = begin;
while (i < end) {
if (crfLines.get(i).equals("") || (crfLines.get(i).split("\\s").length != 98)) {
++i;
continue;
}
if (!val.equals(crfLines.get(i).split("\\s")[0])) {
++i;
continue;
}
int yes = checkForConsecutivePresence(i, mList, mListPos, id, crfLines);
if (yes <= 0) {
++i;
continue;
}
mListPosChanged += yes;
for (int j = i; j < i + yes; j++) {
String valString = crfLines.get(j);
valString += (j == i) ? " B" : " I";
crfLines.add(j, valString);
}
i += yes;
}
return crfLines;
}
What is mListPostChanged? I find it confusing that it's being set to the value of a parameter named mListPos--it makes me think the m prefix is meaningless.
What is val in the line containing the split?