We are learning recursion in my intro to Java class, and I am having a hard time understanding how the method in the example given works. What is happening when the method is called?.
Here is the code:
public class Hanoi
private int n;
private int pegA;
private int pegB;
public Hanoi(int in_n, int in_pegA, int in_pegB)
{
n = in_n;
pegA = in_pegA;
pegB = in_pegB;
}
public void makemoves()
{
if (n==1)
System.out.format("%d ==> %d%n", pegA, pegB)
else
{
int otherPeg = 6 - pegA - pegB; // 1 + 2 + 3 =6
Hanoi firstmove = new Hanoi (n-1, pegA, otherPeg);
firstmove.makemoves();
System.out.format("%d ==> %d%n", pegA, pegB);
Hanoi secondmove = new Hanoi (n-1, otherPeg, pegB);
secondmove.makemoves();
}
}
}
Recursion is simply a method calling itself, and testing for a break condition.
This is an very easy example to illustrate the basic concept:
static void recurse( int val ) {
if ( val == 0 ) {
return; // returns from last invocation
}
System.out.println("val=" + val );
recurse( val - 1 );
return; // here the method returns to previous invocation (or initial call from main)
}
public static void main( String[] args) {
recurse( 3 );
}
The first invocation recurse( 3 ) calls the method,
after testing that 3 != 0 the method calls itself with val - 1 until the value becomes 0.
The call hierachy looks like:
recurse( 3 )
recurse( 2 )
recurse( 1 )
recurse( 0 ) // break condition
return // val == 0
return // val == 1
return // val == 2
return // val == 3
How this work is simply by traverse a binary tree in order. Check the wiki.
Related
So in this Swedish card game (I think it's called 31 or Scat), we have to calculate a deck of 3 cards. If u have 2 spades and 1 diamond your score is either the score of the 2 spades values' added together or the value of that one diamond dependent on which alternative gives you the most points. My system is that I create a method that will evaluate the string array of 3 cards like this: if u have a spade card with a 3 then as a string it's stored "S03" in the array.
In order to see which cards points can be added together I will see if the first character of their string is the same and if so.. Then the 2 other characters will be converted into a number like 03 (3)
Which is what I tried here:
int Card1Value = Integer.parseInt(String.valueOf(CardDeck[1].charAt(2))+String.valueOf(CardDeck[1].charAt(3)));
The if conditions are my attempt of determining the score.
The reason why my method is a return int is so I can get the playerdeckvalue scores determined
My code:
public class CardDecks {
public static int DeckValue( String[] CardDeck) {
int Card1Value = Integer.parseInt( String.valueOf(CardDeck[1].charAt(2))+String.valueOf(CardDeck[1].charAt(3)));
int Card2Value = Integer.parseInt( String.valueOf(CardDeck[2].charAt(2))+String.valueOf(CardDeck[2].charAt(3)));
int Card3Value = Integer.parseInt( String.valueOf(CardDeck[3].charAt(2))+String.valueOf(CardDeck[3].charAt(3)));
int AltValue1;
int AltValue2;
int AltValue3;
int CardDeckValue = 0;
if (CardDeck[0].charAt(1)==CardDeck[1].charAt(1) &&
CardDeck[0].charAt(1)==CardDeck[2].charAt(1)) {
CardDeckValue = Card1Value + Card2Value + Card3Value;
return CardDeckValue;
}
else if (CardDeck[0].charAt(1)==CardDeck[1].charAt(1)) {
AltValue1 = Card3Value;
AltValue2 = Card1Value+Card2Value;
CardDeckValue = Math.max(AltValue1, AltValue2);
return CardDeckValue;
}
else if (CardDeck[0].charAt(1)==CardDeck[2].charAt(1)) {
AltValue1 = Card2Value;
AltValue2 = Card1Value+Card3Value;
CardDeckValue = Math.max(AltValue1, AltValue2);
return CardDeckValue;
}
else if (CardDeck[1].charAt(2)==CardDeck[2].charAt(1)) {
AltValue1 = Card1Value;
AltValue2 = Card2Value+Card3Value;
CardDeckValue = Math.max(AltValue1, AltValue2);
return CardDeckValue;
}
else if (CardDeck[0].charAt(1)!=CardDeck[1].charAt(1) &&
CardDeck[0].charAt(1)!=CardDeck[2].charAt(1)) {
AltValue1 = Card1Value;
AltValue2 = Card2Value;
AltValue3 = Card3Value;
CardDeckValue= Math.max(AltValue2, Math.max(AltValue2, AltValue3));
return CardDeckValue;
}
return CardDeckValue;
}
public static void main(String[] args) {
String[] PlayerDeck = new String[]{"K01", "K03", "D10" };
System.out.println( DeckValue(PlayerDeck) );
}
}
The feedback I got was:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: 3 at
java.base/java.lang.StringLatin1.charAt(StringLatin1.java:48) at
java.base/java.lang.String.charAt(String.java:1515) at
problem3.DeckValue(problem3.java:8) at
problem3.main(problem3.java:69)
CharAt(i) actually returns the character at position i in strings. It works because strings are arrays of characters.
In programming, all arrays start at position 0.
When you type CharAt(3), it's looking for the forth character of your string.
0 -> S
1 -> 0
2 -> 3
3 -> out of bounds
I am currently learning the basics of Java from a book and I've got this code as an example of Nested Loops using Recursion. I understand everything, but the usage of return function in the end of the code. I cannot figure out how the program decide, when to stop exactly when K=4. I've tried to debug it and this continued to be like a mystery for me. Here is the code :
import java.util.Scanner;
public class nestedLoops {
public static int numberOfLoops;
public static int numberOfIterations;
public static int[] loops;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("N = ");
numberOfLoops = input.nextInt();
System.out.print("K = ");
numberOfIterations = input.nextInt();
input.close();
loops = new int[numberOfLoops];
nestedLoops(0);
}
public static void nestedLoops(int currentLoop) {
if (currentLoop == numberOfLoops) {
printLoops();
return;
}
for (int counter=1;counter<=numberOfIterations;counter++) {
loops[currentLoop] = counter;
nestedLoops(currentLoop + 1);
}
}
public static void printLoops() {
for (int i = 0; i < numberOfLoops; i++) {
System.out.printf("%d ", loops[i]);
}
System.out.println();
}
}
It would be very helpful if someone explain me how return works in this particular example in the end when numbers are "4.4" and also how it works at all in a void method, because I've been searching for explanation of that but did not succeed...
Thank you beforehand !
A return statement in a void method stops running the method and returns back to the calling code. In this example with the input:
numberOfLoops = 4
numberOfIterations = 4
Right after taking the input, you create an array based off of the input and then call the nestedLoops(0) method:
public static void nestedLoops(int currentLoop) {
if (currentLoop == numberOfLoops) {
printLoops();
return;
}
for (int counter=1;counter<=numberOfIterations;counter++) {
loops[currentLoop] = counter;
nestedLoops(currentLoop + 1);
}
}
The explanation
For starts, let's just ignore the for loop. The if statement checks to see if currentLoop == numberOfLoops and it does this every time this method is called. Right now currentLoop is 0 (the value we passed into this method when we called it) and numberOfLoops is 4 (the value we entered at the very beginning) so this is false and none of the code inside is called.
The for loop below the if statement is going to run numberOfIterations times. In our case, this loop is going to run 4 times. I will write out what happens below in sequential order:
- input is 4, 4
- nestedLoops(0) called- currentLoop = 0
- if evaluates to false
- for loop runs
- loops[0] = 1
- nestedLoops(1)
- if evaluates to false ( 1 != 4)
- for loop runs
- loops[1] = 1
- nestedLoops(2)
- if evaluates to false (2 != 4)
- for loop runs
- loops[2] = 1
- nestedLoops(3)
- if evaluates to false (3 != 4)
- for loop runs
- loops[3] = 1
- nestedLoops(4)
- if evaluates to TRUE (4 == 4)
- loops are printed (all values are 1 right now)
-returns to calling location
-Which is the for loop associated with this indention.
-For loop increments, and then sets loops[3] = 2.
- then this loop finishes
- then this loop finishes
etc. etc.
The return in a void method just means "okay, stop what you're doing and go back to who/whatever called this and move on" In this case its jumping back to previous for loop to keep working.
The for loop inside the nestedLoops method is calling itself numberOfIterations times. So it goes 0, then makes numberOfIterations calls. So if you entered 4 you would see 4 calls with currentLoop=1 then 16 calls with currentLoop=2 and so on....
When all else fails write some code to debug your code. I am a visual person myself so making some output helps when the debugger doing it for me.
public static HashMap<Integer, Integer> map = new HashMap();
public static void main(String[] args) {
....
System.out.println(map);
}
public static void nestedLoops(int currentLoop) {
if(map.containsKey(currentLoop)) {
map.put(currentLoop, map.get(currentLoop)+1);
} else {
map.put(currentLoop, 1);
}
...
}
I was recently in a job interview for a position as Java Developer. I was given a task: To think about a good way to represent an electric circuit (such as the one in the figure below) in Java.
A circuit is a combination of logic gates XOR, AND, OR etc.. Each gate has two input ports and an output port. Each output is connected to an input of another gate, which goes all the way to a higher gate (as in the picture). Make the system simple, no cycles are allowed (although real life circuits can have them).
I was asked to think about a good way to represent this model in Java, using the following guidelines:
I am given a circuit and a list of values which should be provided to its inputs.
I need to create a model to represent the circuit in Java, i.e., I need to define classes and an API that could be used to represent the circuit.
According to the input values and how the gates are connected, I need to calculate the output that the represented circuit would produce.
I need to think about a way to represent the board, use abstract classes or interfaces, and show understanding of the model (and if needed to use pattern design).
I chose to design the system as a tree and the interviewer told me it was a good choice. Then I build those classes:
Node
public class gate_node {
gate_node right_c,left_c;
Oprtator op;
int value;
int right_v,left_v;
public gate_node(gate_node right,gate_node left,Oprtator op){
this.left_c=left;
this.right_c=right;
this.op=op;
right_v=left_v=0;
}
}
Tree
public class tree {
gate_node head;
tree(gate_node head) {
this.head = head;
}
void go_right() {
head = head.right_c;
}
void go_left() {
head = head.left_c;
}
static int arr[] = { 0, 0, 1, 0 };
static int counter=0;
static int compute(gate_node head) {
if ((head.left_c == null) && (head.right_c == null))
{
int ret=(head.op.calc(arr[counter], arr[counter+1]));
counter++;
counter++;
return ret;
}
return (head.op.calc(compute(head.left_c), compute(head.right_c)));
}
public static void main(String[] args) {
tree t = new tree(new gate_node(null, null, new and()));
t.head.left_c = new gate_node(null, null, new and());
t.head.right_c = new gate_node(null, null, new or());
System.out.println(tree.compute(t.head));
}
}
Oprtator class:
public abstract class Oprtator {
abstract int calc(int x, int y);
}
OR gate:
public class or extends Oprtator {
public int calc(int x, int y){
return (x|y);
}
}
In the above code, I implemented the board as a tree with its a current head (which can go down to the left/right children). Every node has 2 children (also node type), 2 entries (0/1), a value and an operator (abstract class, could be extended by OR/AND..).
I used a counter and an array to insert the values to the appropriate leafs of the tree (as mentioned in the code).
It works but still I got a feeling that my interviewer wanted something more. Is my code is correct? Does anyone have a better way of represent this electrical board and how to give a good output (in terms of complexity or using better connection from one class to another, design patterns, something else?)
It's not a "perfect" answer, but you can solve this using a few classes to hold the logical connection/evaluation and then recursively evaluate the circuit.
Create a base class LogicalNode and give it a list of inputs to manage. Give it a base class function to evaluate all the inputs and return an output. This gets overridden in derived classes. Each type of node (INPUT, NOT, AND, OR) gets a derived class with a special "ComputOutput" overridden version. If you compute the output at the output node, it should recurse up the tree, computing all inputs of inputs of inputs, etc., till it reaches the "INPUT" nodes, which are fixed/logical inputs to the system.
You can create new types fairly quickly (see code). Not a lot of comments here, but it should be somewhat self explanatory.
Something like this (in C#):
public class LogicalNode
{
private List<LogicalNode> _inputs = new List<LogicalNode>();
private String _name = "Not Set";
public override string ToString()
{
return String.Format("Node {0}", _name);
}
public void Reset()
{
_inputs.Clear();
}
public void SetName(String name)
{
_name = name;
}
protected List<LogicalNode> GetInputs()
{
return _inputs;
}
public void AddInput(LogicalNode node)
{
_inputs.Add(node);
}
protected virtual bool ComputeOutputInternal()
{
return false;
}
public bool ComputeOutput()
{
// Console.WriteLine("Computing output on {0}.", _name);
return ComputeOutputInternal();
}
}
public class LogicalInput : LogicalNode
{
private bool _state = true;
public void SetState(bool state)
{
_state = state;
}
public bool GetState() { return _state; }
protected override bool ComputeOutputInternal()
{
return _state;
}
}
public class LogicalAND : LogicalNode
{
protected override bool ComputeOutputInternal()
{
List<LogicalNode> inputs = GetInputs();
bool result = true;
for (Int32 idx = 0; idx < inputs.Count && result; idx++)
{
result = result && inputs[idx].ComputeOutput();
}
return result;
}
}
public class LogicalOR : LogicalNode
{
protected override bool ComputeOutputInternal()
{
List<LogicalNode> inputs = GetInputs();
bool result = false;
for (Int32 idx = 0; idx < inputs.Count; idx++)
{
result = inputs[idx].ComputeOutput();
if (result)
// If we get one true, that is enough.
break;
}
return result;
}
}
public class LogicalNOT : LogicalNode
{
protected override bool ComputeOutputInternal()
{
List<LogicalNode> inputs = GetInputs();
if (inputs.Count > 0)
{ // NOTE: This is not an optimal design for
// handling distinct different kinds of circuits.
//
// It it demonstrative only!!!!
return !inputs[0].ComputeOutput();
}
return false;
}
And then to (quickly) test it:
static void Main(string[] args)
{
// The test circuit
// !((A&&B) || C)
// A B C Out
// 1 1 1 0
// 1 1 0 0
// 1 0 1 0
// 1 0 0 1
// 0 1 1 0
// 0 1 0 1
// 0 0 1 0
// 0 0 0 1
//
//
//
/* ------- -------
* A - | | | |
* | AND |-----| | -------
* B - | (D) | | | | |
* ------- | OR |----| NOT |----
* | (E) | | (F) |
* C --------------| | | |
* ------- -------
*/
LogicalInput A = new LogicalInput();
LogicalInput B = new LogicalInput();
LogicalInput C = new LogicalInput();
LogicalAND D = new LogicalAND();
LogicalOR E = new LogicalOR();
LogicalNOT F = new LogicalNOT();
A.SetName("A");
B.SetName("B");
C.SetName("C");
D.SetName("D");
E.SetName("E");
F.SetName("F");
D.AddInput(A);
D.AddInput(B);
E.AddInput(D);
E.AddInput(C);
F.AddInput(E);
// Truth Table
bool[] states = new bool[]{ true, false };
for(int idxA = 0; idxA < 2; idxA++)
{
for(int idxB = 0; idxB < 2; idxB++)
{
for(int idxC = 0; idxC < 2; idxC++)
{
A.SetState(states[idxA]);
B.SetState(states[idxB]);
C.SetState(states[idxC]);
bool result = F.ComputeOutput();
Console.WriteLine("A = {0}, B = {1}, C = {2}, Output = {3}",
A.GetState(), B.GetState(), C.GetState(), result.ToString());
}
}
}
}
}
With output:
A = True, B = True, C = True, Output = False
A = True, B = True, C = False, Output = False
A = True, B = False, C = True, Output = False
A = True, B = False, C = False, Output = True
A = False, B = True, C = True, Output = False
A = False, B = True, C = False, Output = True
A = False, B = False, C = True, Output = False
A = False, B = False, C = False, Output = True
Was this helpful?
While I obviously can't say exactly what the interviewer was looking for, if I were interviewing you I would probably press you to make your compute method a non-static member of your gate_node class. This way, your networks do not have to be "balanced" (they can be deeper, have more inputs) on one side or the other.
Put another way, looking at your compute code, I do not believe it would work for general circuits.
Perhaps something like the following (in gate_node):
int compute() {
/* The following use of a static sInputCounter assumes that the static/global
* input array is ordered from left to right, irrespective of "depth". */
final int left = (null != left_c ? left_c.compute() : sInput[sInputCounter++]);
final int right = (null != right_c ? right_c.compute() : sInput[sInputCounter++]);
return op.calc(left, right);
}
This way, the "tree" can just be represented by the head/root gate_node (although you still probably want a class like your tree class -- I might call it "network" just to avoid confusion, with static methods for constructing the tree, setting up the inputs, etc.) and you trigger the network evaluation by calling head.compute().
Of course, you are still left with the non-trivial problem of constructing a network from some external specification. I imagine that another issue for the interviewer could have been that this aspect was not well-specified in your solution. (Nor in mine here either, I'm sorry.)
I have a Term class to define a polynomial:
public class Term
{
final private int coef;
final private int expo;
private static Term zero, unit;
static
{
try
{
zero = new Term(0, 0); // the number zero
unit = new Term(1, 0); // the number one
}
catch (Exception e)
{
// constructor will not throw an exception here anyway
}
}
/**
*
* #param c
* The coefficient of the new term
* #param e
* The exponent of the new term (must be non-negative)
* #throws NegativeExponent
*/
public Term(int c, int e) throws NegativeExponent
{
if (e < 0)
throw new NegativeExponent();
coef = c;
expo = (coef == 0) ? 1 : e;
}
final public static Term Zero = zero;
final public static Term Unit = unit;
public boolean isConstant()
{
boolean isConst = false;
if (this.expo == 0)
{
isConst = true;
}
return isConst;
}
}
And I have the JUnit test as follows:
/*
* const1 isConstant(zero) => true (0,0)
* const2 isConstant(unit) => true (1,0)
* const3 isConstant(0,5) => true
* const4 isConstant(5,1) => false
*/
#Test
public void const1() throws TError { assertTrue(Term.Zero.isConstant()); }
#Test
public void const2() throws TError { assertTrue(Term.Unit.isConstant()); }
#Test
public void const3() throws TError { assertTrue(new Term(0,5).isConstant()); }
#Test
public void const4() throws TError { assertFalse(new Term(5,1).isConstant()); }
Tests 2 and 4 pass as they should, but Tests 1 and 3 come up as failures and I cannot work out why, "Zero" is defining the polynomial as (0,0) and the other is defining it as (0,5). So by my thinking, the 1st one should give a green tick and the 3rd test should give a red cross as it has 5 as the exponent.
Any ideas?
Please review your constructor:
public Term(int c, int e) throws NegativeExponent{
if (e < 0) throw new NegativeExponent();
coef = c;
expo = (coef == 0) ? 1 : e;
}
When coef == 0, then exp is assigned with 1.
This makes zero as (0,1) not (0,0). this is the reason for test outcome as below:
const1 -> false as expo = 1-->failure as expecting true
const2 -> true as expo = 0 -->success as expecting true
const3 -> false as expo = 5.-->failure as expecting true
const4 -> false as expo = 1.-->success as expecting false
EDIT: To reverse fix your code to make the test cases pass, I think you may update your constructor as below:
public Term(int c, int e) throws NegativeExponent{
if (e < 0) throw new NegativeExponent();
coef = c;
expo = (c == 0 && e != 0) ? 0 : e;
}
Here, I have updated the constructor to set expo as 0, if coef is 0 as any expo for coef 0 is immaterial.
Yogendra covered why your first test fails. Your const3() fails (for me at least) because new Term(0, 5) has a expo of 5, which gets replaced with 1 b/c of the coef, but 1 is still not 0 so new Term(0, 5) is NOT constant.
Not that you asked, but I'll also give you some general Java pointers for the future...
1) Use all caps for static constants
public static final Term ZERO = new Term(0, 0);
public static final Term UNIT = new Term(1, 0);
this is just a convention that the Java community expects.
2) Give your test cases meaningful names. One powerful use of test cases is that they can double as documentation of your assumptions at the time. Rather than const1() which tells a fellow developer nothing, use a descriptive name like zeroShouldBeAConstant(). This tells the next person who looks at your code that Zero should be considered a constant in this system.
3) Whenever you are returning a boolean variable, consider just returning the statement. Compare the function below to yours and tell me which one is more readable:
public boolean isConstant()
{
return expo == 0;
}
It is less code and hopefully easier to read.
Good luck!
I just begin to learn java (today),
To exercise me, I would like to translate the following "8 Queens" algorithm written in python into Java :
BOARD_SIZE = 8
def under_attack(col, queens):
left = right = col
for r, c in reversed(queens):
left, right = left-1, right+1
if c in (left, col, right):
return True
return False
def solve(n):
if n == 0: return [[]]
print n
smaller_solutions = solve(n-1)
return [solution+[(n,i+1)] for i in range(BOARD_SIZE) for solution in smaller_solutions if not under_attack(i+1, solution)]
sols = solve(BOARD_SIZE)
for answer in sols:
print answer
For translation, I want to use exactly the same algorithm : recursive and use of "lists of lists of tuple" like in python (I know I should think "java", but for now, it's just for fun)
I wrote this :
import java.util.ArrayList;
class Queens {
public static boolean under_attack(int col, ArrayList<Integer[]> queens) {
int left = col, right = col;
for(int i=queens.size()-1;i>=0;i--) {
int r = queens.get(i)[0];
int c = queens.get(i)[1];
left--;
right++;
if ( c==left || c==col || c==right) {
return true;
}
}
return false;
}
public static ArrayList<ArrayList<Integer[]>> solve(int n){
ArrayList<ArrayList<Integer[]>> new_solutions = new ArrayList<ArrayList<Integer[]>>();
if ( n==0 ) {
return new_solutions;
}
ArrayList<ArrayList<Integer[]>> smaller_solutions = solve(n-1);
for (int i=0;i<8;i++) {
for (ArrayList<Integer[]> solution : smaller_solutions) {
if ( ! under_attack(i+1,solution) ) {
ArrayList<Integer[]> bigger_solution = (ArrayList<Integer[]>) solution.clone();
Integer [] tuple = new Integer [2];
tuple[0] = n;
tuple[1] = i+1;
bigger_solution.add(tuple);
new_solutions.add(bigger_solution);
}
}
}
return new_solutions;
}
public static void main(String[] args) {
System.out.println("Résolution du problème des 8 reines");
ArrayList<ArrayList<Integer[]>> solutions;
solutions = solve(8);
System.out.format("Nb solutions : %d%n",solutions.size());
for (ArrayList<Integer[]> solution : solutions) {
System.out.print("(");
for(Integer[] i:solution) {
System.out.format("[%d,%d],",i[0],i[1]);
}
System.out.println(")");
System.out.println("==============================");
}
}
}
But this does not work : no answers is found
Do you have an idea why ?
The correction needed to your code to run identicaly to the python program is the following. At the begining of the solve() function instead of:
if ( n==0 ) {
return new_solutions;
}
you should write:
if ( n==0 ) {
ArrayList<Integer[]> empty = new ArrayList<Integer[]>();
new_solutions.add(empty);
return new_solutions;
}
The reason is that the artifact [[]] in python is not an empty list, right? It is a list containing as it's only element the empty list. This is exactly the correction in the java code! Otherwise the recursion doesn't work and the under_attack() function is never called (as you can verify adding a diagnostic message at its first line)
Happy coding...and java learning