Every possible path from 2D array? (Cross Product) - c

Let's suppose I have this array
int diml = 3;
int dims = 3;
int time [diml][dims] ={
(10, 3, 5),
( 4, 7, 2),
( 2, 8, 1)
};
How can I get every combination like:
(10, 3, 5)
(10, 3, 2)
(10, 3, 1)
(10, 7, 5)
(10, 7, 2)
(10, 7, 1)
...
(2, 8, 5)
(2, 8, 2)
(2, 8, 1)
*Is this possible without saving all the combinations in a new array, but just a 1D local array that can store the current combination on every cycle?
*I'd prefer cycles over recursion. And at the end of each cycle I need the pattern (like 10, 3, 2) so I can elaborate it.
*The dimensions of the 2D array are MxN (3x3 is just an example).
*A solution with binary trees is accepted (but I want to save the indexes too).
I should do this in C. I have found similar solutions in StackOverflow but they work by column and they save the data in a 2D array, but that's not what I need.
Thanks in advance! (:

For this example codes, The first one was built so it would be easier to understand example 2. Example 1 was built for only 3x3 matrixes. Example 2 was built so that it can accommodate a matrix with 8 columns at maximum. I didn't use malloc or return an array. It will print back all the possible combinations for you. It doesn't deal with returning the data but it wouldn't be hard to incorporate that into the code.
For the method of calculation all the possible combination, I would use a 3x3 matrix as an example.
In a 3x3 matrix, there are 3 rows and 3 columns. I treated each column as a set of number that I can pick and the rows as the possible of numbers that I can pick from. So in that example, I can pick 012 for my first, second, and third set of number.
So to get all the possible combinations, I have 3 arrays, [0] [1] [2]. They all start at 0. I first save the possible combination of 0 0 0. Then I increase array 2 by 1. Then I would get 0 0 1. I then save that combination. I will keep on doing that and one the [2] array == 2. I turn that to 0 and add a 1 to the array to the left of it. So it become 0 1 0. When I reach a loop where my values of my arrays are 0 2 2, the loop after that, I will get 1 0 0. I will keep on doing that until all the value turn to zero then I am done.
For how the data is store, I store them continually in an array. To read back the value properly. Say for example in a 2x5 matrix. Each combination will have 5 numbers. Thus, the first combination is the first five indexes, the next combination, is the next five numbers after that one.
To calculate how much array length you would need before calculating the combinations, you can just base the calculation on rows and columns. Think of this like the lottery. If there are 3 columns, it like you can pick 3 numbers. Each column have 3 rows, so that mean for each time you pick a number there are 3 possible numbers to pick from. For you to hit a jackpot the chances are 1:3 x 1:3 x 1:3 or 1:27 because there are 27 possibilities if picking 3 numbers like this (123 123 123) and matching them in the correct order. Thus, for a 3x3 matrix, it is 3x3x3, 4x4 = 4x4x4x4, 1x3 = 1, 3x1 = 3, 2x5 = 2x2x2x2x2 = 32.
Thus, the amount of possible combinations is "the amount of rows" to the power of "the amount of columns".
The size is the amount of possible combinations multiply by the amount of numbers per combination. Of which would be "possibilities multiply column count = array size needed.
Example 1:
#include <stdio.h>
void printMatrixCombo(int row, int col, int matrix[row][col]);
int main(){
const int m1 = 3;
const int m2 = 3;
int matrix[m1][m2] = {
{10, 3, 5},
{4, 7, 2},
{2, 8, 1}
};
printMatrixCombo(m1, m2, matrix);
return 0;
}
// Only use this for a 3x3
void printMatrixCombo(int row, int col, int matrix[row][col]){
int oi = 0;
int output[81] = {0};
for (int group1 = 0; group1 < 3; group1++){
for (int group2 = 0; group2 < 3; group2++ ){
for (int group3 = 0; group3 < 3; group3++ ){
output[oi++] = matrix[group1][0];
output[oi++] = matrix[group2][1];
output[oi++] = matrix[group3][2];
}
}
}
printf("There were %d combination in the matrix of %d x %d\n", oi / col, row, col );
for ( int i = 0; i < oi ; ){
printf("(");
for ( int j = 0; j < col; j++ ){
printf("%d", output[i+j]);
if ( j != col - 1 ) printf(", ");
}
printf(")\n");
i = i + col;
}
}
Example 2:
#include <stdio.h>
void printMatrixCombo(int row, int col, int matrix[row][col]);
int main(){
const int row = 4;
const int col = 4;
/*// 3x3
int matrix[row][col] = {
{10, 3, 5},
{4, 7, 2},
{2, 8, 1}
};//*/
// 4 x 4
int matrix[row][col] = {
{10, 3, 5, 7},
{4, 7, 2, 3},
{2, 8, 1, 9},
{9, 4, 8, 11}
};//*/
/*// 5 x 5
int matrix[row][col] = {
{10, 3, 5, 7, 25},
{4, 7, 2, 87, 42},
{2, 8, 1, 85, 39},
{9, 4, 8, 94, 57},
{10, 3, 5, 7, 93},
};//*/
/*// 2 x 2
int matrix[row][col] = {
{10, 3},
{4, 7},
};//*/
/*// 1 x 1
int matrix[row][col] = {
{10},
};//*/
/* // 3 x 1
int matrix[row][col] = {
{10},
{4},
{1}
}; //*/
/*// 1 x 3
int matrix[row][col] = {
{10, 4, 1},
};// */
printMatrixCombo(row, col, matrix);
return 0;
}
void printMatrixCombo(int row, int col, int matrix[row][col]){
int oi = 0;
int allZ = 0;
// This is the maximum for a 5x5
// Change to fit usage case
int output[15625] = {0};
int colCount[8] = {0};
int lastCol = col - 1;
int lastRow = row - 1;
while (1){
for ( int i = 0; i < col; i++ )
output[oi++] = matrix[colCount[i]][i];
if ( colCount[lastCol] == lastRow ){
colCount[lastCol] = 0;
for (int i = lastCol - 1; i > -1; i--){
if ( colCount[i] == lastRow ){
colCount[i] = 0;
} else {
colCount[i]++;
break;
}
}
} else {
colCount[lastCol]++;
}
allZ = 1;
for ( int i = 0; i < col; i++ ){
if ( colCount[i] != 0 ){
allZ = 0;
break;
}
}
if (allZ == 1) break;
}
printf("There were %d combination in the matrix of %d x %d\n", oi / col, row, col );
printf("Array's length(indexes) is %d\n", oi );
for ( int i = 0; i < oi ; ){
printf("(");
for ( int j = 0; j < col; j++ ){
printf("%d", output[i+j]);
if ( j != col - 1 ) printf(", ");
}
printf(")\n");
i = i + col;
}
}

Related

C - delete element from array and reorganise

Given this array:
int a[] = {5, 8, 5, 6, 9, 5};
Would it be possible to remove all ints which equals 5 and move the rest the front of the array?
So that after the removal the array would look like this:
int a[] = {8, 6, 9, 0, 0, 0}
I don't know if by removing a element it becomes a 0 or a NULL?
Thanks!
You can do it with two iterations over the array, first iteration two to turn the element you want to delete, second iteration to separate zeros from non-zeros.
int a[] = {5, 8, 5, 6, 9, 5};
int n = 6;
for(int i = 0 ; i < n ; i++ ) {
if(a[i] == 5 ) {
a[i] = 0;
}
}
int* zero = a;
int* nonZero = a;
int j = 0;
while(j < n) {
while(*zero != 0) {
zero++;
}
while(*nonZero == 0) {
nonZero++;
j++;
}
if(zero < nonZero) {
*zero = *nonZero;
*nonZero = 0;
}
j++;
}
Your array is statically allocated, so always has the same size and deleted elements have the 0 value (according how you define the deleted values).
This link can help you and explains about how to delete element from array.
It is been awhile that i have programmed in C but it is posibble.
This is just a pseudo code, but you just need to change it to way of C programming.
int a[] = {5, 8, 5, 6, 9, 5};
int b[] = {5, 8, 5, 6, 9, 5}; // copy of array a to hold temp
for(int i = 0; i < Size of array; i++ ){
for(int j = i; j < Size of array; j++ ){
if(b[j] != 5){
a[i] = b[j];
a[j] = b[i];
break;
}
}
}
It will be like (▼: Target to swap, F: Finished, X: Not a targe to swap, N: Not processed):
▼, ▼, N, N, N, N
5, 8, 5, 6, 9, 5
F, ▼, X, ▼, N, N
8, 5, 5, 6, 9, 5
F, F, ▼, X, ▼, N
8, 6, 5, 5, 9, 5
Result:
8, 6, 9, 5, 5, 5
And remove 5s, it is quite different depends what you mean. If you do not change size of array then they can be 0 or undefined(null). So I think it differs by how you program the function that returns array.
your array is not dynamic so you just can't reduce its size after its been allocated.setting the value zero might solve the problem in your case.

Most effective method of swapping elements of an array after comparing it with other array

Let's say we have two arrays:
Array a1 and Array a2.
'a1' and 'a2' are similar in a way such that both have the same size and same elements but elements don't appear in the same order.
What will be the most effective way of comparing both arrays and finding out the minimum number of swaps required to bring the array 'a1' in the same order as 'a2'?
For example:
int a1[5] = { 1, 2, 3, 4, 5};
int a2[5] = { 2, 3, 1, 5, 4};
Hence the minimum number of swaps required is: 3
In steps:
swap 1: a1[0] <-> a1[1]
swap 2: a1[1] <-> a1[2]
swap 3: a1[3] <-> a1[4]
So, finally a1 will contain { 2, 3, 1, 5, 4}
int numofchanges = 0;
for(int i = 0; i < sizeOfArrays; i++)
{
int arr3[] = arr1;
for(int n = 0; n < sizeOfArrays; n++)
{
arr3[i] = arr1[n];
if(arr3[i] == arr2[i])
{
int tmp = arr1[i];
arr1[i] = arr1[n];
arr1[n] = tmp;
numofchanges++;
}
}
}
WARRNING this wont run is something like pseudo code
the variable numofchanges will hold the number of changes and arr1 now will be arr2
i hope this was helpful

C best function to get split array on elements less, equals and greater than some value

I am programming in C. What is the best method (I mean in linear time) to spit array on elements less, equals and greater than some value x.
For example if I have array
{1, 4, 6, 7, 13, 1, 7, 3, 5, 11}
and x = 7 then it should be
{1, 4, 6, 1, 3, 5, 7, 7, 13, 11 }
I don't want to sort elements because I need more efficient way. Of course in this example in could be any permutation of {1, 4, 6, 1, 3, 5} and {13, 11}.
My thougt: less or grater than some element in array... In this example it is 7.
My function is:
int x = 7;
int u =0, z = 0;
for(int i=0; i<size-1; i++) // size - 1 because the last element will be choosen value
{
if(A[i] == x)
swap(A[i], A[u]);
else if(A[i] == x)
{
swap(A[i], A[n-(++z)]);
continue;
}
i++
}
for(int i = 0; i<z; i++)
swap(A[u+i],A[size-(++z)];
where u is number of current less elements, and z is the number of equals element
But if I have every elements in array equals there it doesn't work (size-(++z)) is going under 0
This is the so-called Dutch national flag problem, named after the three-striped Dutch flag. (It was named that by E.W. Dijkstra, who was Dutch.) It's similar to the partition function needed to implement quicksort, but in most explanations of quicksort a two-way partitioning algorithm is presented whereas here we are looking for a three-way partition. The classic quicksort partitioning algorithms divide the vector into two parts, one consisting of elements no greater than the pivot and the other consisting of elements strictly greater. [See note 1]
The wikipedia article gives pseudocode for Dijkstra's solution, which (unlike the classic partition algorithm usually presented in discussions of quicksort) moves left to right through the vector:
void dutchflag(int* v, size_t n, int x) {
for (size_t lo = 0, hi = n, j = 0; j < hi; ) {
if (v[j] < x) {
swap(v, lo, j); ++lo; ++j;
} else if (v[j] > x) {
--hi; swap(v, j, hi);
} else {
++j;
}
}
There is another algorithm, discovered in 1993 by Bentley and McIlroy and published in their paper "Engineering a Sort Function" which has some nice diagrams illustrating how various partitioning functions work, as well as some discussion about why partitioning algorithms matter. The Bentley & McIlroy algorithm is better in the case that the pivot element occurs infrequently in the list while Dijkstra's is better if it appears often, so you have to know something about your data in order to choose between them. I believe that most modern quicksort algorithms use Bentley & McIlroy, because the common case is that the array to be sorted has few duplicates.
Notes
The Hoare algorithm as presented in the Wikipedia Quicksort article, does not rearrange values equal to the pivot, so they can end up being present in both partitions. Consequently, it is not a true partitioning algorithm.
You can do this:
1) Loop through the array, if element is less than x then put in new array1.
2)If element is greater than x then put in new array2.
This is linear time O(n)
I tried something like this below which I think is O(n). Took me a little bit to work the kinks out but I think it's pretty similar to the dutchflag answer above.
My ouptput
a.exe
1 4 6 5 3 1 7 7 11 13
1 4 5 6 3 1 7 7 7 11 13
code:
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
void order(int * list, int size, int orderVal)
{
int firstIdx, lastIdx, currVal, tempVal;
firstIdx = 0;
lastIdx = size-1;
for ( ;lastIdx>firstIdx;firstIdx++)
{
currVal = list[firstIdx];
if (currVal >= orderVal)
{
tempVal = list[lastIdx];
list[lastIdx] = currVal;
lastIdx--;
list[firstIdx] = tempVal;
if (tempVal >= orderVal)
firstIdx--;
}
}
lastIdx = size-1;
for( ;lastIdx>firstIdx && middleNum>0;lastIdx--)
{
currVal = list[lastIdx];
if (currVal == orderVal)
{
tempVal = list[firstIdx];
list[firstIdx] = currVal;
firstIdx++;
list[lastIdx] = tempVal;
if (tempVal == orderVal)
lastIdx++;
}
}
}
int main(int argc, char * argv[])
{
int i;
int list[] = {1, 4, 6, 7, 13, 1, 7, 3, 5, 11};
int list2[] = {1, 4, 7, 6, 7, 13, 1, 7, 3, 5, 11};
order(list, ARRAY_SIZE(list), 7);
for (i=0; i<ARRAY_SIZE(list); i++)
printf("%d ", list[i]);
printf("\n");
order(list2, ARRAY_SIZE(list2), 7);
for (i=0; i<ARRAY_SIZE(list2); i++)
printf("%d ", list2[i]);
}
Here is an example using a bubble sort. Which type of sort algorithm is best, is up to you, this is just to demonstrate. Here, I treat values < x as -1, values == x as 0, values > x as 1.
Note that the elements < x and those > x are still in the same sequence.
#include <stdio.h>
int main(void)
{
int array[] = { 1, 4, 6, 7, 13, 1, 7, 3, 5, 11 };
int x = 7;
int len = sizeof array / sizeof array[0];
int i, j, m, n, tmp;
for (i=0; i<len-1; i++) {
m = array[i] < x ? -1 : array[i] == x ? 0 : 1;
for (j=i+1; j<len; j++) {
n = array[j] < x ? -1 : array[j] == x ? 0 : 1;
if (m > n) {
tmp = array[i]; // swap the array element
array[i] = array[j];
array[j] = tmp;
m = n; // and replace alias
}
}
}
for(i=0; i<len; i++)
printf("%d ", array[i]);
printf("\n");
return 0;
}
Program output:
1 4 6 1 3 5 7 7 13 11

C - Recursive, cumulative sum of an array

I've been tasked with making a recursive function that takes an array of numbers, and turns it into an array of the cumulative sum of all the numbers up to this point, thus:
1, 2, 3, 4, 5 becomes 1, 3, 6, 10, 15
This is what I came up with:
#include <stdio.h>
int cumul(int tab[], int length, int ind) {
if (ind > 0) {
tab[ind] += tab[ind-1];
}
if (ind < length) {
cumul(tab, length, ind+1);
}
return 0;
}
int main() {
int ind;
int tab[6] = {1, 2, 3, 4, 5, 6};
int length = sizeof(tab)/sizeof(tab[0]);
for (ind = 0; ind < length; ind++) {
printf("%d ", tab[ind]);
}
printf("\n");
cumul(tab, length, 0);
for (ind = 0; ind < length; ind++) {
printf("%d ", tab[ind]);
}
printf("\n");
return 0;
}
It works well in most cases but I've hit a snag for oddly specific arrays:
For example, it doesn't work for tab[6] = {1, 2, 3, 4, 5, 6}, here's the output:
1 2 3 4 5 6
1 3 6 10 15 21 27 7 4196016 0 -1076574208 32528 -1609083416 32767 -1609083416 32767 0 1 4195802 0 0 0 -1815242402 30550560 4195424 0 -1609083424
I have no idea why it goes bonkers. It works fine for just about any tab[5] and tab[7] arrays I tried, but fails for every tab[6] array I tried.
The problem occurs when ind reaches length-1. For example, if length is 6, and ind is 5, then the recursive call is
cumul(tab, 6, 6); // length=6 ind+1=6
At the next level of recursion, after the if ( ind > 0 ), the code will do this
tab[6] += tab[5]; // ind=6 ind-1=5
That results in undefined behavior because you're writing beyond the end of the array.
You could check the upper bound in the first if statement, e.g.
if ( ind > 0 && ind < length )
But it's better to just avoid the recursive call by changing the second if statement to
if ( ind < length - 1 )
Either change avoids the situation where you access tab[length].

How can I average a subset of an array and store the result in another array?

I have a C array fftArray[64] that contains values that I want averaged and placed into another array frequencyBar[8]. Getting the average of the entire array would be easy enough using a for statement.
int average, sum = 0;
for (i = 0; i < 64; i++)
{
sum += fftArray[i];
}
average = sum/64;
But I just can't seem to figure out how to get the average from fftArray[0] through fftArray[8] and store this in frequencyBar[0], the average of fftArray[9] through fftArray[16] and store this in frequencyBar[1], etc. Can anyone help me out with this? Thanks
This looks like a homework assignment, so, rather than give you the outright answer, I'd rather just point you in the right direction...
use a nested loop (one inside the other). One loop cycles 0-7, the other one 0 - 63. Use the smaller one to populate your sliced averages.
or better yet use the % operator to see when you've gone through 8 elements and do an average of your total, then reset the total for the next set. Then you'll have learned how to use the % operator too! :)
[EDIT]
ok, if not homework then something like this... I haven't written C in 5 years, so treat this as pseudo code:
//assuming you have a fftArray[64] with data, as per your question
int i,sum,avCounter,total;
int averages[8];
for(i=0 , avCounter=0, total=0 ; i<64; ){
total += fftArray[i];
if(++i % 8 == 0){ //%gives you the remainder which will be 0 every 8th cycle
averages[avCounter++] = total / 8
total = 0; //reset for next cycle
}
}
I think this will work better than a nested loop... but I'm not sure since % is division which is more processor heavy than addition... however... I doubt anyone would notice :)
int i, j;
for (i = 0; i < 8; i++) {
int sum = 0;
for (j = 0; j < 8; j++) {
sum += fftArray[ 8*i + j ];
}
frequencyBar[i] = sum / 8;
}
Bonus exercise: Optimize this code for speed on your chosen platform.
TF,
DISCLAIMER: This code is just off the top of my head... it hasn't even been compiled, let alone tested.
// returns the average of array[first..last] inclusive.
int average(int[] array, int first, int last) {
int sum = 0;
for (i = first; i <= last; i++)
sum += array[i];
return sum / (last - first + 1); // not sure about the +1
}
Then what you'd do is loop through the indexes of your frequencyBar array [0..7], setting frequencyBar[i] = average(array, first, last);... the tricky bit is calculating the first and last indexes... try i*8 and (i+1)*8 respectively... that may not be exactly right, but it'll be close ;-)
Cheers. Keith.
EDIT: Bored... waiting for my test results to come back. No news is good news, right? ;-)
It turns out that passing the length is a fair bit simpler than passing the last index.
#include <stdio.h>
int sum(int array[], int first, int length) {
int sum = 0;
for (int i = first; i < first+length; i++)
sum += array[i];
return sum;
}
double average(int array[], int first, int length) {
double total = sum(array, first, length);
#ifdef DEBUG
printf("DEBUG: [%2d..%2d] %d", first, first+length-1, array[first]);
for (int i = first+1; i < first+length; i++)
printf(" + %d", array[i]);
printf(" = %d / %d = %f\n", (int)total, length, total/length);
#endif
return total / length;
}
int main(int argc, char* argv[]) {
int array[] = { // average
1, 2, 3, 4, 5, 1, 2, 3, // 2.625
4, 5, 1, 2, 3, 4, 5, 1, // 3.125
2, 3, 4, 5, 1, 2, 3, 4, // 3
5, 1, 2, 3, 4, 5, 1, 2, // 2.875
3, 4, 5, 1, 2, 3, 4, 5, // 3.375
1, 2, 3, 4, 5, 1, 2, 3, // 2.625
4, 5, 1, 2, 3, 4, 5, 1, // 3.125
2, 3, 4, 5, 1, 2, 3, 4 // 3
};
double frequency[8];
for (int i = 0; i < 8; i++)
frequency[i] = average(array, i*8, 8);
for (int i = 0; i < 8; i++)
printf("%f ", frequency[i]);
printf("\n");
}
Watch your sum doesn't wrap around if fftArray has large value in!

Resources