How to undo changes made by a function? - c++

If I have array int a[n], and I have a function which has this array as its argument. This function takes the array, does some changes in the array, and then returns a boolean value. All I want to do is undo the changes done by the function if the returned value is false (return the array as it was). How can I achieve this?

You can do this however you want. There is no "one right way". It depends on the specifics of your situation. Here are a few possibilities:
Keep a copy of the array and revert to the copy if you need to "undo" the function.
Write a version of the function that goes in reverse and call that version if you want need to "undo" the function.
Have the function keep track of the previous values of any array entry it modifies so you can apply that tracking to revert the function.
Don't have the function actually modify the array but instead have it create a set of modifications. Only modify the array if you decide that's what you want to do.
I highly recommend option 4. You can have a "modified array" class that provides precisely the same API as the array that also includes a reference to the real array. It can have an apply member to change the real array. That way, you can just throw away the instance of the "modified array" class if you don't want to keep the changes.
Since the modified array class provides the array API, it can also modify another instance of the modified array class. This provides as many layers of nesting as you may need.

You have to backup the input array into a local array inside of the function (Before doing changes to input array). There after write the function logic. Finally check the value which is going to return by the function. If it is false then copy the backup array data in to input array.

Related

Reference counting in a collection

Let's have a collection of objects (say string is type of collection). I want each element of collection to have a reference count. So, on Add-Usage it should increment count for this given element.
coll.AddUsage("SomeElement"); // Type doesn't matter - but should increase count
On, Release-Usage, it should decrement the reference count for given element, and if count reaches 0, then it should remove the element from collection.
It is not important if AddUsage will allocate element (and set reference-count to 1), or would fail altogether (since element didn't exist). Important thing is RemoveUsage, which should remove given element (object) from collection.
I thought of using vector of a pair (or a custom struct), or using any kind of map/multimap. There exists no existing class in C++ library (may be out of thread-support library, one atomic classes, shared-pointer classes etc).
Question:
So, my question is how to implement such idea, using existing C++ library? It should be thread safe. Yes, C++11/14 is perfectly okay for me. If good idea is there, I would probably craft it on top of templates.
Assuming you ask for a data structure to implement your reference-counting collection...
Use a map<K,V> with K as the type of collection elements (in your example string) and V a type to keep track of meta-information about the element (e.g. reference count). The simplest case is when V is int.
Then, AddUsage is simple, just do refMap[value]++. For RemoveUsage just do a refMap[value]--, then check if the counter hit zero and remove the value from the map.
You need to add error handling too, since AddUsage / RemoveUsage may be
called with an object which is not in the map (not added to the collection)
EDIT: You tagged your question with "multithreading", so you probably want to have a mutex of some sort which guards the concurrent access to refMap.
You could implement something similar to shared_ptr class but extending it to hold collection of objects.
Like you could design a class with map/multimap as its data member. Key would be your object and value be your reference count.As far as interface is concerned just expose two methods:-
AddUsage(Object);
RemoveUsage(Object);
In your AddUsage method you would first check if element already exists in map.If yes then only increment the count. Likewise you would handle RemoveUsage.Object would be deleted from map if its reference count reaches zero.
This is just my opinion. Please let me know if there are any bottlenecks in this implementation.
You can use static member(integer) variable in the structure or class. Increment or decrement whereever you want. Remove the element if the value is zero.

choose array to act on in function without a version of function for each copy of array

I am trying to apply a minimax type algorithm to a Reversi/Othello type game - the problem i'm finding is that each 1/2 ply will needs its' own "fake" game-board to test on.
Thus it appears, as arrays cannot be passed as parameters, that I either need a function with 64 parameters and an array for each 1/2 ply, or I need to hand code copies of the functions and arrays for each ply (i.e. checkMovePly1, checkMovePly2, etc.), or create the arrays locally (at which point the AI taking a move will result in the generation and creation of 64^(2*ply) arrays every turn, which seems like it could run somewhat slowly).
If I can solve the array problem, this seems like it should work for a few ply, as it will only be a time complexity of O(64^(2*ply)), though depending on method that may be 64^(2*ply) creations and destructions of arrays.
Any idea how to get around the multiple array issue, is this a reasonable approach?
C++ provides various containers that should be preferred to arrays. In this case, I would suggest an std::array. If you don't have std::array, an std::vector will also work.
void foobar(std::array<int, 64> board);
This function will copy the array passed in by value.
First arrays can be passed as parameters, but the function called will be operating directly on the original array, not its own copy (beware).
void foo(int[8][8] board);
Second, standard (or custom if need be) container classes are safer to use and easier to copy when needed. Native arrays don't copy easily without slightly hackish tricks, at which point using container classes should render your code easier to read anyway.
Third, this problem looks like a classic subject for a recursive algorithm, which could allow all work to be done on the same array (or container class) instance, thus keeping your resource requirements O(1): fixed gameboad size and known maximum resursion depth.

FastRemoveObject in CCArray will change the positions of objects?

I was told that if relying on a specific ordering of objects, I should not use the fastRemoveObject methods in CCArray. Cocos2d API references don't show the contents of the method specifically. Can anyone tell me the reason?
Yes, fastRemoveObject changes the order of nodes. It is therefore not recommended unless it really doesn't matter in your case.
What it does is the following:
assign object at last index to index of object being removed
nil last object
decrease array count
That way the array will not have to perform memory operations (hence: fast). But the last object will now be at the index of the removed object.

Could the S of S.O.L.I.D be extended for every single element of the code?

The S of the famous Object Oriented Programming design stands for:
Single responsibility principle, the notion that an object should have
only a single responsibility.
I was wondering, can this principle, be extended even to arrays, variables, and all the elements of a program?
For example, let's say we have:
int A[100];
And we use it to store the result of a function, but somehow we use the same A[100] to check, for example, what indexes of A have we already checked and elaborated.
Could this be considered wrong? Shouldn't we create another element to store, for example, the indexes that we have already checked? Isn't this an hint of future messy code?
PS: I'm sorry if my question is not comprehensible but English is not my primary language. If you have any problem understanding the point of it please let me know in a comment below.
If same A instance is used in different program code portions you must follow this principle. If A is a auxiliary variable, local one for example, I think you don't need to be care about it.
If you are tracking the use of bits of the array that have been updated, then you probably shouldn't be using an array, but a map instead.
In any case, if you need that sort of extra control over the array, then basically, you should be considering a class that contains both the contents of the array and the various information about what has and hasn't been done. So your array becomes local to the class object, as do your controls, and voila. You have single responsibility again.

Why does arrayAppend return true and listAppend return the list?

In ColdFusion, the arrayAppend() function takes an array and an item to be appended. It modifies the array that was passed in and returns true if successful.
The listAppend() function, however, takes a list and an item to be appended, and returns a new list with the item appended. It doesn't modify the list that was passed in.
Why do these functions operate in two different ways? I'm always turning to the documentation to remember the return value of each.
This is because there is no "List" data type in ColdFusion.
A "List" is a delimited string, simple as that. It is comma-delimited by default, but you can choose the delimiter. "ListAppend()" is a string concatenation operation, and as such it returns the result of its work just like "string1 & string2" would.
The only thing that "ListAppend()" does for you is: It takes care of the delimiter handling, preventing needless double delimiters - something that "string1 & string2" cannot do.
An array is a real data type and (in contrast to a string) can be modified in-place. This is what ArrayAppend() does.
To understand why this happens you need to know a little bit about how Strings work in Java because the underlying implementation of a list in ColdFusion is a java.lang.String.
<cfset list = "a,b,c"/>
<cfoutput>#list.getClass()#</cfoutput>
In Java, Strings are immutable and have no methods to modify the contents of a String. If you did the following in Java, you would be creating a new instance of a String and assigning it to s for each statement:
String s = "abc";
s = "def";
s = s.concat("ghi");
Using the listAppend() method in ColdFusion is creating a new instance of a String under the hood and returning it, thus the need to do something like this whenever you append values to a list.
<cfset list = "a,b,c"/>
<cfset list = listAppend(list,'d')/>
<cfoutput>#list#</cfoutput>
However, when you modify an array with arrayAppend(), you are directly modifying the array, thus there is no need to reassign the value to itself again like you need to with listAppend().
Also note that, even though all of the built-in array functions modify the array in-place, for user-defined functions, arrays are passed by value! This means that you cannot write a UDF that modifies an array in-place. (Unless you wrap the array in an object that is passed by reference, such as a struct or a CFC.)
The upshot of this is that if you write your own array utility functions, you often have to end up calling them like this:
<cfset MyArray = DoSomethingWithArray(MyArray)>
ListAppend is essentially a string manipulation function that appends the element to the end of the list, and then returns the new list. In order to perform string manipulations that change the size of a string, you can't just append that data in memory. What if the next location in memory contains other important data? Instead, the system has to allocate a block of data equal (or greater) to the size of the new string. This block is in a new location, so the reference needs to be returned so the caller has access to the new data.
With arrayAppend, the size of the array is constant and doesn't change, so no new reference needs to be created.