The objective is to count distinct words from a file.
UPDATE: Previous Code was successfully finished. Now I have to do the same but using threads (Oh man, I hate them...) and in addition I want to make it with semaphores for better flow.
Code contains some extra stuff left out from previous attempts, I'm trying to figure out what can be used..
I can read one word at a time but mostly I get a "null" in the container. So until I get anything from the container all the time I can't test the Sorter class and so on...
The new addition to the program is WordContainer class to store one word to pass it from reader to sorter:
package main2;
import java.util.ArrayList;
public class WordContainer
{
private ArrayList<String> words;
public synchronized String take()
{
String nextWord = null;
while (words.isEmpty())
{
try
{
wait();
}
catch (InterruptedException e)
{
}
}
nextWord = words.remove(0);
notify();
return nextWord;
}
public synchronized void put(String word)
{
while (words.size() > 999)
{
try
{
wait();
}
catch (InterruptedException e)
{
}
}
words.add(word);
notify();
}
}
DataSet Class combined with Sorter method resulting in Sorter Class:
package main2;
import java.util.concurrent.Semaphore;
public class Sorter extends Thread
{
private WordContainer wordContainer;
private int top;
private String[] elements;
private boolean stopped;
private Semaphore s;
private Semaphore s2;
public Sorter(WordContainer wordContainer, Semaphore s, Semaphore s2)
{
this.wordContainer = wordContainer;
elements = new String[1];
top = 0;
stopped = false;
this.s = s;
this.s2 = s2;
}
public void run()
{
String nextWord = wordContainer.take();
while (nextWord != null)
{
try
{
s.acquire();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
nextWord = wordContainer.take();
s2.release();
add(nextWord);
}
}
public void startSorting()
{
start();
}
public void stopSorting()
{
stopped = true;
}
public boolean member(String target)
{
if (top > 0)
{
return binarySearch(target, 0, top);
}
else
{
return false;
}
}
private boolean binarySearch(String target, int from, int to)
{
if (from == to - 1)
{
return elements[from].equals(target);
}
int middle = (to - from) / 2 + from;
if (elements[from].equals(target))
{
return true;
}
if (elements[middle].compareTo(target) > 0)
{
// search left
return binarySearch(target, from, middle);
}
else
{
// search right
return binarySearch(target, middle, to);
}
}
public void add(String nextElement)
{
if (top < elements.length)
{
elements[top++] = nextElement;
System.out.println("[" + top + "] " + nextElement);
sort();
}
else
{
String[] newArray = new String[elements.length * 2];
for (int i = 0; i < elements.length; i++)
{
newArray[i] = elements[i];
}
elements = newArray;
add(nextElement);
}
}
private void sort()
{
int index = 0;
while (index < top - 1)
{
if (elements[index].compareTo(elements[index + 1]) < 0)
{
index++;
}
else
{
String temp = elements[index];
elements[index] = elements[index + 1];
elements[index + 1] = temp;
if (index > 0)
{
index--;
}
}
}
}
public int size()
{
return top;
}
public String getSortedWords()
{
String w = "";
for (int i = 0; i < elements.length; i++)
{
w += elements[i] + ", ";
}
return w;
}
public int getNumberOfDistinctWords()
{
return top;
}
}
Reader Class now looks like this:
package main2;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.Semaphore;
public class Reader extends Thread
{
private static final int whitespace = 45;
private static final int word = 48;
private static final int finished = -1;
private WordContainer wordContainer;
private Semaphore s;
private Semaphore s2;
private String[] wordsR;
private int state;
private BufferedReader reader;
private int nextFreeIndex;
public Reader(File words, WordContainer wordContainer, Semaphore s,
Semaphore s2)
{
state = whitespace;
try
{
reader = new BufferedReader(new FileReader(words));
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
nextFreeIndex = 0;
wordsR = new String[1];
this.wordContainer = wordContainer;
this.s = s;
this.s2 = s;
}
public void startReading()
{
start();
}
public void run()
{
String nextWord = readNext();
while (nextWord != null)
{
nextWord = readNext();
wordContainer.put(nextWord);
s.release();
try
{
s2.acquire();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public String readNext()
{
int next;
StringBuffer nextWord = new StringBuffer();
while (true)
{
try
{
next = reader.read();
}
catch (IOException e)
{
next = -1;
}
char nextChar = (char) next;
switch (state)
{
case whitespace:
if (isWhiteSpace(nextChar))
{
state = whitespace;
}
else if (next == -1)
{
state = finished;
}
else
{
nextWord.append(nextChar);
state = word;
}
break;
case word:
if (isWhiteSpace(nextChar))
{
state = whitespace;
return nextWord.toString();
}
else if (next == -1)
{
state = finished;
return nextWord.toString();
}
else
{
nextWord.append(nextChar);
state = word;
}
break;
case finished:
return null;
}
}
}
private boolean isWhiteSpace(char nextChar)
{
switch (nextChar)
{
case '-':
case '"':
case ':':
case '\'':
case ')':
case '(':
case '!':
case ']':
case '?':
case '.':
case ',':
case ';':
case '[':
case ' ':
case '\t':
case '\n':
case '\r':
return true;
}
return false;
}
public void close()
{
try
{
reader.close();
}
catch (IOException e)
{
}
}
public String getWords()
{
return wordContainer.take();
}
}
Test Class
package test;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.Semaphore;
import main2.Reader;
import main2.Sorter;
import main2.WordContainer;
import junit.framework.Assert;
import junit.framework.TestCase;
public class TestDistinctWordsWithThreads extends TestCase
{
public void test() throws IOException, InterruptedException
{
File words = new File("resources" + File.separator + "AV1611Bible.txt");
if (!words.exists())
{
System.out.println("File [" + words.getAbsolutePath()
+ "] does not exist");
Assert.fail();
}
WordContainer container = new WordContainer();
Semaphore s = new Semaphore(0);
Semaphore s2 = new Semaphore(0);
Reader reader = new Reader(words, container, s, s2);
Sorter sorter = new Sorter(container, s, s2);
reader.startReading();
sorter.startSorting();
reader.join();
sorter.join();
System.out.println(reader.getWords());
Assert.assertTrue(sorter.getNumberOfDistinctWords() == 14720);
/*
* String bible = reader.getWords(); System.out.println(bible); String[]
* bible2 = sorter.getSortedWords(); System.out.println(bible2);
* assertTrue(bible2.length < bible.length());
*/
}
}
Why don't you sinply try something like:
public int countWords(File file) {
Scanner sc = new Scanner(file);
Set<String> allWords = new HashSet<String>();
while(sc.hasNext()) {
allWords.add(sc.next());
}
return allWords.size();
}
Related
I am tasked with creating a Java BFS Algorithm without using the built-in LinkedList and Dynamic ArrayList.
I managed to find 2 examples that seem to achieve the result that I am looking for. They can be found below. When I compare my results to the examples I have found my results seem to have duplicated links.
I suspect it has something to do with my contains() method however having tried many different options that I found from Java: Implement String method contains() without built-in method contains() the issue still persist.
Could someone pls help me with this? Thank you so much in advance!!
Examples
https://github.com/theexplorist/WebCrawler
https://www.youtube.com/watch?v=lyVjfz2Tuck&ab_channel=SylvainSaurel (The code in the video can be found below)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WebCrawler {
public static Queue<String> queue = new LinkedList<>();
public static Set<String> marked = new HashSet<>();
public static String regex = "http[s]*://(\\w+\\.)*(\\w+)";
public static void bfsAlgorithm(String root) throws IOException{
queue.add(root);
BufferedReader br = null;
while (!queue.isEmpty()){
String crawledUrl = queue.poll();
System.out.println("\n=== Site crawled : " + crawledUrl + " ===");
if(marked.size() > 100)
return;
boolean ok = false;
URL url = null;
while(!ok){
try{
url = new URL(crawledUrl);
br = new BufferedReader(new InputStreamReader(url.openStream()));
ok = true;
} catch (MalformedURLException e) {
System.out.println("*** Maformed URL : " + crawledUrl);
crawledUrl = queue.poll();
ok = false;
}
}
StringBuilder sb = new StringBuilder();
String tmp = null;
while((tmp = br.readLine()) != null){
sb.append(tmp);
}
tmp = sb.toString();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(tmp);
while (matcher.find()){
String w = matcher.group();
if(!marked.contains(w)){
marked.add(w);
System.out.println("Sited added for crawling : " + w);
queue.add(w);
}
}
}
if(br != null){
br.close();
}
}
public static void showResults(){
System.out.println("\n\nResults : ");
System.out.println("Web sites crawled : " + marked.size() + "\n");
for (String s: marked){
System.out.println("* " + s);
}
}
public static void main(String[] args){
try{
bfsAlgorithm("https://www.tesla.com/");
showResults();
} catch (IOException e) {
}
}
}
Below are the results for the root url: https://en.wikipedia.org/
I edited the code to only show the first 20 links.
Result from https://github.com/theexplorist/WebCrawler
Result from the Youtube Video
Result from my code
If you look at my result you will see that there are duplicated links.
Pls find my code below
Main.java
public static void main(String[] args) {
WebCrawler crawler = new WebCrawler();
String rootUrl = "https://en.wikipedia.org/";
crawler.discoverWeb(rootUrl);
}
}
DA.java (Dynamic Array)
class DA{
int size;
int capacity = 10;
Object[] nameofda;
public DA(){
this.nameofda = new Object[capacity];
}
public DA(int capacity){
this.capacity = capacity;
this.nameofda = new Object[capacity];
}
public void add(Object anything){
if(size >= capacity){
grow();
}
nameofda[size] = anything;
size++;
}
public void insert(int index, Object anything){
if(size >= capacity){
grow();
}
for (int i = size; i > index; i--){
nameofda[i] = nameofda[i - 1];
}
nameofda[index] = anything;
size++;
}
public void delete(Object anything){
for(int i = 0; i < size; i++){
if(nameofda[i] == anything){
for(int j = 0; j < (size - i - 1); j++){
nameofda[i + j] = nameofda[i + j + 1];
}
nameofda[size - 1] = null;
size--;
if(size <=(int)(capacity/3)){
shrink();
}
break;
}
}
}
public boolean contains(Object anything){
for(int i = 0; i < size; i++){
if (nameofda[i] == anything){
return true;
}
}
return false;
}
private void grow(){
int newcap = (int)(capacity *2);
Object[] newnameofda = new Object[newcap];
for(int i = 0; i < size; i++){
newnameofda[i] = nameofda[i];
}
capacity = newcap;
nameofda = newnameofda;
}
private void shrink(){
int newcap = (int)(capacity / 2);
Object[] newnameofda = new Object[newcap];
for(int i = 0; i < size; i++){
newnameofda[i] = nameofda[i];
}
capacity = newcap;
nameofda = newnameofda;
}
public boolean isEmpty(){
return size == 0;
}
public String toString(){
String nameofstring = "";
for(int i = 0; i < size; i++){
nameofstring += nameofda[i] + ", ";
}
if(nameofstring != ""){
nameofstring = "[" + nameofstring.substring(0, nameofstring.length() - 2) + "]";
}
else {
nameofstring = "[]";
}
return nameofstring;
}
Queue.java (LinkedList)
public class Queue<T> {
private Node<T> front;
private Node<T> rear;
private int length;
private static class Node<T> {
private final T data;
private Node<T> next;
public Node(T data) {
this.data = data;
}
}
public void enQueue(T item) {
if (front == null) {
rear = new Node<T>(item);
front = rear;
} else {
rear.next = new Node<T>(item);
rear = rear.next;
}
length++;
}
public T deQueue() {
if (front != null) {
T item = front.data;
front = front.next;
length--;
return item;
}
return null;
}
public int size() {
return length;
}
public boolean isEmpty(){
return length == 0;
}
public void displayQueue() {
Node<T> currentNode = front;
while (currentNode != null) {
System.out.print(currentNode.data+" ");
currentNode = currentNode.next;
}
}
}
WebCrawler.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WebCrawler {
private Queue<String> queue;
DA discoveredWebsitesList = new DA(5);
public WebCrawler() {
this.queue = new Queue<>();
}
public void discoverWeb(String root) {
this.queue.enQueue(root);
this.discoveredWebsitesList.add(root);
while (!queue.isEmpty()) {
String v = this.queue.deQueue();
StringBuilder rawHtml = readUrl(v);
String regexe = "https://(\\w+\\.)*(\\w+)";
Pattern pattern = Pattern.compile(regexe);
Matcher matcher = pattern.matcher(rawHtml);
while(matcher.find()){
String actualUrl = matcher.group();
if(!this.discoveredWebsitesList.contains(actualUrl)){
this.discoveredWebsitesList.add(actualUrl);
System.out.println("website has been found with URL :" + actualUrl);
this.queue.enQueue(actualUrl);
//System.out.println("Size is: " + queue.size());
if(queue.size() == 20){
System.exit(0);
}
}
}
}
}
public StringBuilder readUrl(String v) {
StringBuilder rawHtml = new StringBuilder() ;
URL ur;
try {
ur = new URL(v);
BufferedReader br = new BufferedReader(new InputStreamReader(ur.openStream()));
String inputLine = "";
while((inputLine = br.readLine()) != null){
rawHtml.append(inputLine);
}br.close();
} catch (Exception e) {
e.printStackTrace();
}
return rawHtml;
}
}
Whats wrong with this program? I want to stop all FutureTask immediately if one of them returns false as result. See line 100 and following. I've a list of future tasks. Then i instantiate an executor service and add all tasks. Then i execute the tasks and iterate through the task list, to check if one task returns false.
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class PrimeIterator {
private boolean longBased = true;
private long startLong;
private BigInteger startBI;
public PrimeIterator(BigInteger start) {
if (start.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
longBased = false;
}
if (longBased) {
startLong = start.longValue();
} else {
startBI = start;
}
}
public BigInteger nextPrime() {
BigInteger b;
while (true) {
if (longBased) {
if (isPrime(startLong)) {
b = BigInteger.valueOf(startLong);
increase();
return b;
}
} else {
if (isPrime(startBI)) {
b = startBI;
increase();
return b;
}
}
increase();
}
}
private boolean isPrime(long toTest) {
if (toTest % 2 == 0) {
return false;
}
long sqrt = (long) Math.sqrt(startLong);
for (long i = 3; i <= sqrt; i += 2) {
if (toTest % i == 0) {
return false;
}
}
return true;
}
private static class MyTask implements Callable<Boolean> {
private final BigInteger toTest;
private final BigInteger part;
private final int multiplier;
private static volatile boolean hasFalseResult;
private MyTask(BigInteger toTest, BigInteger part, int multiplier) {
this.toTest = toTest;
this.part = part;
this.multiplier = multiplier;
hasFalseResult = false;
}
#Override
public Boolean call() throws Exception {
BigInteger from = part.multiply(BigInteger.valueOf(multiplier)).add(BigInteger.valueOf(3));
BigInteger to = part.multiply(BigInteger.valueOf(multiplier + 1)).add(BigInteger.valueOf(3));
System.out.println("starting: " + toTest + " " + from + " " + to + " " + toTest.sqrt());
return isPrime(toTest, from, to);
}
private boolean isPrime(BigInteger b, BigInteger from, BigInteger to) {
for (BigInteger i = from; to.compareTo(i) > 0; i = i.add(BigInteger.TWO)) {
if (hasFalseResult) {
return false;
}
if (b.mod(i).compareTo(BigInteger.ZERO) == 0) {
hasFalseResult = true;
return false;
}
}
return true;
}
}
private boolean isPrime(BigInteger toTest) {
// if (toTest.isProbablePrime(5)) {
if (toTest.mod(BigInteger.TWO).compareTo(BigInteger.ZERO) == 0) {
return false;
}
BigInteger sqrt = toTest.sqrt();
BigInteger part = sqrt.divide(BigInteger.valueOf(10)).add(BigInteger.ONE);
List<FutureTask<Boolean>> taskList = new ArrayList<FutureTask<Boolean>>();
for (int i = 0; i < 10; i++) {
taskList.add(new FutureTask<>(new MyTask(toTest, part, i)));
}
ExecutorService executor = Executors.newFixedThreadPool(3);
for (FutureTask<Boolean> futureTask : taskList) {
executor.execute(futureTask);
}
try {
for (FutureTask<Boolean> futureTask : taskList) {
if (!futureTask.get()) {
return false;
}
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
return false;
}
return true;
// }
// return false;
}
private void increase() {
if (longBased) {
if (startLong == Long.MAX_VALUE) {
longBased = false;
startBI = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE);
} else {
startLong++;
}
} else {
startBI = startBI.add(BigInteger.ONE);
}
}
public static void main(String[] args) {
PrimeIterator pi = new PrimeIterator(BigInteger.valueOf(1));
for (int i = 0; i < 20; i++) {
System.out.println(pi.nextPrime());
}
pi = new PrimeIterator(BigInteger.valueOf(Long.MAX_VALUE - 10));
for (int i = 0; i < 5; i++) {
System.out.println(pi.nextPrime());
}
}
}
FutureTasks run in background threads. Once you return false, your isPrime() method will return immediately. But it won't stop other FutureTasks from completion as they are running in separate threads.
The program that I am writing simulates a road charging system which reads several lines of inputs, each one representing a different command until I reach the EOF (\n).
This commands simulate a road charging system, where the input reads as follows:
PASS 44AB55 I -> where the first word is the command the program receives, the second word is the number plate of the car (44AB55) and the second is the status of the car (Regular or Irregular).
There are three types of commands:
“PASS 00AA00 R” – Increments the number of times that the car has passed in the system and marks its status has Regular or Irreguar. If the car isnt still in the database, it inserts the car as Regular and starts the counter with one passage.
“UNFLAG 00AA00” – Flags the car as Regular if it exists in the database. If the car doesnt exist in the database ignores the command.
“STATUS 00AA00” – Retrieves the status of the car (Regular or Irregular) and the number of passages of the car in the system. If it the car doesnt exist in the database, prints a "NO RECORD" message.
To solve this problem, I am using AVL trees and using the following code:
import java.util.ArrayList;
import java.util.Scanner;
public class TP2_probB {
static No raiz = null;
static double numRotacoes = 0;
static double numAtravessos = 0;
public static class No {
private String matricula;
private int porticos;
private boolean estadoRegular;
private No pai;
private No filhoEsq;
private No filhoDir;
private int balanco;
public No(String matricula, int porticos, boolean estadoRegular) {
this.matricula = matricula;
this.porticos = porticos;
this.estadoRegular = estadoRegular;
this.pai = null;
this.filhoDir = null;
this.filhoEsq = null;
this.balanco = 0;
}
public void setEstadoRegular(boolean estadoRegular) {
this.estadoRegular = estadoRegular;
}
public void setPai(No pai) {
this.pai = pai;
}
public void setFilhoEsq(No filhoEsq) {
this.filhoEsq = filhoEsq;
}
public void setFilhoDir(No filhoDir) {
this.filhoDir = filhoDir;
}
public void atribuiNoEsq(No noEsq) {
this.filhoEsq = noEsq;
}
public void atribuiNoDir(No noDir) {
this.filhoDir = noDir;
}
public void atribuiPai(No noPai) {
this.pai = noPai;
}
public void aumentaPortico() {
porticos++;
}
public String getMatricula() {
return matricula;
}
public boolean isEstadoRegular() {
return estadoRegular;
}
public No getPai() {
return pai;
}
public No getFilhoEsq() {
return filhoEsq;
}
public No getFilhoDir() {
return filhoDir;
}
#Override
public String toString() {
String estado;
if (estadoRegular == true) {
estado = "R";
} else {
estado = "I";
}
return matricula + " " + porticos + " " + estado;
}
}
public static No duplaRotacaoFilhoEsq(No k3)
{
k3.filhoEsq = rotacaoFilhoDir(k3);
return rotacaoFilhoEsq(k3);
}
public static No duplaRotacaoFilhoDir(No k3)
{
k3.filhoDir = rotacaoFilhoEsq(k3);
return rotacaoFilhoDir(k3);
}
public static No rotacaoFilhoDir(No k1) {
No k2 = k1.filhoDir;
k2.pai=k1.pai;
k1.filhoDir = k2.filhoEsq;
if(k1.filhoDir!=null)
{
k1.filhoDir.pai=k1;
}
k2.filhoEsq = k1;
k1.pai=k2;
if(k2.pai!=null)
{
if(k2.pai.filhoDir==k1)
{
k2.pai.filhoDir = k2;
}
else if(k2.pai.filhoEsq==k1)
{
k2.pai.filhoEsq = k2;
}
}
balanco(k2);
balanco(k1);
return k2;
}
public static No rotacaoFilhoEsq(No k1) {
No k2 = k1.filhoEsq;
k2.pai=k1.pai;
k1.filhoEsq = k2.filhoDir;
if(k1.filhoEsq!=null)
{
k1.filhoEsq.pai=k1;
}
k2.filhoDir = k1;
k1.pai=k2;
if(k2.pai!=null)
{
if(k2.pai.filhoDir==k1)
{
k2.pai.filhoDir = k2;
}
else if(k2.pai.filhoEsq==k1)
{
k2.pai.filhoEsq = k2;
}
}
balanco(k2);
balanco(k1);
return k2;
}
public static int pesagem(No aux)
{
if(aux==null)
{
return -1;
}
if(aux.filhoEsq == null && aux.filhoDir == null)
{
return 0;
}
else if ((aux.filhoEsq == null))
{
return (pesagem(aux.filhoDir) + 1);
}
else if ((aux.filhoDir == null))
{
return (pesagem(aux.filhoEsq) + 1);
}
else
return (Math.max(pesagem(aux.filhoEsq), pesagem(aux.filhoDir)) + 1);
}
public static void balanco(No tmp)
{
tmp.balanco = pesagem(tmp.filhoDir)-pesagem(tmp.filhoEsq);
}
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
String linha;
String[] aux;
ArrayList<String> output = new ArrayList<String>();
int x = 0;
while (true) {
linha = input.nextLine();
if (linha.isEmpty())
{
break;
}
else
{
aux = linha.split(" ");
if (aux[0].compareTo("PASS") == 0) {
No novo;
if (aux[2].compareTo("R") == 0) {
novo = new No(aux[1], 1, true);
} else {
novo = new No(aux[1], 1, false);
}
if (raiz == null) {
raiz = novo;
balanco(raiz);
} else {
procuraNo(novo);
}
} else if (aux[0].compareTo("UNFLAG") == 0) {
if (raiz != null) {
No no = new No(aux[1], 0, false);
mudaEstado(no);
}
} else if (aux[0].compareTo("STATUS") == 0) {
if (raiz == null) {
output.add(aux[1] + " NO RECORD");
} else {
No no = new No(aux[1], 0, false);
output.add(procuraRegisto(no));
}
}
}
}
for (int i = 0; i < output.size(); i++) {
System.out.println(output.get(i));
}
System.out.println("Número de Rotações: "+numRotacoes+"\nNúmero de atravessias: "+numAtravessos);
}
public static void procuraNo(No novo) {
No aux = raiz;
while (true) {
if (aux.getMatricula().compareTo(novo.getMatricula()) == 0) {
aux.aumentaPortico();
aux.setEstadoRegular(novo.isEstadoRegular());
equilibra(aux);
break;
} else if (aux.getMatricula().compareTo(novo.getMatricula()) < 0) {
if (aux.getFilhoDir() == null) {
novo.setPai(aux);
aux.setFilhoDir(novo);
aux=aux.filhoDir;
equilibra(aux);
break;
} else {
aux = aux.getFilhoDir();
numAtravessos++;
}
} else if (aux.getMatricula().compareTo(novo.getMatricula()) > 0) {
if (aux.getFilhoEsq() == null) {
novo.setPai(aux);
aux.setFilhoEsq(novo);
aux=aux.filhoEsq;
equilibra(aux);
break;
} else {
aux = aux.getFilhoEsq();
numAtravessos++;
}
}
}
}
public static void equilibra(No tmp) {
balanco(tmp);
int balanco = tmp.balanco;
System.out.println(balanco);
if(balanco==-2)
{
if(pesagem(tmp.filhoEsq.filhoEsq)>=pesagem(tmp.filhoEsq.filhoDir))
{
tmp = rotacaoFilhoEsq(tmp);
numRotacoes++;
System.out.println("Rodou");
}
else
{
tmp = duplaRotacaoFilhoDir(tmp);
numRotacoes++;
System.out.println("Rodou");
}
}
else if(balanco==2)
{
if(pesagem(tmp.filhoDir.filhoDir)>=pesagem(tmp.filhoDir.filhoEsq))
{
tmp = rotacaoFilhoDir(tmp);
numRotacoes++;
System.out.println("Rodou");
}
else
{
tmp = duplaRotacaoFilhoEsq(tmp);
numRotacoes++;
System.out.println("Rodou");
}
}
if(tmp.pai!=null)
{
equilibra(tmp.pai);
}
else
{
raiz = tmp;
}
}
public static void mudaEstado(No novo) {
No aux = raiz;
while (true) {
if (aux.getMatricula().compareTo(novo.getMatricula()) == 0) {
aux.setEstadoRegular(true);
break;
} else if (aux.getMatricula().compareTo(novo.getMatricula()) < 0) {
if (aux.getFilhoDir() == null) {
break;
} else {
aux = aux.getFilhoDir();
numAtravessos++;
}
} else if (aux.getMatricula().compareTo(novo.getMatricula()) > 0) {
if (aux.getFilhoEsq() == null) {
break;
} else {
aux = aux.getFilhoEsq();
numAtravessos++;
}
}
}
}
public static String procuraRegisto(No novo) {
No aux = raiz;
while (true) {
if (aux.getMatricula().compareTo(novo.getMatricula()) == 0) {
return aux.toString();
} else if (aux.getMatricula().compareTo(novo.getMatricula()) < 0) {
if (aux.getFilhoDir() == null) {
return (novo.getMatricula() + " NO RECORD");
} else {
aux = aux.getFilhoDir();
numAtravessos++;
}
} else if (aux.getMatricula().compareTo(novo.getMatricula()) > 0) {
if (aux.getFilhoEsq() == null) {
return (novo.getMatricula() + " NO RECORD");
} else {
aux = aux.getFilhoEsq();
numAtravessos++;
}
}
}
}
}
The problem is that I am getting a stack overflow error:
Exception in thread "main" java.lang.StackOverflowError
at TP2_probB.pesagem(TP2_probB.java:174)
at TP2_probB.pesagem(TP2_probB.java:177)
at TP2_probB.pesagem(TP2_probB.java:177)
at TP2_probB.pesagem(TP2_probB.java:177)
(...)
at TP2_probB.pesagem(TP2_probB.java:177)
Here is a link with two files with inputs used to test the program:
https://drive.google.com/folderview?id=0B3OUu_zQ9xlGfjZHRlp6QkRkREc3dU82QmpSSWNMRlBuTUJmWTN5Ny1LaDhDN3M2WkVjYVk&usp=sharing
Im pretty new to Java and to thread-programming especially. This code is mostly out of a pretty old book (2001) with samples and examples for a search-engine.
But its just not working
Now i don't know if i am making a mistake or if the author made it or if there are incompatibilities with different versions of java...i really have no clue! The oddest thing about it is that it works 1 out of 100 times ...
After hours of debugging i would appreciate any help!
SearchEngine.java:
import java.util.Vector;
import parsing.SourceElement;
import parsing.WebParserWrapper;
import query.Filter;
public class SearchEngine implements Runnable {
private Vector linkHistory = new Vector();
private int currentLink;
private String beginAt = null;
private SearchHandler searchHandler = null;
private boolean searchInProgress = false;
private boolean stopPending = false;
boolean firstTime = true;
public boolean searchInProgress() {
return searchInProgress;
}
public boolean stopPending() {
return stopPending;
}
#SuppressWarnings("unchecked")
public void followLinks(String url) {
if (stopPending)
return;
try {
boolean drillDown = false;
WebParserWrapper webParser = new WebParserWrapper();
Vector sortedElements = webParser.getElements(url, "", "WITHGET");
Vector contentElements = Filter.getFilteredElements(sortedElements, Filter.CONTENT, "matches", "*");
for (int i = 0; i < contentElements.size(); i++) {
SourceElement thisElement = (SourceElement) contentElements.elementAt(i);
String thisKey = (String) thisElement.getKey();
String thisContent = (String) thisElement.getContent();
boolean goodHit = searchHandler.handleElement(url, thisKey, thisContent);
if (goodHit) {
drillDown = true;
}
}
System.out.println(url + " -- DrillDown " + ((drillDown) ? "positive" : "negative"));
if (drillDown) {
Vector linkElements = Filter.getFilteredElements(sortedElements, Filter.KEY, "matches",
"*a[*].#href[*]");
for (int i = 0; i < linkElements.size(); i++) {
SourceElement thisElement = (SourceElement) linkElements.elementAt(i);
String thisContent = (String) thisElement.getContent();
if (!linkHistory.contains(thisContent)) {
linkHistory.add(thisContent);
System.out.println("Collected: " + thisContent);
}
}
}
}
catch (Exception e) {}
if (currentLink < linkHistory.size()) {
String nextLink = (String) linkHistory.elementAt(currentLink++);
if (nextLink != null) {
followLinks(nextLink);
}
}
}
public boolean startSearch(String url, SearchHandler searchHandler) {
if (searchInProgress)
return false;
beginAt = url;
this.searchHandler = searchHandler;
this.linkHistory = new Vector();
this.currentLink = 0;
Thread searchThread = new Thread(this);
searchThread.start();
return true;
}
public void stopSearch() {
stopPending = true;
}
#Override
public void run() {
searchInProgress = true;
followLinks(beginAt);
searchInProgress = false;
stopPending = false;
}
}
SimpleSearcher.java
import java.util.Enumeration;
import java.util.Hashtable;
public class SimpleSearcher implements SearchHandler {
private SearchEngine searchEngine;
private String keyword;
private String startURL;
private Hashtable hits = new Hashtable();
public boolean handleElement(String url, String key, String content) {
boolean goodHit = false;
int keywordCount = 0;
int pos = -1;
while ((pos = content.toLowerCase().indexOf(keyword, pos + 1)) >= 0){
keywordCount++;
}
if (keywordCount > 0) {
Integer count = (Integer) hits.get(url);
if (count == null){
hits.put(url, new Integer(1));
}
else {
hits.remove(url);
hits.put(url, new Integer(count.intValue() + keywordCount));
}
goodHit = true;
}
if (hits.size() >= 3)
searchEngine.stopSearch();
return goodHit;
}
public Hashtable search(String startURL, String keyword) {
searchEngine = new SearchEngine();
this.startURL = startURL;
this.keyword = keyword;
searchEngine.startSearch(startURL, this);
try {Thread.sleep(1000);}catch (Exception e){e.printStackTrace();}
while (searchEngine.searchInProgress());
return this.hits;
}
public static void main(String[] args) {
SimpleSearcher searcher = new SimpleSearcher();
String url = "http://www.nzz.ch/";
String compareWord = "der";
Hashtable hits = searcher.search(url, compareWord);
System.out.println("URLs=" + hits.size());
for (Enumeration keys = hits.keys(); keys.hasMoreElements();) {
String thisKey = (String) keys.nextElement();
int thisCount = ((Integer) hits.get(thisKey)).intValue();
System.out.println(thisCount + " hits at " + thisKey);
}
}
}
SearchHandler.java
public interface SearchHandler {
public boolean handleElement(String url, String key, String content);
}
I'm trying to implement a Producer Consumer problem in java. I'm using a circular buffer (circular array) to for the Producer to insert items into the buffer. Following is my code:
import java.util.*;
import java.io.*;
public class Buffer
{
String a[];
int front, rear;
public Buffer(int size)
{
a = new String[size];
front = rear = -1;
}
public boolean insert(String dataitem)
{
int p;
p = (rear+1) % a.length;
if(p==front)
{
System.out.println("Buffer full");
return false;
}
else
{ rear = p;
a[rear] = dataitem;
if(front == -1)
front = 0;
return true;
}
}
public boolean empty()
{
if(front == -1)
return true;
else
return false;
}
public String delete()
{
String result = a[front];
if(front == rear)
front = rear = -1;
else
front = (front +1)%a.length;
return result;
}
public void display()
{
if(front == -1)
System.out.println("Buffer empty");
else
{
System.out.println("Buffer elements are:");
int i= front;
while(i!= rear)
{
System.out.println(a[i]);
i = (i+1)%a.length;
}
System.out.println(a[i]);
}
}
public static void main(String[] args)
{
int size = Integer.parseInt(args[0]);
Buffer b = new Buffer(size);
int ch;
String dataitem, msg;
Thread prod = new Thread(new Producer(b, size));
Thread cons = new Thread(new Consumer(b, size));
prod.start();
cons.start();
}
}
class Producer extends Thread
{
Buffer b;
int size;
public Producer(Buffer b, int size)
{
this.b = b;
this.size = size;
}
public void run()
{
while(true)
{
synchronized(b)
{
for(int i = 1; i <= size; i++)
{
try
{ String dataitem = Thread.currentThread().getId()+"_"+i;
boolean bool = b.insert(dataitem);
//b.notifyAll();
if(bool)
System.out.println("Successfully inserted "+dataitem);
b.notifyAll();
Thread.sleep(2000);
}
catch(Exception e)
{ e.printStackTrace();
}
}
}
}
}
}
class Consumer extends Thread
{
Buffer b;
int size;
public Consumer(Buffer b, int size)
{
this.b = b;
this.size = size;
}
public void run()
{
while(b.empty())
{
synchronized(b)
{
try
{
System.out.println("Buffer empty");
b.wait();
}
catch(Exception e)
{ e.printStackTrace();
}
}
}
synchronized(b)
{
b.notifyAll();
String dataitem = b.delete();
System.out.println("Removed "+dataitem);
}
}
}
The producer is inserting dataitems into the buffer successfully. But they aren't being consumed by the consumer.
I get the following output when I execute the program.
Successfully inserted 11_1
Successfully inserted 11_2
Buffer full
Buffer full
Buffer full
Buffer full
Buffer full
Buffer full
My question is how do I get the consumer to consume items from the buffer?
The major problem is that the synchronized block in your Producer is too wide. It is never letting the Consumer acquire the lock
Start by narrowing the scope, for example...
while (true) {
for (int i = 1; i <= size; i++) {
try {
String dataitem = Thread.currentThread().getId() + "_" + i;
boolean bool = b.insert(dataitem);
//b.notifyAll();
if (bool) {
System.out.println("Successfully inserted " + dataitem);
}
synchronized (b) {
b.notifyAll();
}
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
You may also consider synchronizing the ing insert and delete methods themselves. I personally would be tempted to use a internal lock, but you could simply synchronize the methods themselves, for example...
public synchronized boolean insert(String dataitem) {...}
public synchronized String delete() {...}
As it stands, your Consumer will only ever read a single value from the buffer, but I'll let you figure that one out ;)
As a side note, I might put the wait and notify functionality directly within the Buffer, so that whenever you try and delete a value, it will wait, within the delete method for the Buffer to be not empty and allow the insert method to make the notifications itself...but that's me ;)
Equally, I might consider blocking the insert method until there is more room, but that will come down to how you want to implement it :P
Updated
Very basically, this will start giving the results you are looking for...
public class ProducerConsumer {
public static void main(String[] args) {
new ProducerConsumer();
}
public ProducerConsumer() {
int size = 5;
Buffer b = new Buffer(size);
Thread prod = new Thread(new Producer(b, size));
Thread cons = new Thread(new Consumer(b, size));
prod.start();
cons.start();
}
public class Buffer {
String a[];
int front, rear;
public Buffer(int size) {
a = new String[size];
front = rear = -1;
}
public synchronized boolean insert(String dataitem) {
int p;
p = (rear + 1) % a.length;
if (p == front) {
System.out.println("Buffer full");
return false;
} else {
rear = p;
a[rear] = dataitem;
if (front == -1) {
front = 0;
}
return true;
}
}
public boolean empty() {
return front == -1;
}
public synchronized String delete() {
String result = a[front];
if (front == rear) {
front = rear = -1;
} else {
front = (front + 1) % a.length;
}
return result;
}
public void display() {
if (front == -1) {
System.out.println("Buffer empty");
} else {
System.out.println("Buffer elements are:");
int i = front;
while (i != rear) {
System.out.println(a[i]);
i = (i + 1) % a.length;
}
System.out.println(a[i]);
}
}
}
class Producer extends Thread {
Buffer b;
int size;
public Producer(Buffer b, int size) {
this.b = b;
this.size = size;
}
public void run() {
int i = 0;
while (true) {
try {
String dataitem = Thread.currentThread().getId() + "_" + ++i;
boolean bool = b.insert(dataitem);
if (bool) {
System.out.println("Successfully inserted " + dataitem);
}
synchronized (b) {
b.notifyAll();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class Consumer extends Thread {
Buffer b;
int size;
public Consumer(Buffer b, int size) {
this.b = b;
this.size = size;
}
public void run() {
while (true) {
while (b.empty()) {
synchronized (b) {
try {
System.out.println("Buffer empty");
b.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
String dataitem = null;
synchronized (b) {
dataitem = b.delete();
}
System.out.println("Removed " + dataitem);
}
}
}
}