I am trying to implement code to convert decimal to binary with a certain precision, for that I use stack and linked list to add the non decimal and decimal parts calculated. I then use Stringbuilder to pop/poll element one by one to ge the final binary number. SOURCE : http://www.geeksforgeeks.org/convert-decimal-fraction-binary-number/
When I push the elements onto stack/list I see they are being pushed(Using o/p stmts for that). For some reason I dont see them when popping out the elements.
Here is my code
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class BinaryToDecimal {
public String toBinary(float n, int p){
int non_dec = (int) Math.floor(n);
Stack<Integer> s_non_dec = new Stack<>();
LinkedList<Integer> q_dec = new LinkedList<>();
float dec = n - non_dec;
int quotient = 1;
while(quotient > 0){
quotient = non_dec/2;
int remainder = non_dec%2;
System.out.println("quotient"+quotient+"non_dec"+non_dec+"remainder"+remainder);
s_non_dec.push(remainder);
non_dec = quotient;
}
while(p>0){
System.out.println("before dec"+dec);
dec = dec*2;
System.out.println("after dec"+dec);
if(dec >=1){
System.out.println("add 1");
q_dec.add(1);
dec = dec - 1;
}
else{
System.out.println("add 0");
q_dec.add(0);
}
p--;
}
StringBuilder sb = new StringBuilder();
for(int i=0;i<s_non_dec.size();i++){
System.out.println("pop"+s_non_dec.peek());
sb.append(s_non_dec.pop());
}
sb.append('.');
for(int i=0;i<q_dec.size();i++){
System.out.println("poll"+q_dec.peek());
sb.append(q_dec.poll());
}
return sb.toString();
}
public static void main (String args[]){
BinaryToDecimal btd = new BinaryToDecimal();
System.out.println(btd.toBinary(2.47f, 5));
}
}
My output :
quotient1non_dec2remainder0
quotient0non_dec1remainder1
before dec0.47000003
after dec0.94000006
add 0
before dec0.94000006
after dec1.8800001
add 1
before dec0.8800001
after dec1.7600002
add 1
before dec0.7600002
after dec1.5200005
add 1
before dec0.52000046
after dec1.0400009
add 1
pop1
poll0
poll1
poll1
1.011
as seen above, even tough I push 1 and 0 into my stack, my output has only 1 for the non decimal part instead of 1 and 0! The same happens for the decimal part!
Ive been looking at this code for hours, any help is appreciated!
Error is with your for loop.
for(int i=0;i<s_non_dec.size();i++){
System.out.println("pop"+s_non_dec.peek());
sb.append(s_non_dec.pop());
}
Here you are looping on stack size s_non_dec.size, which will keep on decreasing after every pop operation and "i" will keep on increasing after every iteration. You can better check if stack is empty or not. Use
while(!s_non_dec.isEmpty()) {
System.out.println("pop"+s_non_dec.peek());
sb.append(s_non_dec.pop());
}
Related
I have tried to find the time complexity for the below code but I am not sure whether it is right or not. can anyone help me on finding the time complexity for the below code. the code language is JAVA.
code:
// importing the necessary header files for the program
// header files are imported using the keyword import
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
//creating a class called "Partone". class can be created using the keyword class
public class Partone
{
public static void main(String[] args) throws IOException
{
// opening a file named "hikernet1"
File inputFile = new File("hikernet1.txt");
int maxTransmission = 0; //declaring maxTransmission as Integer data type and setting as 0
//reading the content of the file
Scanner reader = new Scanner(inputFile);
// inputCoordinatedAndTransmissionRange
String[] iCATR = reader.useDelimiter("\\A").next().replaceAll("\n", ",").replace("\r", "").split(",");
for (int i = 0; i < Integer.parseInt(iCATR[0]); i++)
{
int transmissions = 0; //declaring transmissions as integer data type and setting is as 0
String[] thisHiker = iCATR[i+1].split(" ");
int transMissionRange = Integer.parseInt(thisHiker[2]);
for (int j = 0; j < Integer.parseInt(iCATR[0]); j++)
{
int distance = (int) Math.sqrt(
Math.pow(Integer.parseInt(thisHiker[0])-Integer.parseInt(iCATR[j+1].split(" ")[0]), 2) + //x2-x1
Math.pow(Integer.parseInt(thisHiker[1])-Integer.parseInt(iCATR[j+1].split(" ")[1]), 2)); //y2-y1
if (distance<=transMissionRange)
{
transmissions++;
}
}
if (transmissions>maxTransmission) //checking the condition
{
maxTransmission = transmissions;
}
}
System.out.println(" The Maximum Transmission: "+maxTransmission);
//the outpit will be displayed in the hikernet1out file
FileWriter fw = new FileWriter("hikernet1out.txt"); //hikernet1out is the name of the output file
fw.write(""+maxTransmission);
fw.close(); //closing the file
reader.close(); //closing all the files
}
} //end of the program
any help would be appreciated much . thanks in advance.
Integer.parseInt(iCATR[0]); retruning any value let consider n.
The inner loop is running n times for every iteration of the outer loop.
The total number of nested loop itration = total number of iteration of outer loop . total number of iteration of inner loop = n * n = n^2
For each iteration nested loop doing O(1) operation.
Total time complexity = O(n^2)*O(1) = O(n^2).
Problem Link: https://www.spoj.com/problems/PPATH/
Brief explanation of the problem,
1) Construct a graph with prime numbers between 1000 and 9999.
2) Add an undirected edge between two numbers 'a' and 'b', if they differ only by one digit.
EX: 1033 and 1733 differ only by one digit.
3) In that graph we need to find the length of the shortest path from the given source to the given destination.
I have solved the above problem by constructing a graph using the prime number between 1000 and 9999, by connecting numbers that differ only by one digit. EX: 1033 and 1733 differ only by one digit.
I have used DFS along with memorisation to find the shortest path.
For some input i am getting wrong answer, 1 greater than the actual value, since there are 1000 nodes i can't able to figure out the issue. It will be so helpful if someone help me to figure out the issue.
I know this problem can be solved by BFS, but i need to know what's wrong with this problem.
test cases when the below program prints wrong answer
1
7573 9973
Actual answer : 4
My code output : 5
(I have found the actual answer by submitting a BFS approach to the problem and it got Accepted in SPOJ).
import java.util.*;
import java.lang.*;
import java.io.*;
class FireEscapeRoutes_FIRESC {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws Exception{
int t = 1;
while (t--!=0){
int source = 7573;
int destination = 9973;
List<Integer> fourDigitPrimeNos = new ArrayList<>();
for(int i=1001;i<=9999;i++){
if(isPrime(i)){
fourDigitPrimeNos.add(i);
//System.out.println(i);
}
}
Graph graph = new Graph(fourDigitPrimeNos.size());
/*
If two number 'a' and 'b' differ only by one digit then an edge is added.
*/
for (int i=0;i<fourDigitPrimeNos.size();i++){
for (int j=i+1;j<fourDigitPrimeNos.size();j++){
if(isSingleDistnace(fourDigitPrimeNos.get(i),fourDigitPrimeNos.get(j))){
graph.add(fourDigitPrimeNos.get(i),fourDigitPrimeNos.get(j));
}
}
}
//System.out.println(graph.graph);
Long minPath = graph.getShortestPath(source,destination);
if(minPath!=Long.MAX_VALUE){
System.out.println(minPath);
}else{
System.out.println("Impossible");
}
}
}
static boolean isSingleDistnace(int a, int b){
String as = a+"";
String bs = b+"";
int ds = 0;
for (int i=0;i<as.length();i++){
if(!(as.charAt(i)==bs.charAt(i))){
if(ds>=1){
return false;
}
ds++;
}
}
if(ds==0){
return false;
}
return true;
}
static boolean isPrime(int n){
for (int i=2;i<=Math.sqrt(n);i++){
if(n%i==0){
return false;
}
}
return true;
}
}
class Graph{
int noOfVertices;
HashMap<Integer,List<Integer>> graph;
Graph(int v){
noOfVertices = v;
graph = new HashMap<Integer,List<Integer>>();
}
void add(int u,int v){
if (!graph.containsKey(u)){
graph.put(u,new ArrayList<>());
}
if(!graph.containsKey(v)){
graph.put(v,new ArrayList<>());
}
graph.get(u).add(v);
graph.get(v).add(u);
}
Long getShortestPath(int start, int dest){
HashMap<Integer,Long> visitedVsMinCost = new HashMap<>();
Long min = Long.MAX_VALUE;
min = getShortestPathUtil(start,dest,visitedVsMinCost);
return min-1;
}
Long getShortestPathUtil(Integer start,Integer dest,HashMap<Integer,Long> visitedVsMinCost){
if(start.equals(dest)){
return 1l;
}
visitedVsMinCost.put(start, Long.MAX_VALUE);
List<Integer> frnds = graph.get(start);
Long min = Long.MAX_VALUE;
for (Integer iThFrind:frnds){
if(!visitedVsMinCost.containsKey(iThFrind)){
Long shortestPathUtil = getShortestPathUtil(iThFrind, dest, visitedVsMinCost);
//System.out.println(shortestPathUtil + " min " + min);
min = Math.min(min, shortestPathUtil);
}else {
if(!visitedVsMinCost.get(iThFrind).equals(Long.MAX_VALUE)) {
min = Math.min(min, visitedVsMinCost.get(iThFrind)+1);
}
}
}
visitedVsMinCost.put(start,min);
//System.out.println(min);
if (min.equals(Long.MAX_VALUE)){
return min;
}
return min+1;
}
}
NOTE: This below Part is to explain why my code works on the situation mentioned by #c0der. Since i can't able to comment more characters i am editting this question. To understand approach you can use this below part.
I can understand it is difficult to debug the code, so i try to explain my approach using the graph mentioned by #coder answer and
above code work fine in the scenario you mentioned.
Start = 1 and destination= 5, shortest path = 2 (1->4->5)
1) if DFS traverses through `1->2->3->4->5' and reached the destination '5' it return '1' to the '4'th node.
2) now the '4'th node memorise the returned value '1'. (This means between 4 and 5, there is one node, including destination, excluding the source 4).
2.1) Then it returns '2'(1+1) to the '3'rd node. and '3'rd node memorise the value '2'. (This means between 3rd node and destination(5) node , there is 2 node, in the shortest path. including destination, excluding source 3
3) similiarly call will go back to '1'.
4) then '1'st node, calls '4'th node and see it is visited before, so it takes the memorized value of '4' th node which is '1' and it returns '2' to '1'.
Debugging of the code posted is a long task.
However DFS is not the right tool for the job.
To visualize why DFS is not a good tool to find the shortest path consider the following simple graph:
If DSF happens to start by traversing nodes 1->2->3->4->5 the shortest path 1->4->5
will not be traversed because 4 is marked as visited.
This may be the reason why DFS along with memorisation is unable to find the shortest path.
Edit:
The following is a modified version of your code: it returns the actual shortest path found, if any.
This may help in debugging.
If finds the shortest path by performing DFS to traverse all possible paths and keeping the shortest one.
It is not optimized in the sense that if there are loops in the graph it may recalculate a path that has already been calculated before. You may want to add memorization of calculated pathes to make it more efficient.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
class FireEscapeRoutes_FIRESC {
public static void main(String[] args) throws Exception{
List<Integer> fourDigitPrimeNos = new ArrayList<>();
for(int i=1001; i<=9999; i++){
if(isPrime(i)){
fourDigitPrimeNos.add(i);
}
}
Graph graph = new Graph();
/*
If two number 'a' and 'b' differ only by one digit then an edge is added.
*/
for (int i=0;i<fourDigitPrimeNos.size();i++){
for (int j=i+1;j<fourDigitPrimeNos.size();j++){
if(isSingleDistnace(fourDigitPrimeNos.get(i),fourDigitPrimeNos.get(j))){
graph.add(fourDigitPrimeNos.get(i),fourDigitPrimeNos.get(j));
}
}
}
int source = 1033;
int destination = 8179; //expected 6 : 1033 1733 3733 3739 3779 8779 8179
/* more test cases
int source = 7573;
int destination = 9973; //expected 5
int source = 1373;
int destination = 8017; //expected 7
int source = 1033;
int destination = 1033; //expected 1
*/
List<Integer> shortestPath = graph.getShortestPath(source,destination);
if(shortestPath != null){
System.out.println("\nPath Found :"+ shortestPath);
System.out.println("Path length: "+shortestPath.size());
}else{
System.out.println("Impossible");
}
}
static boolean isSingleDistnace(int a, int b){
String as = a+"";
String bs = b+"";
int ds = 0;
for (int i=0;i<as.length();i++){
if(!(as.charAt(i)==bs.charAt(i))){
if(ds>=1)
return false;
ds++;
}
}
if(ds==0) return false;
return true;
}
static boolean isPrime(int n){
if (n <= 1) return false; //make sure it is positive
for (int i=2;i<=Math.sqrt(n);i++){
if(n%i==0)
return false;
}
return true;
}
}
class Graph{
private final HashMap<Integer,List<Integer>> graph;
//measure time and print out some progress indication
private static long startTime, printime;
private static long HEART_BEAT = 15000;
Graph(){
graph = new HashMap<>();
}
void add(int u,int v){
if (!graph.containsKey(u)){
graph.put(u,new ArrayList<>());
}
if(!graph.containsKey(v)){
graph.put(v,new ArrayList<>());
}
graph.get(u).add(v);
graph.get(v).add(u);
}
List<Integer> getShortestPath(int start, int dest){
System.out.print("Working ");
startTime = System.currentTimeMillis();
List<Integer> path = new ArrayList<>();
path = getShortestPathUtil(start,dest, Integer.MAX_VALUE, path);
System.out.println("\n run time in minutes " + (double) (System.currentTimeMillis() - startTime) /60000);
return path;
}
List<Integer> getShortestPathUtil(int start,int dest,int minLengthFound, List<Integer> path){
if(System.currentTimeMillis() - printime >= HEART_BEAT ){
System.out.print(".");
printime = System.currentTimeMillis();
}
if(path.contains(start)) return null; //prevent loops
path.add(start);
if(start == dest) return path;
//stop traverse if path is longer than the shortest one found earlier
if(minLengthFound != Integer.MAX_VALUE && path.size() >= minLengthFound) return null;
List <Integer> keepShortestPathFound = null;
for (int neighbor : graph.get(start)){
if(path.contains(neighbor)) {
continue;
}
List<Integer> shortestPathFromNeighbor = getShortestPathUtil(neighbor, dest, minLengthFound, new ArrayList<>(path));
if(shortestPathFromNeighbor != null && shortestPathFromNeighbor.contains(dest) &&
shortestPathFromNeighbor.size() < minLengthFound){
keepShortestPathFound = shortestPathFromNeighbor;
minLengthFound = shortestPathFromNeighbor.size();
}
}
return keepShortestPathFound;
}
}
Perhaps i wasn't clear enough. I apologize. I tried condensing and adding images in this edit to make it more clear.
50 Seed Value, 1200 RNG Value.
60 Seed Value, 1200 RNG Value.
In the examples above (for clarity instead of writing it all out), you can see the outputs you get for 50 vs 60. It's not the distinct values I'm concerned. It's the display now. As you can see, the number gets bigger since I put in a new seed value. I want it to display what the 50 seed value is, but have the properties of whatever seed value I put in.
If I put in for example 60, I want to get:
H1 T1 H1 T1 HHH3 TTTTT5 H1 T1 HHHH4 T1 HH2 T1 H1 T1 H1 T1 H1 T1 H1 TTT3 H1 TTT3 H1 TTTT4 H1 T1 HHH3 TT2 H1 T... (just like with the 50 seed value).
BUT it would get 35 distinct values instead of the 30. Let me know if I can be clearer I apologize for being so confusing.
import java.util.Scanner;
import java.util.Random;
public class CoinFlipAnalyzer{
private static final Scanner
stdIn = new Scanner(System.in);
public static void main (String[] args){
// Integer Values:
int totalNumberOfRuns = 0;
int run = 1;
// Boolean Values:
boolean theCoin;
boolean tempVal = false;
// Gathering the Users Input:
System.out.println("Welcome to the coin flip analyzer.\n"
+ "How many flips?");
int numberOfFlips = stdIn.nextInt();
System.out.println("What do you want to seed the random number generator with?");
int rngSeed = stdIn.nextInt();
Random rng = new Random(rngSeed); // Initiates the Random Number Generator.
System.out.println();
// Loop and Array to Decide Whether the Value is Heads or Tail.
long[] runLength = new long[numberOfFlips];
for (int i = 0; i < numberOfFlips; i++) {
theCoin = rng.nextBoolean(); // As requested, I used the nextBoolean expression.
if (theCoin != tempVal) {
if (i > 0) {
System.out.print(run + " ");
}
runLength[run - 1]++;
totalNumberOfRuns++;
run = 1;
}
else {
run++;
}
if (theCoin) {
System.out.print("H");
tempVal = true;
}
else {
System.out.print("T");
tempVal = false;
}
}
System.out.print("...");
System.out.println();
System.out.println("There were a total of " + totalNumberOfRuns +
" distinct runs in the simulation.\nTheir breakdown follows:");
System.out.println();
I think I understand the requirement. In essence, there is some desired width, and if the number of outputs exceeds the width, then print using an ellipses.
There is the StringUtils from Apache Commons that has an 'Abbreviate' method.
public static String abbreviate(String str,
int maxWidth)
Abbreviates a String using ellipses. This will turn "Now is the time for all good men" into "Now is the time for..."
To use this (or the other suggestion below), I would remove the immediate output that is being generated in the run, and instead build a String. One could build a char[] as well, but here we will go with a String (or a StringBuilder). There is another advantage to so doing -- it is generally a good practice to separate some of the logic from the output. Plus it would be more testable.
So, if one can use the StringUtils.abbreviate(...), then take the result from the doFlips(...) and pass it to the method, and the result will be done.
/*
* moved the flipping into a method; allow it to build the
* results rather than immediately outputting them
*/
private static StringBuilder doFlips(int numberOfFlips, Random rng)
{
long[] runLength = new long[numberOfFlips];
boolean theCoin;
boolean tempVal = false;
int run = 1;
int totalNumberOfRuns = 0;
// Here we will collect the output; use better name in production
StringBuilder sb = new StringBuilder();
for (int i = 0; i < numberOfFlips; i++) {
theCoin = rng.nextBoolean(); // As requested, I used the nextBoolean
// expression.
if (theCoin != tempVal) {
if (i > 0) {
sb.append(run);
sb.append(" ");
}
runLength[run - 1]++;
totalNumberOfRuns++;
run = 1;
}
else {
run++;
}
if (theCoin) {
sb.append("H");
tempVal = true;
}
else {
sb.append("T");
tempVal = false;
}
}
return sb;
}
If one cannot use the library, it is easy enough to write a chop method:
/**
* Chop the input StringBuilder and give "..." at
* maxOutput.
*
* NOTE: no error checking
*/
private static String ourChop(StringBuilder sb, int maxOutput)
{
if (sb.length() <= maxOutput) {
return sb.toString();
}
// we chop everything past maxOutput - 3
sb.setLength(maxOutput - 3);
sb.append("...");
return sb.toString();
}
So, we can then do the following:
public static void main(String[] args)
{
int seed = 1200;
int maxOutput = 25;
// 50 flips, 25 length max, including ... if needed
StringBuilder res = doFlips(50, new Random(seed));
System.out.println(ourChop(res, maxOutput));
res = doFlips(60, new Random(seed));
System.out.println(ourChop(res, maxOutput));
And we get this output (at 25):
H1 T1 H1 T1 HHH3 TTTTT...
H1 T1 H1 T1 HHH3 TTTTT...
Now, if the goal is to align to the max output of some given run, then one would need to collect all of the runs (50, 60, etc.), and then find the particular value (say the shortest of the outputs; note that in theory in a truly random setting, 60 could have a shorter output than 50, but not when using the same seed). One could then use that determined value to chop to a given output length.
If I have misunderstood the approach, I apologize.
I am working on a problem from Cracking the Coding Interview, problem 9.6 page 110.
Here is the problem:
Implement an algorithm to print all valid (e.g., properly opened and closed combinations of n-pairs of parentheses. Examples
b(1) - "()"
b(2) - "(()), ()()"
b(3) - "((())), (()()), (())(), ()(()), ()()()"
I am trying to use the bottom up recursion approach that the author discusses on page 107 - "We start with knowing how to solve the problem for a simple case, like a list with only one element, and figure out how to solve the problem for two elements, then for three elements, and so on. The key here is to think about how you can build the solution for one case off the previous case"
Here is the code I have so far
static void print(int n) {
print(n, new HashSet<String>(), "", "");
}
static void print(int n, Set<String> combs, String start, String end) {
if(n == 0) {
if(!combs.contains(start + end)) {
System.out.print(start + end);
combs.add(start + end);
}
} else {
print(n-1, combs, "(" + start, end +")");
System.out.print(", ");
print(n-1, combs, start, end + "()");
System.out.print(", ");
print(n-1, combs, "()" + start, end);
}
}
To get this code, I worked from the first case to the second case. I saw that b(2) = "(b(1)), b(1),b(1)"
This code does work for the first two cases. I am really struggling with the third case though. Can someone give me a hint(not the whole answer, could turn to the back of the book for that), about how to go from case 2 to case 3, or in other words using case 2 to get to case 3? Like how would you go from (()), ()() to ((())), (()()), (())(), ()(()), ()()()? Would you abandon the pattern you saw from b(1) to b(2) because it doesn't work for b(2) to b(3)?
We can generate from b(n) to b(n + 1) by using this recursive formula:
(b(n - x))b(x) with 0 <= x <= n
So, you can have all of your combinations by iterating through all x.
Code:
public static ArrayList<String> cal(int num){
if(num == 0){
ArrayList<String> list = new ArrayList();
list.add("");
return list;
}else{
ArrayList<String>result = new ArrayList();
for(int i = 0; i <= num - 1; i++){
ArrayList<String> a = cal(i);
ArrayList<String> b = cal(num - 1 - i);
for(String x : a){
for(String y : b){
result.add("(" + x + ")" + y);
}
}
}
return result;
}
}
Input: 3
Output: ()()(), ()(()), (())(), (()()), ((()))
Input: 4
Output: ()()()(), ()()(()), ()(())(), ()(()()), ()((())), (())()(), (())(()), (()())(), ((()))(), (()()()), (()(())), ((())()), ((()())), (((())))
Thanks Khanna111 for pointing out the mistake I made in my original answer, which was incomplete and under-counted the string patterns. As a result, I have updated my answer accordingly.
Please consider giving credit to Pham Trung for his answer with the correct recursive formula. My answer is essentially the same as his, with only a slight difference in the way I formulate the construction of patterns from smaller sub-problems (as I find it easier to explain the details in my approach).
========================================================================
Update Solution
For any valid pattern s of size n, s falls in exactly one of the following cases:
Case 1: s cannot be partitioned into two valid patterns of smaller size
Case 2: s can be partitioned into two valid patterns of smaller size
For case 1, s must be of the form (_____), where _____ is a valid pattern of size n - 1. So in this case, for every valid pattern t of size n - 1, we simply construct a pattern s by concatenating t with ( and ) as prefix and suffix, respectively (i.e. s = (t)).
For case 2, we can partition s into uv, where u and v are both valid patterns of smaller size. In this case, we have to consider all possible patterns of u and v, where u can be any valid pattern of size i = 1, 2, ..., n - 1, while v can be any valid pattern of size n - i.
When n = 0, clearly only the empty string is a valid pattern, so we have dp(0) = { "" } as our base case. A complete implementation with caching to improve the performance is given below:
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class BalancingBrackets {
private static Map<Integer, Set<String>> dp = new HashMap<>();
public static void main(String[] args) {
Set<String> result = compute(4);
boolean isFirst = true;
for (String s : result) {
if (isFirst) {
isFirst = false;
System.out.print(s);
} else {
System.out.print(", " + s);
}
}
}
private static Set<String> compute(Integer n) {
// Return the cached result if available
if (dp.containsKey(n)) {
return dp.get(n);
}
Set<String> set = new HashSet<>();
if (n == 0) {
// This is the base case with n = 0, which consists only of the
// empty string
set.add("");
} else if (n > 0) {
// For generating patterns in case 1
for (String s : compute(n - 1)) {
set.add("(" + s + ")");
}
// For generating patterns in case 2
for (int i = 1; i < n; i++) {
Set<String> leftPatterns = compute(i);
Set<String> rightPatterns = compute(n - i);
for (String l : leftPatterns) {
for (String r : rightPatterns) {
set.add(l + r);
}
}
}
} else {
// Input cannot be negative
throw new IllegalArgumentException("Input cannot be negative.");
}
// Cache the solution to save time for computing large size problems
dp.put(n, set);
return set;
}
}
I am working on an algorithm, and I need to be able to pass in a List and see if there are four numbers in a row at any point in the list.
I have been struggling with an easy way to do this... Here is the basic idea.. I would like the fourNumbersInARow() method to return true:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Numbers {
/**
* #param args
*/
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<Integer>();
for(int i = 0; i<10; i++){
numbers.add((new Random().nextInt()));
}
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
System.out.println(fourNumbersInARow());
}
private static boolean fourNumbersInARow() {
}
}
Use two variables: last_value and row_count. Going through the list one by one, always look whether the current value is exactly one bigger than the last_value; if yes, increase row_count, if no, reset it to 1. In any case, set last_value to the current value and loop. If at any point row_count becomes 4, return true. If you reach the end of the list, return false.
EDIT: changed counter range to start at 1
Here's an implementation in Java.
static boolean fourNumbersInARow(List<Integer> list) {
int last = 0xFACADE; // can be any number
int count = 0; // important!
for (int i : list) {
if (i == last + 1) {
if (++count == 4) return true;
} else {
count = 1;
}
last = i;
}
return false;
}
Unlike others, this resets the count of numbers in a row to 1 when the sequence is broken (because a number on its own is 1 number in a row). This allows for easier treatment of the first iteration where technically there is no previous number.
In pseudocode:
consecutiveCount = 1
lastNumber = firstElementInList(list)
for (number in list.fromSecondElement()):
if (number - lastNumber == 1):
consecutiveCount++
else:
consecutiveCount = 1
if (consecutiveCount == 4):
return true
lastNumber = number
return false
The bottom line is, you'll want to keep track of the last number in that was in the list, and compare it with the current number to see if the difference is 1. In order to remember the last number, a variable such as lastNumber is needed.
Then, in order to keep track of how many consecutive numbers there have been there should be a counter for that as well, which in the example about is the consecutiveCount.
When the condition where four consecutive numbers have occurred, then the method should return true.
This sounds a little like a homework question, so I don't want to write out a complete solution. But in your method just iterate through the list. Take the first number and see if the next number comes after the current, if so then set a variable flag with the start position and the current number, on the next iteration through the loop check to see if that value is before the previous the value etc... Once four in a row are found, break out of the loop and return true. If you encounter a number that is no chronologically correct then set a flag(start location) to null or negative and start the process over from the current location in the list.
Check this Code, this will return true if there a sequence of 4 numbers and else false otherwise
public class FindFourSequence {
public boolean isFourinRow(ArrayList seqList) {
boolean flag = false;
int tempValue = 0;
int tempValue2 = 0;
int tempValue3 = 0;
int tempValue4 = 0;
Iterator iter = seqList.iterator();
while(iter.hasNext()){
String s1 = (String)iter.next();
tempValue=Integer.valueOf(s1).intValue();
if(!(iter.hasNext())){
break;
}
String s2 = (String)iter.next();
tempValue2=Integer.valueOf(s2).intValue();
if(((tempValue2-tempValue)==1) || (tempValue-tempValue2)==1){
if(!(iter.hasNext())){
break;
}
String s3 = (String)iter.next();
tempValue3=Integer.valueOf(s3).intValue();
if((tempValue3-tempValue2)==1 || (tempValue2-tempValue3)==1){
if(!(iter.hasNext())){
break;
}
String s4 = (String)iter.next();
tempValue4=Integer.valueOf(s4).intValue();
if((tempValue3-tempValue4==1) || (tempValue4-tempValue3)==1){
flag = true;
return flag;
}
}
}
}
return flag;
}
public static void main(String[] args) throws Exception {
ArrayList aList = new ArrayList();
boolean flag = false;
FindFourSequence example = new FindFourSequence();
Random random = new Random();
for (int k = 0; k < 25; k++) {
int number = random.nextInt(20);
System.out.println(" the Number is :" + number);
aList.add("" + number);
}
/* aList.add("" + 1);
aList.add("" + 2);
aList.add("" + 3);
aList.add("" + 4);*/
flag = example.isFourinRow(aList);
System.out.println(" the result value is : " + flag);
}
}