Heyy guys, I need to determine if a given HTML Document is well formed or not.
I just need a simple implementation using only Java core API classes i.e. no third party stuff like JTIDY or something.
Actually, what is exactly needed is an algorithm that scans a list of TAGS. If it finds an open tag, and the next tag isn't its corresponding close tag, then it should be another open tag which in turn should have its close tag as the next tag, and if not it should be another open tag and then its corresponding close tag next, and the close tags of the previous open tags in reverse order coming one after the other on the list. If the list conforms to this order then it returns true or else false. I've already written methods to convert a tag to a close tag.
Here is the skeleton code of what I've started working on already. Its not too neat, but it should give you guys a basic idea of what I'm trying to do.
public boolean validateHtml(){
ArrayList<String> tags = fetchTags();
//fetchTags returns this [<html>, <head>, <title>, </title>, </head>, <body>, <h1>, </h1>, </body>, </html>]
//I create another ArrayList to store tags that I haven't found its corresponding close tag yet
ArrayList<String> unclosedTags = new ArrayList<String>();
String temp;
for (int i = 0; i < tags.size(); i++) {
temp = tags.get(i);
if(!tags.get(i+1).equals(TagOperations.convertToCloseTag(tags.get(i)))){
unclosedTags.add(tags.get(i));
if(){
}
}else{
return true;//well formed html
}
}
return true;
}
Two thoughts. First off maybe you could get away with using an XML parser on the html? Potentially easier and vastly less time consuming.
I havn't put a whole lot of thought into this but to me it sounds like recursion and stack would be the way to go. Something like
public myClass(String htmlInput)
{
openedTags = new Stack<String>();
this.htmlInput = htmlInput;
}
public boolean validate()
{
return validate(this.htmlInput);
}
private boolean validate(String html)
{
boolean result = true;
String curTag;
while(htmlLeft) //worker loop
{
if(isOneOffTag(curTag)) //matches <tags />
continue;
else if(isOpenTag(curTag)) //matches <tags>
{
openedTags.push(curTag);
if(!validate(innerHtml))
return false;
}
else if(isCloseTag(curTag)) //matches </tags>
{
String lastTag = (String)openedTags.peek();
if(!tagIsSimiliar(curTag, lastTag))
return false;
openedTags.pop();
}
}
return result;
}
private String nextTag(){return null;}
private boolean isOpenTag(String tag){ return true;}
private boolean isCloseTag(String tag){ return true;}
private boolean isOneOffTag(String tag){ return true;}
private boolean tagIsSimiliar(String curTag, String lastTag){return true;}
*edit 1: probably should have pushed onto the stack.
**edit 2: I suppose the issue here would be to determine where when returning solely a boolean you've left off. This would require some kind of pointer so that you know where you've left off. The idea though i believe would still work.
Related
I have been stuck on a particular problem that is to extract an infixexpression from a VariableDeclarationStatement. for example:
String s = 'a'+'b'+'c';
This is an instance of VariableDeclarationStatement. and i need to get the infixexpression 'a'+'b'+'c' out of it.
I have tried : 1.Tried converting to string.But no conversion back is possible.
2.Tried converting to list but still not possible.
I have tried above methods to try and manipulate and extract InfixExpression out of it.Please help me.
EDIT
here is what i have done :
if (node instanceof InfixExpression) {
infixExpression= (InfixExpression) node;
} else if (node.getParent() instanceof InfixExpression) {
infixExpression= (InfixExpression) node.getParent();
} else { //while trying to get this proposal with spaces its reaching here.
String nodeString =node.toString();
String infixExp="s";
int t;
for (t=0;nodeString.charAt(t)!='=';t++);
infixExp.concat(nodeString.substring(t+1, nodeString.length()));
infixExpression = (InfixExpression)infixExp; //this cast doesn't work here
}
Its still unclear what you want to do.
public class InfixVisitor extends ASTVisitor {
#Override
public boolean visit(InfixExpression node) {
// NOTE: node.toString() should only be used debugging.
// Probably you could use it anyway.
...
return super.visit(node);
}
}
With above visitor you can access all InfixExpression nodes with e.g.:
ASTNode sourceNode = ...
sourceNode.accept(new InfixVisitor());
For my last assignment, I made an Inventory program, using Arrays. Our final assignment is to change the Array to a Linked List. We are not to use the LinkedList class, we are to create our own. I got my program working, but my instructor said it is only okay, but could be better. Mainly, my findItem method, in my InventoryLL class. My question is: is there a better way to go about finding an Item in my Linked List? Any suggestions would be greatly appreciated, I have gotten 100% on each assignment so far, just trying to finishing strong, and learn as much as I can :)
public ItemNode findItem()
{
boolean found = false;
int inputID = 0;
ItemNode current = head;
try{
System.out.print("\nGreetings, please enter the ID number for item:\n");
inputID = scannerObject.nextInt();
scannerObject.nextLine();
while (found != true){
if (current.getID() == inputID){
found = true;
break;
}
current = current.getNext();
}
}catch(Exception e)
{
System.out.println("\nERROR!");
}
return current;
}
The short answer, is that you can't make it more efficient without making it into a (for example) skip list, which is an ordered linked list, that includes a sort of "express path".
Wikipedia has a well written article that explains both the implementation of the list, as well as the searching of it
Though it might be a little bit out of scope.
Well, in your code you're assuming that 'found' will eventually come true; you should be aware that it could not happen. Also, you can change the loop for avoiding using a "break", which is not very smart, altough it is not wrong.
You could too pass the value of inputID through the parameters, so your call to the function will be findItem(0) (or findItem(7) or whatever you like)
public ItemNode findItem(inputID){
boolean found = false;
for (itemNode current = head; !found; current = current.getNext()){
if (current.getID() == inputID){
found = true;
}
}
if (found) {
return current;
}
else{
System.out.println("not found"); //or some other code
}
I have a method that gets two Json nodes that should be Json array nodes of different sizes.
I need to check if ArrayA contains all the elements of ArrayB. How do I do that?
private boolean isContains (JsonNode ArrayA, JsonNode ArrayB) {
if (ArrayA.isArray() && ArrayB.isArray()) {
// Here goes the missing code.
}
}
The JSON Patch reverse part might do what you are looking for.
See: https://github.com/fge/json-patch#json-diff-factorization
Edit:
It is as easy as:
JsonNode diff = JsonDiff.asJson(first, second);
And than you can check whether diff contains removes or adds or both.
There seems to be no inbuilt method I can see, but JsonNode implements Iteratable so you can loop through both and do a compare. Something along the lines of:
boolean matches = true;
for (JsonNode nodeB : arrayB)
{
boolean matchesInternal = false;
for (JsonNode nodeA : arrayA)
{
if (nodeA.equals(nodeB))
{
matchesInternal = true;
break;
}
}
if (!matchesInternal) {
matches = false;
break;
}
}
return matches;
You can use zjsonpatch library, which presents the diff information in accordance with RFC 6902 (JSON Patch). Its very easy to use. Please visit its description page for its usage.
This library is better than fge-json-patch (which was mentioned in above answer) because it can detect correctly items being inserted/removed from arrays.
For those who faced the same problem but prefer more flat code. You can use the Apache Commons's IterableUtils.toList() to convert the ArrayNode#elements() to List and then perform List#containsAll() operation to check whether they contain the same elements. It will look like this:
sourceArray.size() == targetArray.size() && IteratorUtils.toList(sourceArray.elements()).containsAll(IteratorUtils.toList(targetArray.elements()))
I'm trying to create a recall program that sends text messages to 200+ people and then searches an email that the replies are forwarded too.
This method is supposed to search the array list of replies that is built using another method, but it doesn't work correctly. It will only work if the very first message on the array list matches the very first number in the contact list.
Those are some other problems, but my main question here is why does it say that the code specifically inside of my for loop is dead code?
public static boolean searchForPhone(String phone){
CharSequence phoneN = phone;
for(int i=0;i<myMessages.size();i++){
if(myMessages.get(i).contains(phone)){
return true;
}
else{
return false;
}
}
return false;
}
This is your code, properly formatted:
public static boolean searchForPhone(String phone) {
for (int i = 0; i < myMessages.size(); i++) {
if (myMessages.get(i).contains(phone)) {
return true;
} else {
return false;
}
}
return false;
}
The construct flagged as Dead code is the i++ in the for-loop header. It is indeed dead code because the for loop's body unconditionally makes the method return. Therefore the "step" part of the for header is unreachable aka. dead.
The same fact makes your code perform incorrectly, BTW. Removing the else clause would be a big improvement.
Will this help?
public static boolean searchForPhone(String phone){
CharSequence phoneN = phone;
for(int i=0;i<myMessages.size();i++){
if(myMessages.get(i).contains(phone)){
return true;
}
}
return false;
}
Look you are looping over n-element list. When you get first element on the list you got if/else statement.
So you will HAVE TO either of 2 things, both of witch is return. So your program will exit on first element returned.
To make it simplier, your code is equal to:
CharSequence phoneN = phone;
if (myMessages.size() ==0 ){
return false;
}
return myMessages.get(0).contains(phone);
Try from Window > Preferences > Java > Compiler > Error/Warnings
Change Dead code (e.g 'if(false)') and Unnecessary 'else' statement to Error.
Your loop always returns from the function at the end of the first iteration. This makes i++ dead code since it never executes.
Anyway, remove the else clause to fix the code.
In the else part you need to continue to search. Else if your fist element is not the matching one will return false and not going to check other element.
public static boolean searchForPhone(String phone) {
CharSequence phoneN = phone;
for (int i = 0; i < myMessages.size(); i++) {
if (myMessages.get(i).contains(phone)) {
return true;
} else {
//return false this conditional return cause
// the complain it as dead code. Since for loop will become not
//loop
continue; // will search for other elements.
}
}
return false;
}
Now you can simplify this code to following because else part is not really necessary.
public static boolean searchForPhone(String phone) {
CharSequence phoneN = phone;
for (int i = 0; i < myMessages.size(); i++) {
if (myMessages.get(i).contains(phone)) {
return true;
}
}
return false;
}
Please find below my implementation for DFS.
protected void DFS(String search) {
for(Tree<T> child : leafs) {
if(child.value.equals(search))
return;
else
child.DFS(search);
System.out.println(child.value);
}
}
The objective is to stop traversal on finding the node whose value is in the variable search. However, the above function goes on traversing the tree even beyond the declared search node. Could someone help me modify the above function?
Thank you.
Edit 1
protected boolean DFS(String anaphorKey) {
boolean found = false;
for(Tree<T> child : leafs) {
if(child.head.equals(anaphorKey))
return true;
found = child.DFS(anaphorKey);
if(found == true)
break;
System.out.println(child.head);
//System.out.println("anaphorKey: "+anaphorKey);
}
return found;
}
Tried implementing the given answer suggestion (#SJuan76). The implementation above isn't working as desired. Could you point me to the place where code is not as per the logic suggested?
rookie, might I suggest an implementation using the classic for-loop (as opposed to the enhanced for-loop being used now) which allows integration of your stop-condition a bit better, something like:
protected boolean DFS(String key) {
boolean found = false;
for(int i = 0; i < leafs.size() && !found; i++) {
Tree<T> child = leafs.get(i);
if(child.head.equals(key))
found = true;
else
found = child.DFS(key);
}
return found;
}
So as soon as your found condition is hit, the 'found' becomes true and your loop stops.
What you may have forgotten is the "found = child.DFS(key)" portion of the recursion, where you need to remember the result of your recursive calls so ALL your for-loops on up the chain all break as soon as you return.
Hope that helps.
Option A (Nice): the function returns a value, when the node is found it returns a different value that if the node was not found. When you call to method, if you get the found value you stop the loop and return the found value too.
Option B (Ugly): When found, thow an Exception (better if it is your own implementation of it). Don't forget to catch it.
Option C (Uglier): The same with global (static) variables.
UPDATE 1:
It looks like your method should run ok now, can you check (System.out.println) if your value is ever found?
In a more personal opinion, I would find
protected boolean DFS(String anaphorKey) {
for(Tree<T> child : leafs) {
if(child.head.equals(anaphorKey))
return true;
if(child.DFS(anaphorKey)) // No need to store value. No need to check == true (it is implicit)
return true; // If we are in this line the value was found, always return true
System.out.println(child.head);
//System.out.println("anaphorKey: "+anaphorKey);
}
return false; // If the method did not exit previously it was because the value was not found, so in this line always return false
}
more readable (but it should work exactly as your implementation)