I have already designed the following algorithm that determines the binomial coefficient using a two dimensional array. For example, to calculate the binomial coefficient of n choose k, we can create a two dimensional array like so:
int[][] arr = new int[n][k];
We can populate the array in the following way:
for(int i = 0; i <= n; i++){
for(int j = 0; j <= minimum(i, k); j++){
if(j == 0 || i == j){
arr[i, j] = 1;
} else{
arr[i, j] = arr[i - 1, j - 1] + arr[i - 1, j];
}
}
}
However, I need to redesign this algorithm to use a one dimensional array from indexes 0-k. I am having a lot of trouble pinpointing how to do this. I have started in small steps, and realized some common occurrences:
If k = 0, arr[0] will be 1, and that will be returned regardless of n.
If k = 1, arr[0] will be 1, arr[1] should be n, if I'm designing it in a loop.
When I say k = 2, this is where it gets tricky, because the value of arr[2] will really depend on the previous values. I believe that as I loop (say from i = 0 to i = n), the values of arr[] will change but I can't quite grasp how. I've started with something along these lines:
for(int i = 0; i <= n; i++){
for(int j = 0; j <= minimum(i, k); j++){
if(j == 0 || i == j){
arr[j] = 1;
} else if(j == 1){
arr[j] = i;
} else{
arr[j] = ??; // I can't access previous values, because I didn't record them?
}
}
}
How should I handle this?
Here is a code which uses only one one dimensional array:
int[] coefficients = new int[k + 1];
coefficients[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = k; j >= 1; j--) {
coefficients[j] += coefficients[j - 1];
}
}
Why is it correct? To compute coefficients[j] for a fixed i, we need to know the value of coefficients[j - 1] and coefficients[j] for i - 1. If we iterate from k down to 0, we can safely record a new value for the current position because we will never need its old value.
Related
So I was trying to implement Cormen's pseudocode for bubble sorting but I can't seem to get it to work.
This is my approach on Cormen's pseudocode:
void BUBBLE_SORT(int a[200], int n) {
int i, j, aux;
for (i = 1; i <= n - 1; i++) {
for (j = n; j < i + 1; j++) {
if (a[j] < a[j - 1]) {
aux = a[j];
a[j] = a[j + 1];
a[j + 1] = aux;
}
}
}
}
I tried another piece of code found on the internet but the result was not different:
void bubbleSort(int arr[], int n) {
int i, j;
for (i = 0; i < n - 1; i++)
for (j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1])
swap(&arr[j], &arr[j + 1]);
}
I would love to know where my comprehension failed in understanding Cormen's implementation and to get the bubble sorting to work!
There are at least three issues:
The pseudocode assumes array indices go from 1 to length. In C arrays are indexed from 0 to length-1; your code doesn't correct for that.
The inner loop in the pseudocode goes downto i+1, but your inner loop tries to count up:
for(j=n;j<i+1;j++)
should be
for (j = n; j > i; j--)
The pseudocode swaps A[j] and A[j-1], but your C code swaps A[j] and A[j+1].
Mistakes in your implementation:
You start counting your array from 1th index. But in C programing a array start with 0th position. [you should right i = 0 instead of i = 1]
The inner loop must run from j = n-1 from j = i+1 and the value of j must be decreasing.
You compare a[j] with a[j-1] but u swap a[j] with a[j+1]. you should have swap a[j] with a[j-1]
See the changes in the code below. Hope it will be useful:
int i, j, aux;
for(i=0;i<n-1;i++){
for(j=n-1;j>=i+1;j--){
if(a[j]<a[j-1]){
aux=a[j];
a[j]=a[j-1];
a[j-1]=aux;
}
}
}
Q: Find all prime numbers between two given Numbers a and b, by using Sieve of Eratosthene.
Im using dynamic array to store prime numbers, but it does nt work.
After debug it, everything is ok untill the last
printf() that crashes.
Code
int main() {
int i, j, n, a, b, k;
int *tab;
scanf("%i", &n); // n is number of sets
for (i = 1; i <= n; i++){
scanf("%i %i", &a, &b);
tab = (int*) malloc(b * sizeof(int)); //allocating the memorry
for (j= 0; j < b; j++){ //seting all numbers to be prime
*(tab + j) = 1;
}
for (j = 2; j <= b; j++){
if (*(tab + j) == 1){
for(k = j; k <= b; k+=j)
*(tab + k) = 0; //seting 0 for all non prime numbers
}
}
for (j = a; j <= b; j++){
if (*(tab + j) == 1){
printf("%i", j); //printing prime numbers
}
}
free(tab);
}
return 0;
}
your second loop should be
for (j = 2; j <= b; j++){
if (*(tab + j) == 1){
for(k = j; k <= b; k += j)
*(tab + k) = 0; //seting 0 for all non prime numbers
}
}
the problem was that because you used multiplication, you tried to access an item in the tab array with index above its allocated size.
edit: and as #melpomene stated, the array is too short. therefore the allocation should be
tab = (int*) malloc((1+b) * sizeof(int));
The problem is, you're accessing array out of its bounds:
*(tab + k*j) = 0;
when
k <= b
j <= b
When you declare array of b elements, you can only access array from 0 to b-1 index.
BTW, as mentioned in comments, using tab[k*j] is more readable and shows clearly that tab is array.
I don't really understand what you mean by sets number, but pseudocode of Sieve of Eratosthenes taken from wiki is applied from 2 to n. So in your case 2 becomes a and n becomes b. You don't need checking all numbers from a to b, root of b will suffice.
Your algorithm should look like:
create array for holding b - a elements
make every element equals 1
make 0 elements which fulfill Eratosthenes rules for complex number
print indexes which contains 1.
I know that the number of inversions in an n-element array can be counted in O(n log(n)) operations using an enhanced merge sort.
However, I came across a different solution, which somehow manages to count the number of inversions in O(n) time, provided that the input is a permutation of (1, 2, 3, ..., n−1, n):
EDIT:-
I am sorry for the code I pasted as it doesn't work in all the cases . Actually this code was used for this question and it passed all the cases . But I am still leaving the code so that it may serve as some intuition and maybe a linear time solution for this problem will come up.
NOTE :- The Below Mentioned Code is Incorrect.
/* int in = 0;
for (int i = 0; i < n; i++) {
a[i] = a[i] - i - 1;
}
for (int i = 0; i < n; i++) {
if (a[i] > 0)
in = in + a[i];
else if (a[i] < -1)
in = in - a[i] - 1;
} */
Now the question is can we come up with a linear time solution for this problem ?
The obvious answer is that it doesn't. For example, for n = 4 and a = {2, 3, 4, 1}, you code gives the answer 5, even though the correct inversion count is clearly 3.
The approach is WRONG!
Consider the example below!
int a[] = { 2, 3, 1 };
int in = 0;
for (int i = 0; i < n; i++) {
a[i] = a[i] - i - 1;
}
// a[] = { 1, 1, -2 };
for (int i = 0; i < n; i++) {
if (a[i] > 0)
in = in + a[i];
else if (a[i] < -1)
in = in - a[i] - 1;
}
// in = 1 + 1 - (-1) = 3
The correct answer is 2 but it returns 3 here!
In the program that I'm writing, I currently have a for-loop that goes through an array, num[5], and checks to see if there are any 1's in that array, which looks like:
int counter = 0;
for (int i = 1; i <= 5; i++)
if (num[i] == 1)
counter++;
This works successfully, but I'm now trying to go through the array and see what the indices of the 1's in the program are. So, if I have 01001, I want to make an array that holds the positions of the 1's. The following is what I've tried so far:
int b[counter];
for (int k = 0; k <= counter; k++) {
for (i = 0; i <= 5; i++) {
if (num[i] == 1) {
b[k] = i;
}
}
}
but this doesn't produce the desired result. When I type the string in, say 1001, I get 444. Can someone tell me what I'm doing incorrectly?
For each value of k, for each occurrence of a 1, you're setting b[k] to the index of the 1. Thus each b[k] will have the index of the last 1.
Try:
int b[counter];
int k = 0;
for (i = 0; i <= 5; i++) {
if (num[i] == 1) {
b[k++] = i;
}
}
So, whenever it gets a 1, it assigns b[k] to the index and then increases k.
Then you should also use k, not counter, when trying to print out b.
The problem lies in this part of your code.
int b[counter];
for (int k = 0; k <= counter; k++) {
**for (i = 0; i <= 5; i++) {
if (num[i] == 1) {
b[k] = i;
}**
}
}
Suppose you get a 1 at the index 1 of the array as in 01001. You assign b[k] = 1;
This is perfectly valid. But as the loop continues you get another 1 at the index 4. Thus the command b[k] = 4; is again executed.
Note that your value of k is constant in both the statements and hence you get the array b as 44.
So what you need to do is break the inner for loop as soon as you get a 1.
Here is the modified code. You also need to keep a track of the iterator i and I have done that here using the variable- new_pos // new position.
int b[counter];
int new_pos=0; //to keep track of the iterator
for (int k = 0; k <= counter; k++) {
for (i = new_pos; i <= 5; i++) {
if (num[i] == 1) {
b[k] = i;
new_pos = i+1;
break;
}
}
}
The code provided by Dukeling is also perfect, but I am just giving another way to make your own code work.
If I have a 2D array, it is trivial to loop through the entire array, a row or a column by using for loops. However, occasionally, I need to traverse an arbitrary 2D sub-array.
A great example would be sudoku in which I might store an entire grid in a 2D array but then need to analyse each individual block of 9 squares. Currently, I would do something like the following:
for(i = 0; i < 9; i += 3) {
for(j = 0; j < 9; j += 3) {
for(k = 0; k < 3; k++) {
for(m = 0; m < 3; m++) {
block[m][k] == grid[j + m][i + k];
}
}
//At this point in each iteration of i/j we will have a 2D array in block
//which we can then iterate over using more for loops.
}
}
Is there a better way to iterate over arbitrary sub-arrays especially when they occur in a regular pattern such as above?
The performance on this loop structure will be horrendous. Consider the inner most loop:
for(m = 0; m < 3; m++) {
block[m][k] == grid[j + m][i + k];
}
C is "row-major" ordered, which means that accessing block will cause a cache miss on each iteration! That's because the memory is not accessed contiguously.
There's a similar issue for grid. Your nested loop order is to fix i before varying j, yet you are accessing grid on j as the row. This again is not contiguous and will cache miss on every iteration.
So a rule of thumb for when dealing with nested loops and multidimensional arrays is to place the loop indices and array indices in the same order. For your code, that's
for(j = 0; j < 9; j += 3) {
for(m = 0; m < 3; m++) {
for(i = 0; i < 9; i += 3) {
for(k = 0; k < 3; k++) {
block[m][k] == grid[j + m][i + k];
}
}
// make sure you access everything so that order doesn't change
// your program's semantics
}
}
Well in the case of sudoku couldn't you just store 9 3x3 arrays. Then you don't need to bother with sub arrays... If you start moving to much larger grids than sudoku you would improve cache performance this way as well.
Ignoring that, your code above works fine.
Imagine you have a 2D array a[n][m]. In order to loop a subarray q x r whose upper right corner is at position x,y use:
for(int i = x; i < n && i < x + q; ++i)
for(int j = y; j < m && j < y + r; ++j)
{
///
}
For your sudoku example, you could do this
for(int i = 0; i<3; ++i)
for(int j = 0; j < 3; ++j)
for(int locali = 0; locali < 3; ++locali)
for(int localj = 0; localkj <3; ++localj)
//the locali,localj element of the bigger i,j 3X3 square is
a[3*i + locali][3*j+localj]