Multi dimentionnal for loop - c

Is there a simple way to convert this
for (int i=0; i < 31; i++)
for (int j=0; j < 74; j++)
for (int k=1; k < 12; k++)
for (int l=13; l < 15; l++)
...
To a simpler this
mfor (int start[]={0,0,1,13}; int max[]={31,74,12,15}) {
printf("%i %i\n", start[1], start[3]);
}
Is there a macro or a plugin-like ?
This loop can iterate thought Tensor (like an image) to do stuff like Tensor Convolution or Pooling. In any dimentions (can be more than 4)
Or how to add some syntax to C. I have the implementation for mfor loop. Because for loop is in real a while loop.

There's no simple way, but you could implement an iterator-like type that generates the Cartesian product over n given ranges:
enum {
MAX = 8
};
typedef struct Combinator Combinator;
struct Combinator {
size_t index; // running index of generated numbers
size_t n; // number of dimensions
int data[MAX]; // current combination
int start[MAX]; // lower and ...
int end[MAX]; // .. exclusive upper limits
};
/*
* Adds a dimensin with valid range [start, end) to the combinator
*/
void combo_add(Combinator *c, int start, int end)
{
if (c->n < MAX && start < end) {
c->data[c->n] = start;
c->start[c->n] = start;
c->end[c->n] = end;
c->n++;
}
}
/*
* Reset the combinator to the lower limits
*/
void combo_reset(Combinator *c)
{
c->index = 0;
memcpy(c->data, c->start, sizeof(c->start));
}
/*
* Get the next comnination in c->data. Returns 1 if there
* is a next combination, 0 otherwise.
*/
int combo_next(Combinator *c)
{
size_t i = 0;
if (c->index++ == 0) return 1;
do {
c->data[i]++;
if(c->data[i] < c->end[i]) return 1;
c->data[i] = c->start[i];
i++;
} while (i < c->n);
return 0;
}
This implements an odometer-like counter: It increments the first counter. If it overflows, it resets it and increments the next counter, moving to te next counter as needed. If the last counter overflows, the generation of combinations stops. (There's a bit of a kludge with the index for the first combination so that you can control everything from the loop condition of a while loop. There's probably a more elegant way to solve this.)
Use the combinator like this:
Combinator combo = {0}; // Must initialize with zero
combo_add(&combo, 0, 3);
combo_add(&combo, 10, 12);
combo_add(&combo, 4, 7);
while (combo_next(&combo)) {
printf("%4zu: [%d, %d, %d]\n", combo.index,
combo.data[0], combo.data[1], combo.data[2]);
}
This combiinator is designed to use only once: Create it, set up the ranges, then exhaust the combinations.
If you break out of the loop, the combinator retains its state, so that further call to combo_next continue where you broke off. You can start afresh by calling combo_reset. (This is a bit like reading from a file: The usual way to use them is to read everything, but you can rewind.)

Related

Find the most frequent elements in an array of Integers

I have to find all of the elements which have the maximum frequency. For example, if array a={1,2,3,1,2,4}, I have to print as 1, also 2. My code prints only 2. How to print the second one?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define n 6
int main(){
int a[n]={1,2,3,1,2,4};
int counter=0,mostFreq=-1,maxcnt=0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(a[i]==a[j]){
counter++;
}
}
if(counter>maxcnt){
maxcnt=counter;
mostFreq=a[i];
}
}
printf("The most frequent element is: %d",mostFreq);
}
How to print the second one?
The goal it not only to print a potential 2nd one, but all the all of the elements which have the maximum frequency.
OP already has code that determines the maximum frequency. Let us build on that. Save it as int target = mostFreq;.
Instead of printing mostFreq, a simple (still O(n*n)) approach would perform the same 2-nested for() loops again. Replace this 2nd:
if(counter>maxcnt){
maxcnt=counter;
mostFreq=a[i];
}
With:
if(counter == target){
; // TBD code: print the a[i] and counter.
}
For large n, a more efficient approach would sort a[] (research qsort()). Then walk the sorted a[] twice, first time finding the maximum frequency and the 2nd time printing values that match this frequency.
This is O(n* log n) in time and O(n) in memory (if a copy of the original array needed to preserve the original). If also works well with negative values or if we change the type of a[] from int to long long, double, etc.
The standard student solution to such problems would be this:
Make a second array called frequency, of the same size as the maximum value occurring in your data.
Init this array to zero.
Each time you encounter a value in the data, use that value as an index to access the frequency array, then increment the corresponding frequency by 1. For example freq[value]++;.
When done, search through the frequency array for the largest number(s). Optionally, you could sort it.
We can (potentially) save some effort in an approach with unsorted data by creating an array of boolean flags to determine whether we need to count an element at all.
For the array {1, 2, 3, 1, 2, 4} we do have nested for loops, so O(n) complexity, but we can avoid the inner loop entirely for repeated numbers.
#include <stdio.h>
#include <stdbool.h>
int main(void) {
int arr[] = {1, 2, 3, 1, 2, 4};
size_t arr_size = sizeof(arr) / sizeof(*arr);
bool checked[arr_size];
for (size_t i = 0; i < arr_size; i++) checked[i] = false;
unsigned int counts[arr_size];
for (size_t i = 0; i < arr_size; i++) counts[i] = 0;
for (size_t i = 0; i < arr_size; i++) {
if (!checked[i]) {
checked[i] = true;
counts[i]++;
for (size_t j = i+1; j < arr_size; j++) {
if (arr[i] == arr[j]) {
checked[j] = true;
counts[i]++;
}
}
}
}
unsigned int max = 0;
for (size_t i = 0; i < arr_size; i++) {
if (counts[i] > max) max = counts[i];
}
for (size_t i = 0; i < arr_size; i++) {
if (counts[i] == max)
printf("%d\n", arr[i]);
}
return 0;
}

Efficiently print every x iterations in for loop

I am writing a program in which a certain for-loop gets iterated over many many times.
One single iteration doesn't take to long but since the program iterates the loop so often it takes quite some time to compute.
In an effort to get more information on the progress of the program without slowing it down to much I would like to print the progress every xth step.
Is there a different way to do this, than a conditional with a modulo like so:
for(int i = 0; i < some_large_number; i++){
if(i % x == 0)
printf("%f%%\r", percent);
//some other code
.
.
.
}
?
Thanks is advance
This code:
for(int i = 0; i < some_large_number; i++){
if(i % x == 0)
printf("%f%%\r", percent);
//some other code
.
.
.
}
can be restructured as:
/* Partition the execution into blocks of x iterations, possibly including a
final fragmentary block. The expression (some_large_number+(x-1))/x
calculates some_large_number/x with any fraction rounded up.
*/
for (int block = 0, i = 0; block < (some_large_number+(x-1))/x; ++block)
{
printf("%f%%\r", percent);
// Set limit to the lesser of the end of the current block or some_large_number.
int limit = (block+1) * x;
if (some_large_number < limit) limit = some_large_number;
// Iterate the original code.
for (; i < limit; ++i)
{
//some other code
}
}
With the following caveats and properties:
The inner loop has no more work than the original loop (it has no extra variable to count or test) and has the i % x == 0 test completely removed. This is optimal for the inner loop in the sense it reduces the nominal amount of work as much as possible, although real-world hardware sometimes has finicky behaviors that can result in more compute time for less actual work.
New identifiers block and limit are introduced but can be changed to avoid any conflicts with uses in the original code.
Other than the above, the inner loop operates identically to the original code: It sees the same values of i in the same order as the original code, so no changes are needed in that code.
some_large_number+(x-1) could overflow int.
I would do it like this:
int j = x;
for (int i = 0; i < some_large_number; i++){
if(--j == 0) {
printf("%f%%\r", percent);
j = x;
}
//some other code
.
.
.
}
Divide the some_large_number by x. Now loop for x times and nest it with the new integer and then print the percent. I meant this:
int temp = some_large_number/x;
for (int i = 0; i < x; i++){
for (int j = 0; j < temp; j++){
//some code
}
printf("%f%%\r", percent);
}
The fastest approach regarding your performance concern would be to use a nested loop:
unsigned int x = 6;
unsigned int segments = some_large_number / x;
unsigned int y;
for ( unsigned int i = 0; i < segments; i++ ) {
printf("%f%%\r", percent);
for ( unsigned int j = 0; j < x; j++ ) {
/* some code here */
}
}
// If some_large_number can´t be divided evenly through `x`:
if (( y = (some_large_number % x)) != 0 )
{
for ( unsigned int i = 0; i < y; i++ ) {
/* same code as inside of the former inner loop. */
}
}
Another example would be to use a different counting variable for the check to execute the print process by comparing that to x - 1 and reset the variable to -1 if it matches:
unsigned int x = 6;
unsigned int some_large_number = 100000000;
for ( unsigned int i = 0, int j = 0; i < some_large_number; i++, j++ ) {
if(j == (x - 1))
{
printf("%f%%\r", percent);
j = -1;
}
/* some code here */
}

How to replace a recursive function to using stack or iteration?

I have a recursive function that I wrote in C that looks like this:
void findSolutions(int** B, int n, int i) {
if (i > n) {
printBoard(B, n);
} else {
for (int x = 1; x <= n; x++) {
if (B[i][x] == 0) {
placeQueen(B, n, i, x);
findSolutions(B, n, i + 1);
removeQueen(B, n, i, x);
}
}
}
}
The initial call is (size is an integer given by user and B is a 2D array):
findSolutions(B, size, 1);
I tried to convert it into a iteration function but there is another function called removeQueen after findSolutions. I got stuck on where to put this function call. How to solve this problem? Stack is also fine but I'm also having trouble doing that.
I'm going to assume that placeQueen(B, n, i, x) makes a change to B and that removeQueen(B, n, i, x) undoes that change.
This answer shows how to approach the problem generically. It doesn't modify the algorithm like Aconcagua has.
Let's start by defining a state structure.
typedef struct {
int **B;
int n;
int i;
} State;
The original code is equivalent to the following:
void _findSolutions(State *state) {
if (state->i >= state->n) {
printBoard(state->B, state->n);
} else {
for (int x = 1; x <= state->n; ++x) {
if (state->B[state->i][x] == 0) {
State *state2 = State_clone(state); // Deep clone.
placeQueen(state2);
++state2->i;
findSolutions(state2);
}
}
}
State_free(state); // Frees the board too.
}
void findSolutions(int** B, int n, int i) {
State *state = State_new(B, n, i); // Deep clones B.
_findSolutions(state);
}
Now, we're in position to eliminate the recursion.
void _findSolutions(State *state) {
StateStack *S = StateStack_new();
do {
if (state->i >= state->n) {
printBoard(state->B, state->n);
} else {
for (int x = state->n; x>=1; --x) { // Reversed the loop to maintain order.
if (state->B[state->i][x] == 0) {
State *state2 = State_clone(state); // Deep clone.
placeQueen(state2);
++state2->i;
StateStack_push(S, state2);
}
}
}
State_free(state); // Frees the board too.
} while (StateStack_pop(&state));
StateStack_free(S);
}
void findSolutions(int** B, int n, int i) {
State *state = State_new(B, n, i); // Deep clones B.
_findSolutions(state);
}
We can eliminate the helper we no longer need.
void findSolutions(int** B, int n, int i) {
StateStack *S = StateStack_new();
State *state = State_new(B, n, i); // Deep clones B.
do {
if (state->i >= state->n) {
printBoard(state->B, state->n);
} else {
for (int x = state->n; x>=1; --x) { // Reversed the loop to maintain order.
if (state->B[state->i][x] == 0) {
State *state2 = State_clone(state); // Deep clone.
placeQueen(state2);
++state2->i;
StateStack_push(S, state2);
}
}
}
State_free(state); // Frees the board too.
} while (StateStack_pop(S, &state));
StateStack_free(S);
}
Functions you need to implement:
StateStack *StateStack_new(void)
void StateStack_free(StateStack *S)
void StateStack_push(StateStack *S, State *state)
int StateStack_pop(StateStack *S, State **p)
State *State_new(int **B, int n, int i) (Note: Clones B)
State *State_clone(const State *state) (Note: Clones state->B)
void State_free(State *state) (Note: Frees state->B)
Structures you need to implement:
StateStack
Tip:
It would be best if you replaced
int **B = malloc((n+1)*sizeof(int*));
for (int i=1; i<=n; ++i)
B[i] = calloc(n+1, sizeof(int));
...
for (int x = 1; x <= n; ++x)
...
B[i][x]
with
char *B = calloc(n*n, 1);
...
for (int x = 0; x < n; ++x)
...
B[(i-1)*n+(x-1)]
What you get by the recursive call is that you get stored the location of the queen in current row before you advance to next row. You will have to re-produce this in the non-recursive version of your function.
You might use another array storing these positions:
unsigned int* positions = calloc(n + 1, sizeof(unsigned int));
// need to initialise all positions to 1 yet:
for(unsigned int i = 1; i <= n; ++i)
{
positions[i] = 1;
}
I reserved a dummy element so that we can use the same indices...
You can now count up last position from 1 to n, and when reaching n there, you increment next position, restarting with current from 1 – just the same way as you increment numbers in decimal, hexadecimal or octal system: 1999 + 1 = 2000 (zero based in this case...).
for(;;)
{
for(unsigned int i = 1; i <= n; ++i)
{
placeQueen(B, n, i, positions[i]);
}
printBoard(B, n);
for(unsigned int i = 1; i <= n; ++i)
{
removeQueen(B, n, i, positions[i]);
}
for(unsigned int i = 1; i <= n; ++i)
{
if(++positions[i] <= n)
// break incrementing if we are in between the numbers:
// 1424 will get 1431 (with last position updated already before)
goto CONTINUE;
positions[i] = 1;
}
// we completed the entire positions list, i. e. we reset very
// last position to 1 again (comparable to an overflow: 4444 got 1111)
// so we are done -> exit main loop:
break;
CONTINUE: (void)0;
}
It's untested code, so you might find a bug in, but it should clearly illustrate the idea. It's the naive aproach, always placing the queens and removing them again.
You can do it a bit cleverer, though: place all queens at positions 1 initially and only move the queens if you really need:
for(unsigned int i = 1; i <= n; ++i)
{
positions[i] = 1;
placeQueen(B, n, i, 1);
}
for(;;)
{
printBoard(B, n);
for(unsigned int i = 1; i <= n; ++i)
{
removeQueen(B, n, i, positions[i]);
++positions[i]
if(++positions[i] <= n)
{
placeQueen(B, n, i, positions[i]);
goto CONTINUE;
}
placeQueen(B, n, i, 1);
positions[i] = 1;
}
break;
CONTINUE: (void)0;
}
// cleaning up the board again:
for(unsigned int i = 1; i <= n; ++i)
{
removeQueen(B, n, i, 1);
}
Again, untested...
You might discover that now the queens move within first row first, different to your recursive approach before. If that disturbs you, you can count down from n to 1 while incrementing the positions and you get original order back...
At the very end (after exiting the loop), don't forget to free the array again to avoid memory leak:
free(positions);
If n doesn't get too large (eight for a typical chess board?), you might use a VLA to prevent that problem.
Edit:
Above solutions will print any possible combinations to place eight queens on a chess board. For an 8x8 board, you get 88 possible combinations, which are more than 16 millions of combinations. You pretty sure will want to filter out some of these combinations, as you did in your original solution as well (if(B[i][x] == 0)), e. g.:
unsigned char* checks = malloc(n + 1);
for(;;)
{
memset(checks, 0, (n + 1));
for(unsigned int i = 1; i <= n; ++i)
{
if(checks[positions[i]] != 0)
goto SKIP;
checks[positions[i]] = 1;
}
// place queens and print board
SKIP:
// increment positions
}
(Trivial approach! Including the filter in the more elaborate approach will get more tricky!)
This will even be a bit more strict than your test, which would have allowed
_ Q _
Q _ _
_ Q _
on a 3x3 board, as you only compare against previous column, whereas my filter wouldn't (leaving a bit more than 40 000 boards to be printed for an 8x8 board).
Edit 2: The diagonals
To filter out those boards where the queens attack each other on the diagonals you'll need additional checks. For these, you'll have to find out what the common criterion is for the fields on the same diagonal. At first, we have to distinguish two types of diagonals, those starting at B[1][1], B[1][2], ... as well as B[2][1], B[3][1], ... – all these run from top left to bottom right direction. On the main diagonal, you'll discover that the difference between row and column index does not differ, on next neighbouring diagonals the indices differ by 1 and -1 respectively, and so on. So we'll have differences in the range [-(n-1); n-1].
If we make the checks array twice as large and shift all differences by n, can re-use do exactly the same checks as we did already for the columns:
unsigned char* checks = (unsigned char*)malloc(2*n + 1);
and after we checked the columns:
memset(checks, 0, (2 * n + 1));
for(unsigned int i = 1; i <= n; ++i)
{
if(checks[n + i - positions[i]] != 0)
goto SKIP;
checks[n + i - positions[i]] = 1;
}
Side note: Even if the array is larger, you still can just memset(checks, 0, n + 1); for the columns as we don't use the additional entries...
Now next we are interested in are the diagonals going from bottom left to top right. Similarly to the other direction, you'll discover that the difference between n - i and positions[i] remains constant for fields on the same diagonal. Again we shift by n and end up in:
memset(checks, 0, (2 * n + 1));
for(unsigned int i = 1; i <= n; ++i)
{
if(checks[2 * n - i - positions[i]] != 0)
goto SKIP;
checks[2 * n - i - positions[i]] = 1;
}
Et voilà, only boards on which queens cannot attack each other.
You might discover that some boards are symmetries (rotational or reflection) of others. Filtering these, though, is much more complicated...

How tor print the first occurrence if there are more than 1 max values?

So I have to write some code that reads from a file and outputs certain parts of it.
For one part of it, I have to read some values and print out the one that occurs the most.
My problem is that if there are more than 1 values that occur a maximum amount of times (e.g. 5 and 4 both occur 2 times), my code is printing the latter value.
I want to print the first one (in this example, that would be 5). How do I do that?
Here is my code so far;
int find_max(int id[], char poi_names[][51], int num){
int max_index = 0;
int max_freq = 1;
for(int i = 0; i < num -1; i++){
int freq = 1;
for(int j = 0; j < num; j++){
if(id[i] == id[j]){
freq ++;
}
}
if(max_freq<freq){
max_index = i;
max_freq = freq;
}
}
return max_index;
}
Insert another condition if frequency is same as max frequency and in that condition check if the max_index is less than the index, if less than print.
else if (max_freq == freq){
if(max_index > index)
max_index = index
}
I think this should give the first occurrence.
Instead of checking for (max_freq lessthan freq), allow it to replace the id also when (max_freq==freq)... This will allow new values with the same freq to replace the previous maximum.
if(max_freq<=freq){
max_index = i;
max_freq = freq;
}

Controlled nested looping

I have the nested loops that nested (r=) 3 times. Each loop running for (n=) 5 times.
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
{
for (k=0; k<n; k++)
//
}
}
But how do we do the nesting dynamically at run time. Say we know it should be nested r times. Each loop running n times. I thought something like recursion but it goes indefinitely.
funloop (int r)
{
for (int i = 0; i < n; i++)
{
//
if (r < 3)
funloop (r++);
else
return;
}
}
Please let me know how this could be done? I couldn't find a sources online.
If you don't know the depth of the recursion statically, the most common approach is to use recursion to represent the looping. For example, suppose that you need to have d levels of nesting of loops that all need to iterate k times. Then you could implement that using recursion of this form:
void RecursivelyNestIterations(unsigned d, unsigned k) {
/* Base case: If the depth is zero, we don't need to iterate. */
if (d == 0) return;
/* Recursive step: If we need to loop d times, loop once, calling the
* function recursively to have it loop d - 1 times.
*/
for (unsigned i = 0; i < k; ++i) {
/* Recurse by looping d - 1 times using the same number of iterations. */
RecursivelyNestIterations(d - 1, k);
}
}
Hope this helps!
The simplest method is just to collapse it to one for loop:
for(i=0; i<pow(n, r); i++) {
}
That can however make it difficult to access the loop counters, if you need them, but that can be done mathematically. For example, the innermost loop counter variable value is given by :
int c = i % n;
You could have an array of such counters and determine the values with similar equations, or you can just increment them, when required, e.g.:
void iterate(int r, int n) {
int i, rc, *c = malloc(sizeof(int) * r);
memset(c, 0, sizeof(int) * r);
for(i = 0; i < pow(n, r); i++) {
// code here, using loop counters in the 'c' array, where c[0] is counter
// for the outer loop, and c[r - 1] is the counter for the innermost loop
// update the counters
rc = r;
while(rc > 0) {
rc--;
c[rc]++;
if(c[rc] == n) {
c[rc] = 0;
} else {
break;
}
}
}
free(c);
}
Just call if (r) funloop(r-1); in the loop body.
#include <stdlib.h>
#include <stdio.h>
static int n = 3;
void _funloop(int cur,int total)
{
if(cur!=total)
{
for(int cnt=0;cnt!=n;++cnt)
{
fprintf(stdout,"%d::%d\n",cur,cnt);
}
_funloop(cur+1,total);
}
}
void funloop(int total)
{
_funloop(0,total);
}
int main()
{
funloop(10);
return 0;
}
A solution that doesn't use recursion is discussed in this Tip
[link]http://www.codeproject.com/Tips/759707/Generating-dynamically-nested-loops
The code is in C++ and require # for the include and define statements
include <iostream>
define MAXROWS 9
define MAXVALUES 9
using namespace std;
char display[] = {'1','2','3','4','5','6','7','8','9'};
int main() {
int arrs[MAXROWS]; // represent the different variables in the for loops
bool status = false;
for (int r=0;r<MAXROWS;r++)
arrs[r] = 0; // Initialize values
while (!status) {
int total = 0;
// calculate total for exit condition
for (int r=0;r<MAXROWS;r++)
total +=arrs[r];
// test for exit condition
if (total == (MAXVALUES-1)*MAXROWS)
status = true;
// printing
for (int r=0;r<MAXROWS;r++)
cout << display[arrs[r]]; // print(arrs[r])
cout << endl; // print(endline)
// increment loop variables
bool change = true;
int r = MAXROWS-1; // start from innermost loop
while (change && r>=0) {
// increment the innermost variable and check if spill overs
if (++arrs[r] > MAXVALUES-1) {
arrs[r] = 0; // reintialize loop variable
// Change the upper variable by one
// We need to increment the immediate upper level loop by one
change = true;
}
else
change = false; // Stop as there the upper levels of the loop are unaffected
// We can perform any inner loop calculation here arrs[r]
r=r-1; // move to upper level of the loop
}
}

Resources