I have the following recursive code which I want to change to iterative code. I am unsure of where to begin as the function is very complex with recursive calls at two locations. Any possible iterative implementations to the below function ?
int ncip(int dim, double R){
int n, r = (int)floor(R);
if (dim == 1)
return 1 + 2*r;
n = ncip(dim-1, R); // last coord 0
for (int i=1; i<=r; ++i){
n += 2*ncip(dim-1, sqrt(R*R - i*i) ); // last coord +- i
}
return n;
}
One common approach is to use a stack for the function calls. A simple implementation would be as follows and you can do some optimization on it
int ncip(int dim, double R){
typedef pair<int, double> data; // ties parameters into one unit
stack<data> s;
s.push(make_pair(dim,R)); // push the first set of parameters
int n = 0;
while(false == s.empty()) { // do the loop until stack is depleted
auto item = s.top(); // get the top item and pop it after
s.pop();
int r = static_cast<int>(floor(item.second));
if (item.first == 1) {
n += 1 + 2*r;
} else {
s.push(make_pair(item.first-1,item.second));
for (int i = 1; i <= r; ++i){
// since you have a multiplier 2 we push the same parameters twice
s.push(make_pair(item.first-1, sqrt(item.second*item.second - i*i) ));
s.push(make_pair(item.first-1, sqrt(item.second*item.second - i*i) ));
}
}
}
return n;
}
Related
I need to find the maximum remainder for n divided by any integer number from 1 to n, and the denominator which this remainder is found with.
In my implementation fun1 works as expected and returns the max remainder, fun2 is supposed to give 3 but its giving 2 .probably mistake is at break statement.
Sample input: 5
Expected output: 2 3.
My output: 2 2.
#include <iostream>
#include <algorithm>
using namespace std;
int fun2(int a);
int fun1(int n ,int num);
int main(){
int n = 0; int num = 0;;
cin >> n;
int p = fun1(n, num);
cout << p << "\n";
cout << fun2(p);
}
int fun1(int n, int num){
int b = 0;
for(int i = 1; i <= n; i++){
num = n % i;
b = max(num, b);
}
return b;
}
int fun2(int n,int p ){
int num = 0; int c = 0; int d = 0;
for(int i = 1; i <= n; i++){
num = n % i;
c = max(num, c);
if(c == p){
break;
}
d = i;
}
return d;
}
Since you already managed to successfully find the biggest remainder, you may get use of this function and return the number this remainder is found with:
std::pair<int, int> biggestRemDem(int value) {
int dm = 1;
int rm = 0;
for(int i = dm; i <= value; ++i){
const auto tmpRm = value % i;
if (tmpRm > rm) {
rm = tmpRm;
dm = i;
}
}
return { rm, dm };
}
The signature of the function needs to return std::pair however, but you no longer need the std::max, so the headers required to include are also changed:
#include <iostream>
#include <utility>
std::pair<int, int> biggestRemDem(int value);
int main(){
int n{};
std::cin >> n;
const auto result = biggestRemDem(n);
std::cout << result.first << " " << result.second << std::endl;
}
In fun2 you have:
if(c == p){
break;
}
d = i;
When you found the right index so that c == p the break will exit the loop and d == i; is not execute. Therefore d has the value from the previous loop, i.e. one less than you need.
Apart from that the code really smells:
fun1
should not have a second argument sum.
should remember the index where if found the largest remainder and you would be done
fun2
the maximum remainder is p, no need to max(num, c). Actually drop the c alltogether and just use num == p
n % 1 == 0 and n % n == 0. The loop will always break with i < n. Might as well not have a conditional: for(int i = 1; ; i++)
you need d because at the end of the loop i disappears. Why not pull i out of the loop? int i; for(i = 1; ; i++)
and now you can use a different conditional again
int fun2(int n,int p ){
int i;
for(i = 1; n % i != p; i++) { }
return i;
}
or
int fun2(int n,int p ){
int i = 1;
for(; n % i != p; i++) { }
return i;
}
or
int fun2(int n,int p ){
int i = 1;
while(n % i != p) ++i;
return i;
}
I need to find the maximum remainder for n divided by any integer number from 1 to n, and the denominator which this remainder is found with.
It seems that the asker decided to solve this in two steps. They wrote a function fun1 returning the maximum remainder and a function fun2, which fed with the previously calculated remainder, returns the corresponding dividend.
While not an efficient approach, it could work if implemented correctly, but that's not the case.
Other than some (very) bad naming choices, we can find:
In the original version of the posted code, fun2 has a function prototype with a single parameter and it is called passing the value returned by fun1, which is the maximum remainder. The problem is that this way the function has no way to know what was the original value of n and actually declares a local n, initialized to zero, so that the body of the loop for(int i = 1; i <= n; i++) is never executed.
The actual version of this question shows a definition of fun2 with two parameters, that can't compile unless both the prototype and the call site are changed accordingly.
Assuming that the original n and the remainder p were succesfully passed to fun2, there still would be another issue:
int fun2(int n, int p ) {
int c = 0, d = 0;
for(int i = 1; i <= n; i++) {
int num = n % i;
c = max(num, c);
if(c == p){ // So, if we reach the passed remainder...
break; // We break out of the loop, skipping...
}
d = i; // this line, meaning...
}
return d; // That the dividend previous to the correct one is returned!
}
They could just return i; when c == p.
The answer by The Dreams Wind presents a much better approach to this task. I'd like to suggest an O(1) solution, though. Consider these points:
The result of n % i can't be equal or greater than i. It's in the range [0, i).
n / 2 is the greatest number that can divide n other than n itself. It means that all the numbers i in (n/2, n) are such that n % i > 0.
For every number i in (n/2, n), we can actually say that n % i = n - i.
So, when n is greater than 2, the i corresponding to the maximum remainder is just 1 + n/2 and said remainder is n - n/2 - 1.
I am trying to implement version of Kadane's algorithm which returns subarray. Instead of just returning largest sum I would like to get container.
Based on wiki pseudocode I have prepared simple implementation.
However, I would like to avoid using indexes best_start and best_end.
I can not find a way to fill out vector step by step using push_back.
Could you give me suggestion how should I change logic of this program?
std::vector<int> maxSubArrayWiki(const std::vector<int>& nums) {
std::vector<int> out;
int max_sum = INT_MIN;
int sum = 0;
int i = 0;
int current_start, best_start, best_end = 0;
for(const auto& n : nums){
if(sum <= 0) {
current_start = i;
out = {};
sum = n;
}
else {
sum += n;
}
if(sum > max_sum) {
max_sum = sum;
best_start = current_start;
out.push_back(n);
best_end = i + 1;
}
i++;
}
// is it possible to avoid following? return std::vector<int>(&nums[best_start], &nums[best_end]);
return out;
}
out:
4 2 1
expected:
4 -1 2 1
http://coliru.stacked-crooked.com/a/8d120f8f0ab923a6
How to count comparisons in selectionsort?
terms:
when the statements you perform to find the maximum value is 'true'
then count comparison.
The value to get the maximum value is held at the first element in the array, not at random.
I try with C
variable count position change - no work
new variable 'first' , first=sort[MAX] insert first for loop, - no work
#include <stdio.h>
int main() {
int sort[10000], i, n, MAX, temp, count;
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", &sort[i]);
}
for (MAX = 0; MAX < n; MAX++)
for (i = MAX + 1; i < n; i++) {
if (sort[MAX] > sort[i]) {
count++;
temp = sort[MAX];
sort[MAX] = sort[i];
sort[i] = temp;
}
}
printf("%d ", count);
return 0;
}
Sample Input
10
0 7 1 6 7 7 6 6 5 4
Sample Output
17
EDIT: new code:
#include <stdio.h>
#define SWAP(x, y, temp) ( (temp)=(x), (x)=(y), (y)=(temp) )
int count = 0;
void selection_sort(int list[], int n) {
int i, j, least, temp;
for (i = 0; i < n - 1; i++) {
least = i;
for (j = i + 1; j < n; j++) {
if (list[j] < list[least]) {
least = j;
count++;
}
}
SWAP(list[i], list[least], temp);
}
}
int main() {
int list[10000], i, n;
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", &list[i]);
};
selection_sort(list, n);
printf("%d", count);
}
how about this? why this code didn't move too?
You aren't counting the right thing, this code
if(sort[MAX]>sort[i])
{
count++;
temp=sort[MAX];
sort[MAX]=sort[i];
sort[i]=temp;
}
counts the times that two numbers are swapped. But you want to count comparisons so it should be this
count++;
if(sort[MAX]>sort[i]) // this is what we are counting
{
temp=sort[MAX];
sort[MAX]=sort[i];
sort[i]=temp;
}
Another problem is that you don't give count an initial value of zero
int sort[10000],i,n,MAX,temp,count;
should be
int sort[10000],i,n,MAX,temp,count = 0;
how to count comparison selectionsort?
Your definition of the term is oddly worded, but it seems to be intended to focus on the essential comparisons of the algorithm, as opposed to comparisons performed incidentally for other purposes, or inside library functions. That is, in the implementation you present (whose correctness I do not evaluate), you're to count each evaluation of sort[MAX]>first, but not MAX<n or i<n.
You appear to be using variable count for that purpose, but you are counting only comparisons that evaluate to true. My interpretation of the problem, based both on the wording presented and on my general expectations for such a problem, is that every evaluation of sort[MAX]>first should be counted, regardless of the result. That would be achieved by lifting the expression count++ out of the if block, but leaving it inside the inner enclosing for loop.
Of course, as #john observes, you do need to initialize count to 0 before beginning to sort. You might luck into getting that by accident, but the initial value of a local variables without an initializer is indeterminate (at least) until a value is assigned.
i try with c variable count position change - no work
new variable 'first' , first=sort[MAX] insert first for loop, - no work
Even with the misplacement of your increment to count, if your sort were in fact working then you would expect to see some counts for most inputs. That you don't is a good sign that your sort in fact does not work correctly. I would suggest outputting also the the sorted results so that you can debug the details of the sort algorithm.
You could abstract out the comparison into a function or macro that also increments a counter. The macro approach could be
#define GT(x,y,counter) (counter++, (x) > (y) ? 1 : 0)
...
if ( GT( sort[MAX], sort[i], count ) == 1 )
{
// perform swap
}
whereas the function approach would be
int gt( int x, int y, int *counter )
{
(*counter)++;
if ( x > y )
return 1;
return 0;
}
...
if ( gt( sort[MAX], sort[i], &count ) == 1 )
{
// perform swap
}
You are counting the number of swaps, not the number of comparisons.
Here is a corrected without a global variable and a few extra checks:
#include <stdio.h>
#define SWAP(x, y, temp) ((temp) = (x), (x) = (y), (y) = (temp))
int selection_sort(int list[], int n) {
int count = 0;
int i, j, least, temp;
for (i = 0; i < n - 1; i++) {
least = i;
for (j = i + 1; j < n; j++) {
count++;
if (list[j] < list[least]) {
least = j;
}
}
SWAP(list[i], list[least], temp);
}
return count;
}
int main() {
int list[10000], i, n, count;
if (scanf("%d", &n) != 1 || n > 10000)
return 1;
for (i = 0; i < n; i++) {
if (scanf("%d", &list[i]) != 1)
return 1;
}
count = selection_sort(list, n);
printf("%d\n", count);
return 0;
}
Not however that your algorithm will always perform the same number of comparisons for any set of n values: n * (n - 1) / 2 comparisons, and since you do not test of i != least, it will perform n - 1 swaps.
Im currently looking to turn something like this:
.............
.............
..XXX.....X..
..XXX.....X..
..XXX........
..XXX........
..XXXXXXX....
..XXXXXXX....
..XXXXXXX....
.............
.............
into this:
.............
.............
..XXX.....O..
..XXX.....O..
..XXX........
..XXX........
..XXXXXXX....
..XXXXXXX....
..XXXXXXX....
.............
.............
with the user entering ./a.exe input4.txt floodfill 2 10 o
I believe im going to need to implement some recursion into the program to be able to only look at indexes that match that of the user pointer (including positions of up, down, left, and right) instead of reading the entire vector (which i wouldn't mind doing but dont see how i would begin doing so).
here is the code I have so far for the flood fill function:
void floodfilll(vector<vector<char>> &vec, int x, int y, char r, char dum)
{
int ii;
ii = 0;
int jj;
jj = 0;
for (int i = 0; i < vec.size(); i ++) {
for (int j = 0; j < vec[i].size(); j++) {
if (vec[i][j] == r) {
vec[i][j] == r;
if ((i + ii) > 0) {
if (vec[i-1][j] == r)
vec[i-1][j] = dum;
vec[i][j] == r;
ii--;
floodfilll(vec, x + ii, y, r, dum);
}
if ((j + jj) > 0) {
if(vec[i][j-1] != r)
vec[i][j-1] = dum;
vec[i][j] == r;
jj--;
floodfilll(vec, x, y + jj, r, dum);
}
if ((i + ii)<vec.size()) {
if (vec[i+1][j] != r)
vec[i+1][j] = dum;
vec[i][j] == r;
ii++;
floodfilll(vec, x + ii, y, r, dum);
}
if ((j + jj)<vec[i].size()) {
if (vec[i][j+1] != r)
vec[i][j+1] = dum;
vec[i][j] == r;
jj++;
floodfilll(vec, x, y + jj, r, dum);
}
}
}
replacee(vec, dum, r);
}
}
NOTE: Im using a function called replacee to replace Var dum, with Var R. Var dum is assigned 'i' and r is 'X'.
Also, the text file is parsed as a 2d vector of char's (char)**
Its just the way the rest of my program is based. Here is the replace function:
void replacee(vector<vector<char>> &vec, char oldd, char neww)
{
for (vector<char> &v : vec) // reference to innver vector
{
replace(v.begin(), v.end(), oldd, neww); // standard library algorithm
}
}
This is the int main file im using:
int main(int argc, char* argv[]) {
fstream fin; char ch;
string name (argv[1]); //File Name.
vector<vector<char>> data;
// 2D Vector.
vector<char> temp;
// Temporary vector to be pushed
// into vec, since its a vector of vectors.
fin.open(name.c_str(),ios::in);
// Assume name as an arbitary file.
string argument2 (argv[2]);
while(fin)
{
ch = fin.get();
if(ch!='\n') {
temp.push_back(ch);
}
else
{
data.push_back(temp);
temp.clear();
}
}
if (argument2 == "floodfill") {
string argument3 (argv[3]);
string argument4 (argv[4]);
string argument5 (argv[5]);
int x = 0;
int y = 0;
stringstream xx(argument3);
stringstream yy(argument4);
xx >> x;
yy >> y;
floodfilll(data, x, y, argument5[0], 'i');
for (int m = 0; m < data.size(); m ++) {
for (int n = 0; n < data[m].size(); n++) {
cout << data[m][n];
}
cout << endl;
}
}
fin.close();
}
Sorry if it looks like im just pasting code for grabs, this is incase anyone has a solution outside my mode of thought. The int main and replacee functions work as intended. I just need help coming up with a way to make floodfilll work correctly.
This is the output i get with my code:
$ ./a.exe input4.txt floodfill 2 10 o
.............
.............
..XXX.....X..
..XXX.....X..
..XXX........
..XXX........
..XXXXXXX....
..XXXXXXX....
..XXXXXXX....
.............
Why do you iterate over the whole field in each recursion?
Normally, flood filling works as follows:
You have a specific starting point.
You fill this starting point with the colour intended
You check for each of the four (or 8, if you consider diagonals as well) neighbours, if they have the same colour as the starting point originally had; if so, you continue with recursively.
So an implementation might look like this:
void floodfill
(
std::vector<std::vector<char>>& v,
unsigned int x, unsigned int y, char r
)
{
char p = v[x][y];
v[x][y] = r;
if(x > 0 && v[x - 1][y] == p)
floodfill(v, x - 1, y, r);
if(x + 1 < v.size() && v[x + 1][y] == p)
floodfill(v, x + 1, y, r);
if(y > 0 && v[x][y - 1] == p)
floodfill(v, x, y - 1, r);
if(y + 1 < v[x].size() && v[x][y + 1] == p)
floodfill(v, x, y + 1, r);
}
Note that I did not check for the case of colour to fill being the same as the one of the starting pixel, neither did I initially check the range check of x and y. For efficiency, I wouldn't add these checks in the recursive function, but in a specific entry function starting the recursion, so they are done only once when needed and not needlessly repeated.
One option is to use recursion, as suggested by the other answer. However, personally I prefer avoiding recursion where it is not necessary. An alternative, is a queue-based approach.
void floodfill (std::vector<std::vector<char>>& v, unsigned int x, unsigned int y, char r) {
char init = v[x][y];
if (init == r) return; //We don't want to get caught in an endless loop.
if (x >= v.size() || y >= v[x].size) return; //Index out of bounds.
std::queue<std::pair<unsigned int, unsigned int>> q;
q.push(std::make_pair(x, y)); //Push the initial position into the queue.
v[x][y] = r; //Replace the initial point.
while (!q.empty()) {//Keep looking at relevant neighbours so long as there is something in the queue.
auto pt = q.front(); //Collect the first entry.
q.pop(); //Remove it, we don't want to keep processing the same point.
//Now add neighbours if they match our initial point.
if(pt.first > 0 && v[pt.first - 1][pt.second] == init)
q.push(std::make_pair(pt.first - 1, pt.second);
v[pt.first - 1][pt.second] = r; //Replace the value here to avoid pushing the same point twice.
if(pt.first + 1 < v.size() && v[pt.first + 1][pt.second] == init)
q.push(std::make_pair(pt.first + 1, pt.second);
v[pt.first + 1][pt.second] = r;
if(pt.second > 0 && v[pt.first][pt.second - 1] == init)
q.push(std::make_pair(pt.first, pt.second - 1);
v[pt.first][pt.second - 1] = r;
if(pt.second + 1 < v[pt.first].size() && v[pt.first][pt.second + 1] == init)
q.push(std::make_pair(pt.first, pt.second + 1);
v[pt.first][pt.second + 1] = r;
}
}
This gives you a BFS-like flood-fill pattern without recursion. Alternatively you could also use a stack instead of the queue, then the flood-fill would behave more like a DFS (much more similar to what the recursive pattern will do). It might even perform a little better than the queue, given the data structure is a little simpler.
This program should work correctly but it doesn't! assume you are building a minheap by inserting nmubers into an array. Each time of insertion should be followed by Heapify function to make sure that the sort of numbers do not violate the minheap rule. This is what I wrote but there is something wrong with it and I couldn't make it!
int P(int i) //returning the index of parent
{
if (i % 2 == 0) { i = ((i - 2) / 2); }
else { i = ((i - 1) / 2); }
return i;
}
void Heapify(double A[], int i)//putting the smallest value in the root because we have a min heap
{
if (P(i) != NULL && A[i] < A[P(i)])
{
temp = A[P(i)];
A[P(i)] = A[i];
A[i] = temp;
Heapify(A, P(i));
}
}
Generally speaking, your heapify function doesn't seem to take a minimum of both left and right branches into consideration. Let me show you an ideal, working implementation (object-oriented, so you might want to pass the heap as a parameter). You can find the exact pseudocode all over the internet, so I'm not really presenting anything unique.
void Heap::Heapify (int i)
{
int l = left(i);
int r = right(i);
int lowest;
if (l < heap_size && heap[l] -> value < heap[i] -> value )
lowest = l;
else
lowest = i;
if (r < heap_size && heap[r] -> value < heap[lowest] -> value)
lowest = r;
if (lowest != i)
{
swap (heap[i], heap[lowest]);
Heapify(lowest);
}
}
where
int left ( int i ) { return 2 * i; }
int right ( int i ) { return 2 * i + 1; }
As you can see, an algorithm first checks which one of left and right children have lower value. That value is swapped with current value. That is everything there is to it.