I have some code that I would like to make more efficient by recursion. Trouble is I don't know where to start. The code compares two arraylists a and b to see if they are equal. Assume the sizes of both arrays are equal.
The code is
public boolean isEqual(A B) {
boolean answer = false;
if (lessThanOrEqualTo(B) == true);
for (int i = 0; i < DList.size(); i++) {
if (DList.get(i) == B.DList.get(i)) answer = true;
else answer = false;
}
return answer;
}
I have currently written
public boolean isEqualRecursion(A B) {
if DList.size() == 0;
return false();
} else {
}
I know the stopping case is 0 as when size is 0 nothing happens. I have no idea what to write next
Any help will be appreciated
Thanks
I have some code that I would like to make more efficient by recursion.
It is unlikely that you can make it more efficient by recursion. The chances are that it will be less efficient, and also fragile. This is because standard Java compilers don't implement tail-call optimization. The fragility occurs because a recursive comparison algorithm is liable to trigger a stack overflow if the input arrays are large enough.
However, if you want to continue with this as "an exercise", then my HINT is to add an index argument to the isEqualRecursion signature ...
I think that this is a pretty good start for you. This looks through all your elements, assuming they are an array, and then checks if they are equal in size.
public boolean isEqual(ArrayList<?> a, ArrayList<?> b) {
if (a.size() != b.size())
return false;
for (int i = 0; i < a.size(); i++) {
if (!isEqual((ArrayList<?>)a.get(i), (ArrayList<?>)b.get(i))) {
return false;
}
}
return true;
}
Now a couple of things to consider:
This assumes that the content of a(and b) must be an ArrayList at line (ArrayList<?>)a.get(i) what if our ArrayList actually contains something else, like an Integer?
What if our array lists contain null as an item?
What if we pass in two null ArrayLists? (or even just one?)
I'm not sure the point of your function lessThanOrEqualTo(B) is this part of the question or did you write this down wrong?
Also what is a DList?
This is a typical recursion question. You might want to try something like this:
int x = 0;
if(Dlist.get(x) != B.Dlist.get(x)) {
return false;
} else {
x+1;
}
if( x!= dList.size()) {
recursion;
}
return true;
Related
This might be a stupid question but we're beginners and I didn't find an answer to my problem so here it is: We're developping a file system (small based) and we have this method that is supposed to move files from one Directory to another. (Deleting the file or directory from one and adding to another.)
We're using ArrayLists to store the Items (Item is then superclass of Directory and File).
Because of the fact that everything has to be sorted alphabetically, the method to move contains a while loop to verify where the item has to be placed (no preferences to Directories or Files) but for some reason the break statement I inserted is ALWAYS executed (or at least that's what I think is the reason.) Thanks!
Here's the code:
if(item != null){
boolean bool = false;
int i = 0;
loop: while(!bool && i <= items.size()-1) {
if(i==0) {
if(checkIfAlphabetic(item.getName(), items.get(0).getName())){ items.add(0,item);
bool = true;
}
else{
break loop;
}
}
else if(checkIfAlphabetic(items.get(i-1).getName(), item.getName()) && checkIfAlphabetic(item.getName(), items.get(i).getName() )) {
items.add(i, item);
bool = true;
}
else i++;
}
if(!bool){
items.add(item);
}
setModificationTime();
}
I already excuse myself if there are some things unclear.
PS. Also for some reason the Item I want to add always gets added twice.
As requested, the code for checkIfAlphabetic:
private boolean checkIfAlphabetic(String search, String target){
int[] searchInt = search.codePoints().toArray();
int[] targetInt = target.codePoints().toArray();
int i = 0;
while(i<search.length() && i<target.length()){
if(searchInt[i] > targetInt[i]){
return false;
}
else if(searchInt[i] < targetInt[i]) return true;
else i++;
}
if(search.length() < target.length()){
return true;
}
else return false;
}
Your while loop is faulty. It will always stop after the first iteration, no matter what.
This is what happens in order of statements. This is pseudo-code, not Java. Don't copy/paste, it won't work.
boolean bool = false;
int i = 0;
// entering the while loop:
if (!bool && i <= items.size() - 1) // returns true. We go in the while loop.
if (i == 0) // returns true, we go in that block.
if (check... ) // if this returns true, this happens:
bool = true;
else // if the previous statement returns false, this happens:
break;
So here, if the check... returns false, we're gonna get out of the loop. Let's continue in the other case:
// nothing else happens inside the loop, so go back to the loop condition.
if (!bool && i <= items.size() - 1) // Hey, wait a minute, bool is true. So "not" true is false. The condition is therefore not met, let's leave the loop.
So this is what happens, after a single execution, no matter what, your code exits the loop. In your scenario, bool = true is the near absolute equivalent to a break.
This is what you need to fix.
If I had to write your code, this is how I'd do it:
List<Item> items = ... ;
java.util.Collections.sort(items, new ItemNameComparator());
private static class ItemNameComparator implements Comparator<Item> {
#Override
public int compare(Item a, Item b) {
return a.getName().compareTo(b.getName());
}
}
If you use Java 8:
List<Item> items = ...;
items.sort((a, b) -> a.getName().compareTo(b.getName()));
All the tools exist in the Java libraries, use them instead of reimplementing them again and again.
I implemented a SuDoku backtracking algorithm, but it keeps giving me StackOverflow Error. Any other methods or algorithms to avoid this, because I can't get my head around forming a loop for this.
public boolean guess(int istart){
int i=istart, j=0; boolean found=false;
for(i=istart; i<9; i++){//find first empty cell
for(j=0; j<9; j++){
if(get(i,j)==0) {found=true; break;}
}
if(found) break;
}
boolean[] pos=pos_copy;//pos_copy is a length-9 boolean array with all elements set to true
for(int n=0; n<9; n++){//store all possible numbers in pos[]
if(get(i,n)!=0) pos[get(i,n)-1]=false;
if(get(n,j)!=0) pos[get(n,j)-1]=false;
if(get(start[i]+n/3, start[j]+n%3)!=0) pos[get(start[i]+n/3, start[j]+n%3)-1]=false;
}
for(int n=0; n<9; n++) if(pos[n]) {
set(i,j,n+1);
if(i==8 && j==8) return true;
if(guess(i)) return true;//recurse; gives Stackoverflow at this line
}
set(i,j,0);
return false;
}
There is no (realistic) way to put this in a loop, but you can circumvent the recursion using a Dequeue approach (in the form of a stack).
First create a class that holds the current state of numbers entered into the Sodoku-field. Then instead of calling set(...) create a copy of that field and set the value in that copy. Then put that copy in a Dequeue and terminate the function.
Your search loop then becomes:
SodokuField field;
while (((field = dequeue.pollLast()) != null) && (field.isComplete() == false)) {
guess(field);
}
if (field != null) {
showSolution(field);
}
This approach has two benefits: first you won't get any StackOverflowException anymore, and second: you can easily put the code part above in the run() method of a Runnable and have multiple threads wait on a ConcurrentLinkedDeque.
Note: it is important to work stack-based, as otherwise you would create every possible combination of fields before finding the solution and therefore very soon run into memory issues.
is there any other way to break this loop without using the actual break statement?
the thing is for some reason my professor doesn't like that we use break in any other place that in the switch
i am having troubles in my method adding an object into the array of objects in the next empty space in the array
this is my code: (any other way to do it?)
public void add(Employee employeeObj)throws ArrayIndexOutOfBoundsException{
try{
for(int i= 0; i<MAX; i++){
if(listEmployee[i] == null){
listEmployee[i] = employeeObj;
break;
}
}
}catch(ArrayIndexOutOfBoundsException e){
throw new ArrayIndexOutOfBoundsException("ERROR!");
}
}
the method just need to add the employeObj into the array and if the case, thows an exception.
thanks for your help
try this:
for(int i= 0; i<MAX; i++){
if(listEmployee[i] == null){
listEmployee[i] = employeeObj;
i=MAX;
}
but I see no problem with using breaks. There will always be circumstances where you want to stop processing a loop, and using a break; makes much more sense (and makes it more readable!) than setting your loop counter up to a value that would make your loop stop at the next iteration.
You can simply do i = MAX or use a boolean flag if you don't have such a trivial situation.
As a personal note forbidding the usage of break outside switch statements doesn't make any sense.
Since your method is doing nothing else in this case, you can just use return instead of break:
public void add(Employee employeeObj)throws ArrayIndexOutOfBoundsException {
try{
for (int i= 0; i<MAX; i++) {
if (listEmployee[i] == null) {
listEmployee[i] = employeeObj;
return;
}
}
} catch(ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException("ERROR!");
}
}
But in general the other answers here are more applicable. That said, I would ask your professor to explain why break shouldn't be used - IMHO alternatives are often much less readable.
i am having troubles in my method adding an object into the array of objects in the next empty space in the array
I would suggest simply finding out the length of the array and inserting the object in the next location. No need to iterate the complete length of arrray.
public void add(Employee employeeObj){
int n = listEmployee.length;
listEmployee[n] = employeeObj;
}
}
Alternatively you could do it as
int i = Arrays.asList(listEmployee).indexOf(null);
if (i >= 0) {
listEmployee[i] = employeeObj;
}
note that Arrays.asList creates a view over array, not a new List
I want to search or select specific itmes from a list/array. So on constructing the function for searching in AS3 in flash, I got stuck..Please help to solve this problem...Thanks in advance
var ar:Array = new Array();
ar=[ "bhati", "malav", "vinod"];
//Searching Function
function findIndexOfValue( array:Array, _value:* ):int {
var _length:uint = array.length;
for(var i:uint=0; i < _length; i++) {
if(array[i] == _value) {
return i;
}
else{
return -1;
}
}
}
trace(findInndexOfValue( ar, "bhati" )); // it should output 0 .
//compiler error:- 1170:Function doesn't return a value., I tried my best, but unable to solve this.
How about
function findIndexOfValue( array:Array, _value:* ):int {
var _length:uint = array.length;
for(var i:uint=0; i < _length; i++) {
if(array[i] == _value) {
return i;
}
}
return -1;
}
Why bother with this? This functionality is built right into the Array class in AS3 (And most, if not all, OOP languages).
trace( this.ar.indexOf( "bhati" ) ); //will output 0
Array#indexOf()
As to why your script doesn't work, you have to return a value. You can't have all the returns in conditionals or loops. There must be a return in within the base level of the function.
EDIT: Just took a closer look at your function and there is more wrong with it than just the return. You will never make it beyond the first item in the array because it will always return a value (thanks to the else conditional). Simply remove the else bit and move the return in it to after the for loop runs and you will have a rough duplication of how indexOf works
How can i do forward jumps like this?? Eclipse is complaining label1 is not found...
Thx
public class foo {
int xyz() {
int b = 1;
if (b == 0) {
break label1;
}
// MORE CODE HERE
label1:
return 1;
}
}
You are trying to use the equivalent of goto in Java. You can't, and for good reason. Abandon ship.
Labels are included in Java for the sole reason of choosing which loop or switch to break out of, in the case of nested loops (or switch statements). They have no other purpose, and even that single purpose is often considered dangerously close to a goto.
Labels are only applicable to loops (and blocks in general). And you are trying to mimic a goto. Don't.
You can't do that. You can only break out of an enclosing loop structure. You don't have a loop structure at all. Try this instead:
public class foo {
int xyz() {
int b = 1;
boolean skip = false;
if (b == 0) {
skip = true;
}
if (!skip) {
// MORE CODE HERE
}
return 1;
}
}
I addition to the previous answers, why not just
if (b == 0) {
return 1;
}
?