I'll be honest, I am not sure of the terms I used in the title.
Basically I was curious to know the difference between something like:
class MyRecursiveClass
{
public:
int myData;
MyRecursiveClass* nextInLine;
int myRecursiveFunction(int data)
{
data+=myData;
if(nextInLine == null)
return data;
else
return nextInLine->myRecursiveFunction(data);
}
}
and
int staticRecursiveFunction(MyRecursiveClass* target, int currentData)
{
if(target == null)
return currentData;
currentData+=target->myData;
staticRecursiveFunction(target->nextInLine, currentData);
}
or
int otherStaticRecursiveFunction(MyRecursiveClass* target)
{
if(target == null)
return 0;
return target->myData + otherStaticRecursiveFunction(target->nextInLine);
}
Basically what I want is the differences in overhead, as well as better terms for the difference between the two methodologies (I was at a loss when I tried to Google)
Also, any personal opinions and or preferences. I was taught recursion more as a tool to get a job done, and would like to hear professional(and amateur) opinions.
Also good readings on recursive structures/methodologies would be appreciated, though that is not the purpose of this site(more so I don't keep asking potentially dumb questions)
I don't see any difference between the two except that in one case you are calling a static method, and in the other an instance method.
As far as recursion as a technique goes, this makes no difference. This seems to be more about using object-oriented versus procedural programming (and recursion is equally applicable to both).
As for call overhead, calling an instance/virtual method is probably a bit slower on most systems because of the dispatch that has to take place, but that cannot be significant in the grand scheme of things. (If the cost for method calls is a concern, you may want to move away from recursions completely and unwind it into a loop).
Related
Imagine a part of your state machine looks like this:
How do you properly implement the choice part in Qt? I know there are guarded transitions, but that would mean that I need to:
Create a subclass of a QAbstractTransition which accepts e.g. an std::function<bool()> and a flag which determines if the transition happens when that boolean result is true, or when it is false
Create two instances of this class with the same boolean function, but opposite transition guards
Add two transitions from S1 using these two instances.
That approach seems kind of clumsy and error prone for something as simple as a choice.
Is there a more maintainable approach to implement this?
License Notice:
Alternatively to the default StackOverflow license you are hereby allowed to use this code through the MIT License.
I've created a BooleanChoiceTransition class with a constructor like this (might contain errors, the code is not on this machine, so I typed it by heart):
BooleanChoiceTransition::BooleanChoiceTransition(std::function<bool()> choiceFunc, QState* targetForTrueCase, QState* targetForFalseCase)
: QState{}
{
this->addTransition(this, &BooleanChoiceTransition::transitionToTrueTarget, targetForTrueCase);
this->addTransition(this, &BooleanChoiceTransition::transitionToFalseTarget, targetForFalseCase);
(void)QObject::connect(this, &QAbstractState::entered, [this]() {
if(choiceFunc())
{
emit transitionToTrueTarget();
}
else
{
emit transitionToFalseTarget();
}
});
}
with transitionToTrueTarget and transitionToFalseTarget being signals of course.
For the case of the example in the question, the class can be used like so:
auto choiceState = new BooleanChoiceTransition([this](){ return _someConditionFullfilled; }, s2, s3);
s1->addTransition(this, &MyClass::someTrigger, choiceState);
Since BooleanChoiceTransition is a QState, this can even be nested easily:
auto outerChoiceState = new BooleanChoiceTransition([this](){ return _someOtherConditionFullfilled; }, s4, choiceState);
We've one photo sharing application and I'm using tinkerpop 3.4.3 java library and AWS Neptune graph. In our application, we're already using .flatMap() step to chain the traversals from the other methods. Our current code looks like this.
public boolean isViewable(String photoId, String userId) {
return graph.V(photoId).hasLabel("photo")
.flatMap(getDirection(userId))
.otherV().hasId(userId).hasNext();
}
Based on the userId, we retrieve the correct direction/relation information from the other systems and use it here for the result.
Unfortunately we're facing marginal performance issue when using the .flatMap() step when the number of edges of the photoId are high (100K edges).
...flatMap(inE()).otherV().profile() results in ~5000 milli seconds but the same query without .flatMap results in less than 200 milli seconds.
To avoid this, we've modified our current code like the below.
public boolean isViewable(String photoId, String userId) {
GraphTraversal<Vertex, Vertex> traversal = graph.V(photoId).hasLabel("photo");
applyDirection(traversal, userId);
traversal.otherV().hasId(userId).hasNext();
}
private void applyDirection(GraphTraversal<Vertex, Vertex> traversal, String userId) {
if(condition) {
traversal.inE();
} else {
traversal.outE();
}
}
But code looks complex without the chaining. Is there any other steps are available to chain the traversals ?
I don't think your code without the chaining is all that complex or hard to read. It's quite common to take that approach when dynamically building a traversal. If you really dislike it you could build a DSL to make a custom step to encapsulate that logic:
graph.V(photoId).hasLabel("photo")
.eitherInOrOut(userId)
.otherV().hasId(userId).hasNext();
If your logic is truly that simple for determining the Direction you could also use the little known to() step:
graph.V(photoId).hasLabel("photo")
.toE(getDirection(userId))
.otherV().hasId(userId).hasNext();
so I have been working on a programming assignment that involves taking a stack implementation of size ~13,000 and turning it into a linked list. The guide is basically that the stack was filled by sequentially scanning a linked list (IE tail would be the top of the stack), and you want to re create the linked list using the stack. The trick is you have to do it using a recursive method. The only methods in this stack class are pop (returns and removes the top element), and isEmpty(tells if the stack is empty). I have code that gets the job done, however it requires increasing the java stack size (otherwise I get StackOverflowError), which I feel like that isn't allowed.
That being said does anyone know a way I could possibly get this to work without increasing the java stack size.
The stack is a static field I have labeled S. Head is what should be the first node in the linked list, and steper is simply a node to be used to create every other step.
Here is the code I currently have:
public static void stackToList()
{
int x = 0;
if(S.isEmpty())
{
return;
}
x = S.pop();
stackToList();
if (head == null)
{
head = new ListNode(x, null);
steper = head;
}
else
{
steper.next = new ListNode(x, null);
steper = steper.next;
}
}
Thank you ahead of time for any help.
It is happening because you are keeping an entire list of function calls in memory stack. You start creating your linked list only after you reach to the bottom of the stack thus keeping all the previous calls to stackList waiting to be over.
You need to start creating your linked list with the first pop of stack.
A simple & non tested (not worked in Java in a very long time now) function may look like:
public static ListNode stackToList(ListNode head) {
if(S.isEmpty())
return head;
int stackValue = S.pop();
ListNode node = ListNode(stackValue, null);
node.next(head);
return stackToList(node);
}
And you call it like:
ListNode head = stackToList(null)
HTH
EDIT: Now that I posted it, I realized that my code has potentially the same issue as yours, because I remembered Java doesn't support tail-call optimization.
It's not entirely clear from your question if you're using java.util.LinkedList and java.util.Stack but since you didn't provide the code for these objects I will be using those in my example solution below:
public static void main(String[] args) {
//Create a stack
Stack<Integer> stack = new Stack<Integer>();
stack.push(0);
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
stack.push(6);
stack.push(7);
stack.push(8);
stack.push(9);
//Create a list to hold your stack elements
LinkedList<Integer> linkedList = new LinkedList<Integer>();
//Call the conversion method, which modifies both the stack and the list
convertStackToLinkedList(stack, linkedList);
//print the results
System.out.println("linkedList: "+linkedList);
}
public static void convertStackToLinkedList(Stack<Integer> stack, LinkedList<Integer> linkedList){
int topStackElement = stack.pop();
linkedList.add(0,topStackElement);
if(!stack.isEmpty())
convertStackToLinkedList(stack, linkedList);
}
I suspect you may not be using java.util.LinkedList since your code is attempting to modify the internals of the list. So, you would simply need to implement a method similar to that of the add(int index, E element) method in the java.util.LinkedList class and then use it in your recursion. I assume you can do this if you have access to the internals of the list.
EDIT:
I forgot to mention that I agree with the answer by Harsh Gupta in that the reason you're seeing StackOverflowError is that you're waiting until you reach the end of your recursion to modify your list. In some recursion you have to wait until the end but if you don't have to wait don't do it.
I have a situation, where I have existing code that works with raw pointers, and I'm not permitted to smart-pointer-ify it. However, I am permitted to use smart pointers in any new code I develop.
For example.
I have an existing function like:
void processContent()
{
ContentObject * myContent = new ContentObject();
newFunction(myContent);
}
void newFunction(ContentObject * content)
{
// myVector is just a std::vector<ContentObject*>, defined elsewhere
myVector.push_back(content);
}
void doSomethingWithContent()
{
// There is some logic here, but ultimately based on this logic I want to remove entries, and free the memory they point to.
myVector.pop_back();
}
I have control over the content of "newFunction" and "doSomethingWithContent". But the argument passed into newFunction is fixed. Obviously I could manually delete the pointer in myVetor, before popping it, but I wondered if I can implement smart pointers here so that it happens "automatically" for me?
Can I take a raw pointer passed into a function, and turn it into a unique_ptr, then add this to a container, and have it delete the memory when it's popped from the container?
Thanks
Joey
Assume that you can define your myVector as the following:
std::vector<std::shared_ptr<ContentObject>> myVector;
In that case you can switch on smart pointers in your code and myVector will keep all your objects as you expected:
void newFunction(ContentObject * content)
{
myVector.push_back(std::shared_ptr<ContentObject>(content));
}
void doSomethingWithContent()
{
// There is some logic here, but ultimately based on this logic I want to remove entries, and free the memory they point to.
myVector.pop_back();
}
I have some problem with the collection.sort() method.
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:747)
at java.util.TimSort.mergeAt(TimSort.java:483)
at java.util.TimSort.mergeCollapse(TimSort.java:410)
at java.util.TimSort.sort(TimSort.java:214)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)
this is my comparator
public int compare(Key key1, Key key2)
{
if (key1.Score > key2.Score)
return -1;
else if(key1.Score < key2.Score)
return 1;
else
return 0;
}
I am currently jdk 1.7, i tried with 1.6 also but it did not work. I am not able to understand whether it is the problem with sort method or some other issue.( I am trying to sort a list with more than 1000 items and it does not have any NaNs).
Violating the general contract of a comparison method means that it does not provide a consistent or correct answer. It seems this method does not return the same result while comparing the same objects for several times.
This code works fine as a standalone version. Do you have some other threads modifying the collection items?