I can't find the bug in this c program - c

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;
}

Related

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;
}

Sum of i-th elements of the array

The program receives an array of integers. It is necessary on each new line to output the sum of the i-th elements of the array. For example, for such an array {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, the answer will be like this :
55 //1+2+3+4+5+6+7+8+9+10
30 //2+4+6+8+10
18 //3+6+9
12 //4+8
15 //5+10
6 //6
7 //7
8 //8
9 //9
10 //10
Here is my code that solves this problem:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int N, i, j, S;
scanf("%d",&N); //length of array
int a[N];
for(i = 0; i < N; ++i) scanf("%d",&a[i]);
for(i = 1; i <= N; ++i) {
S = 0;
for(j = 0; j < N; ++j)
S += !((j+1)%i) ? a[j] : 0;
printf("%d\n",S);
}
return 0;
}
My problem is that my algorithm is not fast enough. And on big data, its speed is very low.
I tried to come up with an algorithm that would recursively calculate small sums first, and then calculate other. But I failed to implement it.
Please, can you give me a more elegant option to solve this problem.
Simple modification helps to avoid checking all the indices:
for(j = i - 1; j < N; j += i)
S += a[j];
A for loop doesn't have to increment the iterator variable by only one, you can add any amount to it, for example a[i - 1], as in:
for(j = 0; j < N; j += a[i - 1])
That means the innermost loop will not run as many times in the later iterations.
That also means you can simply skip the condition inside the innermost loop, and just do
S += a[j];
Note: This isn't tested, and might need some tweaking. The general principle is the important part: Do less!

C Updating of 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.

Second least occurring element in an array in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am currently working on a project and for one of the parts I need to determine the second least occurring element in a C array. In any case, the maximum number of elements in the array is going to be 100. I have a function written already to find the least occurring element:
int minRepeat(int arr[], int i){
int j = 0;
int l = 0;
int minimum = 100;
int minNum = 0;
for(j = 0; j < i; j++){
int m = 0;
for(l = 0; l < i; l++){
if(arr[j] == arr[l]){
m++;
}
}
if(m < minimum){
minimum = m;
minNum = arr[j];
}
}
return minNum;
}
arr[] is the inputted array and int i is the size of that array.
I am trying to create a function that will find the second least occurring element in a C array. The function is currently:
int secMin(int arr[], int i){
int j = 0;
int l = 0;
int minimum = 0;
int minNum = 0;
int q = 0;
int k = minRepeat(arr, i);
for(q = 0; q < i; q++){
if(arr[q] == k){
minimum++;
}
}
int minimum2 = 100;
for(j = 0; j < i; j++){
int m = 0;
for(l = 0; l < i; l++){
if(arr[j] == arr[l]){
m++;
}
}
if(m < minimum2){
if(m > minimum){
minimum2 = m;
minNum = arr[j];
}
}
}
return minNum;
}
I am calling the first function to find the least occurring element. Looping through that to see how many times that element occurs in the array, and then doing the same as the first function to find the least occurring, but compare it to the first least element at the end to make sure that this element is the second least occurring.
When arr[] = {1, 1, 1, 2, 2, 3, 2, 2, 4, 1}
I get the least occurring number to be 3 and the second least occurring to be 1.
Sometimes the function works with other input and sometimes it does not, such as in the case above.
Thank you for your help!
Just adjust your first example a little to also store the second least element:
if(m < minimum){
secondminimum = minimum;
secondminNum = minNum
minimum = m;
minNum = arr[j];
}
Edit: I just realised that will only work if least and seconleast element do not have the same number of appearances, but you can capture that case.

Code to store indices of occurrences doesn't work

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.

Resources