Recursive Permutation, Ellis Horowitz Algorithms and data structure Confusion. - c++

I am a beginner programmer in my first year of university. My tutor has asked us to do some research on a recursive algorithm and make it none recursive. No natter how much I try it seems impossible.
The question reads
A is a character string (e.g. A = "hello") and interchange, which is
an abstraction, exchanges the k-th with the i-th character of A,
e.g. CALL interchange("hello", 2, 3) would change "hello" to
"hlelo").
The idea is to print out all the possible permutations
The version in c++ reads
void perm(char*a, const int k, const int n)
{
if(k==n)
{
cout << a;
}
else
{
for (i=k;i<=n;i++)
{
interchange(a, k, i);
perm(a, k+1, n)
}
}
}
My tutor much prefers to use a language called ADL that seems only to appear in the Horowitz book "algorithms and data structures". He has posed the question in ADL so I will add that code in too, its very easy to understand.
proc perm(IN a, IN k, IN n)
if k=n then
print(a)
else
{
for i <- k to n do
call interchange(a,k,i)
call perm( a, k+1, n)
end
}
end
thanks for anyone who can help.
Martyn

A recursive algorithm is simply an algorithm that uses a stack.
The recursion allows you to use the call stack as your data stack.
Any recursive function taking this form:
void perm(char*a, const int k, const int n)
{
// check if your code should return
// make a recursive call with new data
}
Can be changed to this:
void perm(char*a, const int k, const int n)
{
// Create a stack, push (a,k,n)
while ( /* stack isn't empty */ )
{
// check if stack should be *popped* (instead of returning)
// Put new data on the stack (instead of recursing)
}
}

Here's a hint, without doing your homework for you. As you walk down the string, looking at the ith character, you're in one of three possible states:
i == k
i == n
else
What do you print in each of those three cases?

Related

permutation in C++

class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int> > result;
vector<int> sofar;
permutehelper(nums, sofar, result);
return result;
}
void permutehelper(vector<int> &rest, vector<int> &sofar, vector<vector<int>> &ans){
if(rest.size() == 0) {
ans.push_back(sofar);
}
else{
for(int i = 0; i < rest.size(); i++){
sofar.push_back(rest[i]);
rest.erase(rest.begin() + i);
permutehelper(rest, sofar, ans);
}
}
}
};
How do I modify it to return all permutation, Currently it is giving only [[1,2,3]]. I know there are many solutions but I want to make it work using vectors sofar and rest.
You only have one rest vector (and only one sofar vector) because you are passing by reference. That means that when you remove an element from rest, it's gone. You never put it back, so it's gone forever. (In fact, you're removing elements from the vector passed as an argument to permute. Some would say that modifying the argument is poor interface design.)
You probably want to pass the parameter vectors by value (other than ans, which accumulates results and thus should be permanently modified). Of course, passing by value makes copies, which introduces an unnecessary quadratic complexity, but it will allow the algorithm to work as expected.

c++: how to determine if a variable is a vector element

I have a method, which i want to execute differently depending on if the passed variable is an element of a vector or not, like for example:
void method(int a){
if (/*a is an element of a vector*/) //do one thing
else //do another thing
}
and then in main:
vector<int> a;
a.pushback(1);
int b = 1;
method(a[0]); // does one thing
method(b); // does the other thing
What is the simplest way to do that?
Well, for all cases this is impossible, because it actually requires your function to look at how it is executed, and there is no such thing in C++. The hated eval() comes to mind.
But in a certain case, when your vector is a global entity, you could pass your variable by link instead of value. Then, you can check if it fits the space between the start and end of the desired vector. This is how it is done(not tested though, but should work)
vector<int> v;
//fill it somewhere somehow
void method(int& a)
{
int* beg = v.data();
int* end = beg + v.size();
int* val = &a;
if ((val >= beg) && (val < end))
{
//it is a part of vector
}
else
{
//it is not a part of vector
{
}
Problem is that you really shouldn't do it this way... As people in the comments said, it DOES look like an XY problem.
An int is an int. An int does not wear a label around its neck, telling everyone where it came from. When an int is passed to a function, there is nothing that specifies where the int originates.
You should take this as an opportunity to learn about iterators, and implement an overloaded method that takes either an
void method(int);
for a parameter, or a
void method(std::vector<int>::iterator iter);
for a parameter (or, perhaps, a const_iterator), and invoke the alternative method() by passing it an iterator to the int in your vector.

C++ sort long deque

I'm trying to sort first half of a deque deque<data> sortDValues of pairs
struct data {
int dValue;
int index;
};
by the dValue using c++ function with lambda expression
sort(sortDValues.begin(), sortDValues.begin() + partASize - i,
[](data const &a, data const &b) { return a.dValue > b.dValue; });
This approach works well most of time, but in some special cases the final program falls. I've located, that the problem of this is in the sort function, however, I couldn't figure out, why.
I'm not sure, if it can have anything in common with filling this dequeue
deque<data> sortDValues;
for(number n : indices)
{
if(perm[n] >= partASize)
sortDValues.push_back(dValues[n]);
else
sortDValues.push_front(dValues[n]);
}
I can give a specific case of this problem: first number is the index, the second the dValue:
Thank you in advance for answers, I wasn't able to find out, where the problem is.

How to pass an array of members of a struct as a parameter to a function?

Here is my problem:
I have a struct:
struct point
{
int x;
int y;
};
and then I have an array:
for (int i = 0;i < n;i++)
{
arr[i].x=rand() % n + 1;
}
I defined the quicksort function as follows:
void quicksort(int *a, int left, int right);
and I want to sort the point by X coordinate, so I call the quicksort:
quicksort(arr.x, 0, n-1);
And this is the error message:
error: request for member 'x' in 'arr', which is of non-class type 'point [(((unsigned int)(((int)n) + -0x000000001)) + 1)]'
Sorry if the question is too stupid or badly formulated, the truth is I'm a newbie and I'm really willing to learn as much as possible and I'd be very thankful for your help!
If you always want to sort by x, then you can hard-code it into the sort function, and just pass a pointer to the array to sort:
void quicksort(point * arr, int left, int right) {
// test points with
// if (arr[i].x < arr[j].x) {/* i sorts before j */}
}
quicksort(arr, 0, n-1);
To specify a class member to sort by, you need a pointer-to-member, not a pointer; something like:
void quicksort(point * arr, int point::*member, int left, int right){
// test points with
// if (arr[i].*member < arr[j].*member) {/* i sorts before j */}
}
quicksort(arr, &point::x, 0, n-1);
More generically, you could follow the example of std::sort and accept any comparison functor:
template <typename RandIter, typename Compare>
void quicksort(RandIter begin, RandIter end, Compare compare) {
// test points with
// if (compare(*it1, *it2)) {/* *it1 sorts before *it2 */}
}
quicksort(arr, arr+n,
[](point const &lhs, point const &rhs) {return lhs.x < rhs.x;});
And of course, unless you're learning how to implement a sorting algorithm, just use std::sort.
quicksort(arr,0,n-1);
then within quicksort, try to compare the arr[i].x
There are a few problems with your code.
1. quicksort accepts int* but you try to pass int value x
2. You try to pass int but you actually call an undefined variable arr.x
What you need to do is either call in the form of &arr[i].x, but to accomplish what you want, you probably want to pass the entire struct as a pointer.
You need to pass arr as the parameter, as that is the array to be sorted. arr.x is meaningless. You are not passing the string "arr.x" as a parameter which can somehow be interpreted as meaning sort on the x field - when the compiler sees this, it is looking for an x element of arr, which doesn't exist, as the error message suggests - only the elements of arr (e.g. arr[0]) have x elements (accessed as arr[0].x).
Assuming this is for academic purposes (why else would you declare your own sorting algorithm instead of using one of the ones already implemented with a custom comparator?), you can do this a few ways:
Array
std::array<point, 10> myArray; // declares an array of size 10 for points
template<size_t N>
void quicksort(std::array<point, N>& arr, ...)
{
// implement sort operating on arr
}
Vector
std::vector<point> myVector; // declares a dynamic array/vector of points
void quicksort(std::vector<point>& arr, ...)
{
// implement sort operating on arr
}
If for some god-awful reason, you want to keep it in C:
Legacy
const size_t SIZE = 10;
point arr[SIZE]; // declare an array of 10 points
void quicksort(point* p, const size_t n, ...)
{
// implement sort operating on elements in p passing in SIZE for n
}
I'd rather defined the function as:
void quicksort(void *a,int left,int right, size_t size, int (*fp)(void*,void*));
size is the size of one element of array and fp is a compare function which returns true if the two arguments are equal. Now you can pass the call the function as:
quicksort(arr,0,n-1,sizeof(arr)/sizeof(arr[0]), compare);
where function compare is something like:
int compare(void* a, void* b) { return *((int*)a) >= *((int*)b); }
Rest of the implementation of function is trivial I think.
(almost) never try to fool the system by passing a pointer to a member when you really want to pass a pointer to an object. Do as Grijesh suggested. Passing a member can lead to horrible side effects. For example, quicksort is going to sort all the integers together, regardless of which of them are X's and which are Y's. In milder cases you may get wrong compare criteria, and often hard to debug effects such as incorrect pointer optimization. Just be honest with the compiler and pass the object pointer if you need to pass an object pointer. There are very very very few exceptions, mostly to do with low-level system programming where the "other side' of the function call won't be able to handle the object.

C++ vector insertion sort algorithm method - pass vector into method

Ive look everywhere and whatever algorithm I find (if any lol) for insertion sort on a vector in c++, it wont work so im assuming it has something to do with my code. Can anyone help me find a way I can pass a vector into a method as an argument and then do an insertion sort on it? At the moment it waits for a few seconds and shows all the values unsorted :(
Insertion Sort Code
void insertionSort (vector<int> data, int n)
{
int i, j, tmp;
for (i=1; i<n; i++)
{
j=i;
tmp=data[i];
while (j>0 && tmp<data[j-1])
{
data[j]=data[j-1];
j--;
}
data[j]=tmp;
}
The important part of the code
cout << "insertion sort" << endl;
system("pause");
insertionSort(numberVectors, i);
let me know if you dont think theres anything wrong with that code and you want me to show you more, should just be this bit though, the other stuff is irrelavent i think
thanks
Your function accepts its argument by value; this means it gets a copy. You sort the copy, in vain.
Change it to a reference instead:
void insertionSort (vector<int>& data, int n)
Pass your array by reference, then changes in the function will be reflected on it
void insertionSort (vector<int> &data, int n)
{
...
}