C Updating of Arrays - arrays

with reference to this question - https://www.geeksforgeeks.org/arrange-given-numbers-form-biggest-number-set-2/
For some reason, if I do not update the elements in the second array, the elements in the first array does not get updated correspondingly.
int array[] = {1, 34, 3};
int newArrayWithSamePower[3] = {11, 34, 33};
// Sort initial array based on power array elements
for (int i = 0; i <= 2; i++) {
for (int j = i + 1; j <= 2; j++) {
if (newArrayWithSamePower[j] > newArrayWithSamePower[i]) {
int temp2 = newArrayWithSamePower[i];
newArrayWithSamePower[i] = newArrayWithSamePower[j];
newArrayWithSamePower[j] = temp2;
// Unsure why array indexes go haywire if you dont update power array
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
for (int i = 0; i <= tempIndex; i++) {
printf("%d\n", array[i]);
}
Expected output: {34, 3, 1}
However, if I do not update the power array, the output will become {3, 1, 34}.

if (newArrayWithSamePower[j] > newArrayWithSamePower[i]) {
int temp2 = newArrayWithSamePower[i];
newArrayWithSamePower[i] = newArrayWithSamePower[j];
newArrayWithSamePower[j] = temp2;
If you do not swap elements of newArrayWithSamePower array within the loop, then on different indexes the if (newArrayWithSamePower[j] > newArrayWithSamePower[i]) condition will be true, thus array will be swapped differently. The algorithm works in place - it has to modify elements to work properly.

Related

Why do array element values not change?

int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i <= 9; i++) {
int tmp = a[i];
a[i] = a[9 - i];
a[9 - i] = tmp;
}
for (int i = 0; i <= 9; i++) {
printf("%d", a[i]);
}
The result of it is: 1234567890,
but why not 10987654321
since it switch values in the first for loop,
but why can not change it when the next for loop runs
I have tried to move "int tmp" outside of the loop, but of no use at all.
Your loop:
for(int i=0;i<=9;i++){
int tmp= a[i];
a[i] = a[9-i];
a[9-i] = tmp;
}
Each iteration it swaps elements.
On the first iteration, it swaps a[0] and a[9]. On the second a[1] and a[8] and so on.
But what about the 10th iteration?
Well, it swaps a[9] and a[0]. But you already swapped those, so it's just swapping them back the way they were.
If you stop after 5 iterations, so you're only swapping each pair once, your code will behave the way you expect.
To illustrate the suggestion from #user4581301 in comments, see below. We get begin and end pointers to the first and last elements in the array, respectively. Our loop continues as long as the begin pointer is less than the end pointer. If end is greater than begin it means we've gone past halfway. If they're equal, it means our array had an odd number of elements, and we've hit the middle one. That middle element wouldn't need to be swapped, so either way we're done.
The update in the loop increments begin and decrements end, moving inward one place from each end of the array.
#include <stdio.h>
int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int *begin, *end;
for (begin = &arr[0], end = &arr[9]; begin < end; ++begin, --end) {
int temp = *begin;
*begin = *end;
*end = temp;
}
for (size_t i = 0; i < 10; ++i) {
printf("%d\n", arr[i]);
}
}
Because you are swapping every pair twice.
Iterate it to half of the array. If you are not able to spot the error kindly dry run it on paper, you will get the answer.
#include <stdio.h>
int main() {
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < 5; i++) {
int tmp = a[i];
a[i] = a[9 - i];
a[9 - i] = tmp;
}
for (int i = 0; i < 10; i++) {
printf("%d", a[i]);
}
}

Have I written the Selection Sort Algoithm in C the right way?

A question in my book explained selection sort in three lines and then asked the reader to write CODE for it in C. I have written the code here and it is working fine, but I am a little confused whether I have written it in the right way or not. Please read the code, I have even added comments and correct me if needed.
#include <stdio.h>
#define VALUESIZE 10
int main(void)
{
int temp;
int value[VALUESIZE] = {3, 5, 46, 89, 72, 42, 312, 465812, 758, 1};
// Printing array just for the user to see.
for (int k=0; k<VALUESIZE; k++)
{
printf("[");
printf("%d", value[k]);
printf("] ");
}
printf("\n");
// Sorting algo begins
for (int i=0; i < VALUESIZE - 1; i++) // This will obviously loop through each element in our array except the last element as it will automatically be sorted after n-1 steps
{
for (int j= i+1; j <= VALUESIZE; j++) // This nested loop will go through each element which appears after ith element. For e.g. If i = 2, then j will loop through entire array starting from j = 3
{
if (value[i] > value[j]) // This basic if statement will compare our ith and following jth value
{
temp = value[i]; // If the program finds any value[j] greater than value[i], then the values will be swapped.
value[i] = value[j];
value[j] = temp;
}
}
}
// Now after sorting, print the new sorted array.
for (int l=0; l<VALUESIZE; l++)
{
printf("[");
printf("%d", value[l]);
printf("] ");
}
printf("\n");
}
Select sort needs to iterate through the array to compare the ith value. At the end of this pass it will swap the 2 values. This is a reason why its not a very good sort algorithm for medium or large arrays.
I have changed your code a bit below
Untested but should work:
// Sorting algo begins
for (int i = 0; i < arr_length - 1; i++)
{
int min = i;
for (int j = i + 1; j <= arr_length; j++)
{
if (value[j] < value[min])
{
min = j;
}
}
//now swap
int cache = value[min];
value[min] = value[i];
value[i] = cache;
}

I can't find the bug in this c program

I found this in a tutorial. It is a program to print the given array backward. But it doesn't print the array backward, cause it has a bug. It says I should find the bug, which I can't.
#include <stdio.h>
int main()
{
int ara[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int i, j, temp;
for(i = 0, j = 9; i < 10; i++, j--)
{
temp = ara[j];
ara[j] = ara[i];
ara[i] = temp;
}
for(i = 0; i < 10; i++)
{
printf("%d\n", ara[i]);
}
return 0;
}
The bug is that the algorithm work by swapping the place of items in the array, but it iterates over too many elements. When i has iterated over the 5 first elements, the array is backwards. But the iteration continues over the last 5 which puts all elements back in the original position.
You can easily find this out by yourself by printing the whole array at each lap in the loop...
The above code is swapping ara[i] and ara[j] as i moves from 0->9 and j moves from 9->0.
The eventual result is all the numbers return to there original position.
Make your 1st for loop look like below if you want to reverse the original array.
for(i = 0, j = 9; i < j; i++, j--)
OR
If you just want to print it backward, the latter for loop is sufficient just modify it to
for(i = 9; i >= 0; i--)
Swap twice be same as do nothing. Make it swap once only.
for(i = 0, j = 9; i < 5; i++, j--)
{
temp = ara[j];
ara[j] = ara[i];
ara[i] = temp;
}

Issue with selection sort and using a findMin method in C

so I'm having an issue with a selection sort that I made in C. When implemented in one function, I can get the selection sort to work. However, when I do what my assignment asks, and use a findMin function that returns the minimum index an array, it doesn't sort it completely. I've tried to debug it using print statements but I can't seem to figure out what is going wrong.
Here is the sorting method I am using with the findMin method:
void sortMin2(int A[]) {
int outer;
int minIndex;
for(outer = 0; outer < 5; outer++) {
minIndex = findMin(A, outer, 5);
if(minIndex != outer) {
swap(&A[minIndex], &A[outer]);
}//end if
} // end for
}
int findMin(int A[], int i, int j) {
int k; // for loop
int index = 0;
for(k = (i + 1); k < (j+1); k++) {
if(A[k] < A[index]) {
index = k;
} // end if
} // end for
return index;
} // end findMin
void swap(int *i, int *j) {
int temp = *i;
*i = *j;
*j = temp;
} // end swap
And here is my output when I run it on an array of five values:
Array Before: 4, 10, 9, 1, 3,
4, 10, 9, 1, 3,
1, 10, 9, 4, 3,
10, 1, 9, 4, 3,
10, 1, 3, 4, 9,
10, 1, 3, 9, 4,
Array after: 4, 1, 3, 9, 10,
Now, here is my selection sort method that does work find (ie. properly sorts it).
void selectionSort2(int A[]) {
int outer; // for loops
int inner;
int minimum = 0;
//int minIndex = 0;
for(outer = 0; outer < 5; outer++) {
//minIndex = findMin(A, 0, 19);
minimum = outer;
for(inner = outer + 1; inner < 5; inner++) {
if(A[minimum] > A[inner]) {
minimum = inner;
} // end if
} // end inner for
if(minimum != outer) {
swap(&A[minimum], &A[outer]);
} // end if
} // end outer for
}
Does anyone see why my sortMin2 function doesn't actually sort it?
Some thingies, inside the code, are not in the right sense.
Why in findMin(...) method, the for loop has k < (j+1) as terminating condition. Don't you think, it should be k < j? Since j + 1 will lead to 6, hence the loop will go till j = 5, which will lead to undefined behaviour(as it is more than the bounds of the array A). Array indices start from 0. Since the size is 5, hence the indices are in the range of 0 - 4.
Moreover, the value of index is never changing. It always starts from 0 in every iteration. Instead it should be int index = i, inside the findMin(...) function, as in Selection Sort we find the smallest element, and put it on the left hand side, to it's rightful position, hence next time, we start from a place, one ahead of this location.
And inside the sortMin2(...) function, you failed to call swap(...), in case you have the new index to swap values with.
Here is the modified version, of the snippet:
int findMin(int A[], int i, int j) {
int k; // for loop
int index = i;
for(k = (i + 1); k < (j); k++) {
if(A[k] < A[index]) {
index = k;
} // end if
} // end for
return index;
} // end findMin
void swap(int *i, int *j) {
int temp = *i;
*i = *j;
*j = temp;
} // e
void display(int A[])
{
int i = 0;
for (i = 0; i < 5; ++i)
printf("%d\t", A[i]);
printf("\n");
}
void sortMin2(int A[]) {
int outer = 0;
int minIndex = -1;
for(outer = 0; outer < 5; outer++) {
minIndex = findMin(A, outer, 5);
if(minIndex != outer) {
swap(&A[minIndex], &A[outer]);
display(A);
}//end if
} // end for
}

Highest value of last k values in array, better than O(n^2)

I have an array of n elements and for each element I'm trying to find the highest value from the last k values (including the current value)? E.g. given k,
int[] highestValues = new int[arr.Length];
for (int i = k - 1; i < arr.Length; i++)
{
int highest = Int32.MinValue;
for (int j = i - k; j <= i; j++)
{
highest = Math.Max(highest, arr[j]);
}
highestValues[i] = highest;
}
It appears the complexity of this algorithm is O(n^2). I was wondering if there was any way to do it quicker, e.g. rather than comparing k numbers in the inner loop, reuse the result from the previous operation.
There is a nice solution for this problem, using Dequeue data structure (a structure which support add and check element at first and last position).
We create class Entry to store both index of the element and value of that element. Observe that the time complexity is approximately 2*n = O(2*n) = O(n) (Each element is added only once to the queue, and we also iterate through each element in the queue once: remove it either at first or last position of the queue).
Pseudo code:
class Entry {
int value, index;
}
int [] highestValues;
Dequeue queue = new Dequeue();
for(int i = 0; i < arr.Length; i++){
Entry en = new Entry(arr[i], i);
while(queue.last().value <= en.value){//Remove all elements smaller than the current element.
queue.removeLast();
}
queue.append(en);
if(i >= k){
highestValues[i] = queue.first().value;
while(queue.first().index < i - k){//Remove all elements which has index out of the range
queue.removeFirst();
}
}
}
}
This is the maximum sliding window problem or Array of maximum value in sliding window.
See:
http://flexaired.blogspot.gr/2013/05/array-of-maximum-value-in-sliding-window.html
http://tech-queries.blogspot.gr/2011/05/sliding-window-maximum.html
The key to this is the double ended queue that allowed removing elements from beginning and end in order to have maintain what is the maximum as we slide along.
Example from sources:
import java.util.ArrayDeque;
import java.util.Deque;
public class SlidingWindow {
public static void maxSlidingWindow(int A[], int n, int w, int B[]) {
Deque<Integer> Q = new ArrayDeque<Integer>();
// Initialize deque Q for first window
for (int i = 0; i < w; i++) {
while (!Q.isEmpty() && A[i] >= A[Q.getLast()])
Q.pollLast();
Q.offerLast(i);
}
for (int i = w; i < n; i++) {
B[i - w] = A[Q.getFirst()];
// update Q for new window
while (!Q.isEmpty() && A[i] >= A[Q.getLast()])
Q.pollLast();
// Pop older element outside window from Q
while (!Q.isEmpty() && Q.getFirst() <= i - w)
Q.pollFirst();
// Insert current element in Q
Q.offerLast(i);
}
B[n - w] = A[Q.getFirst()];
}
public static void main(String args[]) {
int k = 20;
int a[] = new int[100];
for(int i=0; i<100; i++)
a[i] = i;
int b[] = new int[a.length - k + 1];
maxSlidingWindow(a, a.length, k, b);
System.out.println("Sliding Window Maximum is ");
for (int i = 0; i < b.length; i++) {
System.out.print(b[i] + ",");
}
}
}
I have an implementation that I believe works (coded in C#):
public static int[] LastKHighestValues(int[] array, int k)
{
int[] maxes = new int[array.Length];
int indexOfCurrentMax = 0;
int indexOfNextMax = 0;
for (int i = 0; i < array.Length; i++)
{
if (indexOfNextMax <= indexOfCurrentMax ||
array[i] > array[indexOfNextMax])
{
indexOfNextMax = i;
}
if (i - indexOfCurrentMax >= k)
{
indexOfCurrentMax = indexOfNextMax;
}
if (array[i] > array[indexOfCurrentMax])
{
indexOfCurrentMax = i;
}
maxes[i] = array[indexOfCurrentMax];
}
return maxes;
}
The idea is that you keep two "pointers": one to the current max, and one to the next thing to go to after the current max expires. This can be implemented in one pass through the array (so O(n)).
I have a few passing tests, but I'm far from certain I've covered every corner case:
Puzzle.LastKHighestValues(new[] {4, 3, 1}, 1).Should().Equal(new[] {4, 3, 1});
Puzzle.LastKHighestValues(new[] { 7, 7, 7 }, 3).Should().Equal(new[] { 7, 7, 7 });
Puzzle.LastKHighestValues(new[] { 7, 7, 7 }, 4).Should().Equal(new[] { 7, 7, 7 });
Puzzle.LastKHighestValues(new[] { 3, 2, 1 }, 2).Should().Equal(new[] { 3, 3, 2 });
Puzzle.LastKHighestValues(new[] { 7, 1, 4, 1, 1 }, 3).Should().Equal(new[] { 7, 7, 7, 4, 4 });
Puzzle.LastKHighestValues(new[] { 7, 8, 4, 9, 10 }, 2).Should().Equal(new[] { 7, 8, 8, 9, 10 });

Resources