Why my bubble sort implementation prints an extra numbers? - c

Ok so im trying to implement bubble sort but it does not work properly when I type in 0's as a number. It displays extra numbers.
int main ()
{
int amount;
int numbers[50];
int x, y, z, j;
int swap;
printf("How many numbers do you want to sort: ");
scanf("%i", &amount);
for (x = 0; x <= amount; x++)
{
printf("Enter number %i: ", x);
scanf("%i", &numbers[x]);
}
for (j = 0; j <= amount; j++)
{
for (y = 0; y <= amount; y++)
{
if (numbers[y] > numbers[y + 1])
{
swap = numbers[y];
numbers[y] = numbers[y + 1];
numbers[y + 1] = swap;
}
}
}
for (z = 0; z <= amount; z++) {
printf("%i ", numbers[z]);
}
return 0;
}

If you start your for loops with 0, x = 0; x <= amount; will give you an extra loop.
ie:
amount = 5,
loop: 0, 1, 2, 3, 4, 5 (total 6 times)
Try x = 0; x < amount; instead
amount = 5
loop: 0, 1, 2, 3, 4 (total 5 times)
And one more thing, you need to check where your y is in the loop later on:
numbers[y + 1] = swap;
as [y+1] will cause out of bounds error when it's the last iteration of the loop. Remember, arrays we typically start counting from 0, and the last element is therefore size-1.
If you loop from y = 0; y < amount; you'll get:
numbers[0], numbers[1], numbers[2]. numbers[3], numbers[4], total 5 elements
So your last loop with numbers[y + 1] will actually try to access numbers[5], a theoretical 6th element which doesn't exist. Suggest to set that loop to y < amount-1

Related

Gauss-seidel method algorithm code giving inf numbers in solution

I'm not sure why I'm getting inf values when plugging in a 3 equation answer, another set of eyes on the equation loop would be useful, when I use a single equation the number of iterations is correct but when it's more than that the numbers multiply to inf.
Inputs for the code I used
Enter the Total Number of Equations: 3
Enter Allowed Error: 0.5
Enter the Co-Efficients
Matrix[1][1] = 1
Matrix[1][2] = 2
Matrix[1][3] = 3
Matrix[1][4] = 4
Matrix[2][1] = 2
Matrix[2][2] = 3
Matrix[2][3] = 4
Matrix[2][4] = 5
Matrix[3][1] = 3
Matrix[3][2] = 4
Matrix[3][3] = 5
Matrix[3][4] = 6
#include<stdio.h>
#include<math.h>
int main()
{
int count, t, limit;
float temp, error, a, sum = 0;
float matrix[10][10], y[10], allowed_error;
printf("\nEnter the Total Number of Equations:\t");
scanf("%d", &limit);
printf("Enter Allowed Error:\t");
scanf("%f", &allowed_error);
printf("\nEnter the Co-Efficients\n");
for(count = 1; count <= limit; count++)
{
for(t = 1; t <= limit + 1; t++)
{
printf("Matrix[%d][%d] = ", count, t);
scanf("%f", &matrix[count][t]);
}
}
for(count = 1; count <= limit; count++)
{
y[count] = 0;
}
do
{
a = 0;
for(count = 1; count <= limit; count++)
{
sum = 0;
for(t = 1; t <= limit; t++)
{
if(t != count)
{
sum = sum + matrix[count][t] * y[t];
}
}
temp = (matrix[count][limit + 1] - sum) / matrix[count][count];
error = fabs(y[count] - temp);
if(error > a)
{
a = error;
}
y[count] = temp;
printf("\nY[%d]=\t%f", count, y[count]);
}
printf("\n");
}
while(a >= allowed_error);
printf("\n\nSolution\n\n");
for(count = 1; count <= limit; count++)
{
printf("\nY[%d]:\t%f", count, y[count]);
}
return 0;
}
Your code is correct. The issue is that Gauss-Seidel method does not always converge. The convergence criteria is that the matrix A must be either:
symmetric positive-definite
strictly or irreducibly diagonally dominant
The input matrix you used is neither symmetric, nor diagonally-dominant. Hence, the method fails to converge to a solution.

Checking 5 ints in an array if 3 are the same

I have a int array that contains five random numbers. I am trying to check if three of the numbers match.
int die[5] = {2, 3, 5, 2, 1};
int kind = 0;
int score = 0;
int i = 0;
int x = 0;
for (i; i <= 4; i++) {
for (x; x <= 4; x++) {
if (die[i] == die[x]) {
kind++;
score += die[i];
}
}
}
The issue I am running into is the very first case it will compare itself to itself. Which will always come back true. And if I add a +1 to the index, it will end up going out of bounds.
If I start at 1 instead of 0, then when it goes to the second digit, it will return the same once it checks itself against the 2nd number(itself).
You could check if i equals j and just continue; your loop.
for(i=0; i<=4; i++){
// you can set x=i+1 and skip some numbers
for(x=0; x<=4; x++){
if(i==x)
continue;
if (die[i] == die[x]) {
kind++;
score += die[i];
}
}
}
EDIT:
There are simpler ways of doing this (checking if 3 numbers are equal), but if you just want to skip an iteration, use continue.
int die[5] = {2, 3, 5, 2, 1};
int kind = 0;
int score = 0;
for (i = 0; i < 4; i++) { // last check will be die[3] == die[4] to avoid
// die[4] == die[4]
for (x = i + 1 ; x < 5; x++) { // it always checks with the next element
if (die[i] == die[x]) {
kind++;
score += die[i];
}
}
}

Is it the efficeint program to rotate array in left direction?

#include<stdio.h>
#include<stdlib.h>
main()
{
int i,j,l,m,n;
j=0;
printf("\nenter 5 element single dimension array\n");
printf("enter shift rate\n");
scanf("%d",&n);
/* Here we take input from user that by what times user wants to rotate the array in left. */
int arr[5],arrb[n];
for(i=0;i<=4;i++){
scanf("%d",&arr[i]);
}
/* Here we have taken another array. */
for(i=0;i<=4;i++){
printf("%d",arr[i]);
}
for(i=0;i<n;i++){
arrb[j]=arr[i];
j++;
// These loop will shift array element to left by position which's entered by user.
}
printf("\n");
for(i=0;i<=3;i++){
arr[i]=arr[i+n];
}
for(i=0;i<=4;i++){
if(n==1 && i==4)
break;
if(n==2 && i==3)
break;
if(n==3 && i==2)
break;
printf("%d",arr[i]);
}
//To combine these two arrays. Make it look like single array instead of two
for(i=0;i<n;i++){
printf("%d",arrb[i]);
}
// Final sorted array will get printed here
}
Is it the efficeint program to rotate array in left direction?
Actually, very complicated, and some problems contained:
for(i = 0; i < n; i++)
{
arrb[j] = arr[i];
j++;
}
Why not simply:
for(i = 0; i < n; i++)
{
arrb[i] = arr[i];
}
There is no need for a second variable. Still, if n is greater than five, you get into trouble, as you will access arr out of its bounts (undefined behaviour!). At least, you should check the user input!
for(i = 0; i <=3 ; i++)
{
arr[i] = arr[i + n];
}
Same problem: last accessible index is 4 (four), so n must not exceed 1, or you again access the array out of bounds...
Those many 'if's within the printing loop for the first array cannot be efficient...
You can have it much, much simpler:
int arr[5], arrb[5];
// ^
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(i + n) % 5];
This does not cover negative values of n, though.
arrb[i] = arr[(((i + n) % 5) + 5) % 5];
would be safe even for negative values... All you need now for the output is:
for(int i = 0; i < 5; ++i)
printf("%d ", arrb[i]);
There would be one last point uncovered, though: if user enters for n a value greater than INT_MAX - 4, you get a signed integer overflow, which again is undefined behaviour!
We can again cover this by changing the index formula:
arrb[i] = arr[(5 + i + (n % 5)) % 5];
n % 5 is invariant, so we can move it out of the loop:
n %= 5;
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(5 + i + n) % 5];
Finally, if we make n positive already outside, we can spare the addition in the for loop.
n = ((n % 5) + 5) % 5;
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(i + n) % 5]; // my original formula again...
Last step is especially worth considering for very long running loops.
I think you want to do something like this (you should check that 0 <= n <= 5, too):
int b[5];
int k = 0;
for(i=0; i<5; i++){
if (i < 5 - n)
b[i] = arr[i+n];
else
{
b[i] = arr[k];
k++;
}
}
Array b is used to save the rotated matrix.

How can I make a new array, by counting the no.of appearances of value and printing it next to that value?

I should make new array out of existing one (ex. 1 0 4 5 4 3 1) so that the new one contains digits already in existing array and the number of their appearances.
So, the new one would look like this: 1 2 0 1 4 2 5 1 3 1 (1 appears 2 times, 0 appears 1 time.... 3 appears 1 time; the order in which they appear in first array should be kept in new one also); I know how to count no. of times a value appears in an array, but how do I insert the no.of appearances? (C language)
#include <stdio.h>
#define max 100
int main() {
int b, n, s, i, a[max], j, k;
printf("Enter the number of array elements:\n");
scanf("%d", &n);
if ((n > max) || (n <= 0)) exit();
printf("Enter the array:\n");
for (i = 0; i < n; i++)
scanf("%d", a[i]);
for (i = 0; i < n; i++) {
for (j = i + 1; j < n;) {
if (a[j] == a[i]) {
for (k = j; k < n; k++) {
a[k] = a[k + 1];
}}}}
//in the last 5 rows i've tried to compare elements, and if they are same, to increment the counter, and I've stopped here since I realised I don't know how to do that for every digit/integer that appears in array//
If you know that the existing array consists of digits between 0 and 9, then you can use the index of the array to indicate the value that you are incrementing.
int in[12] = {1,5,2,5,6,5,3,2,1,5,6,3};
int out[10] = {0,0,0,0,0,0,0,0,0,0};
for (int i = 0; i < 12; ++i)
{
++out[ in[i] ];
}
If you provide any code snippet, its easy for the community to help you.
Try this, even you optimize the no.of loops :)
#include <stdio.h>
void func(int in[], int in_length, int *out[], int *out_length) {
int temp[10] = {0}, i = 0, j = 0, value;
//scan the input
for(i=0; i< in_length; ++i) {
value = in[i];
if(value >= 0 && value <= 9) { //hope all the values are single digits
temp[value]++;
}
}
// Find no.of unique digits
int unique_digits = 0;
for(i = 0; i < 10; ++i) {
if(temp[i] > 0)
unique_digits++;
}
// Allocate memory for output
*out_length = 2 * unique_digits ;
printf("digits: %d out_length: %d \n",unique_digits, *out_length );
*out = malloc(2 * unique_digits * sizeof(int));
//Fill the output
for(i = 0, j = 0; i<in_length && j < *out_length; ++i) {
//printf("\n i:%d, j:%d val:%d cout:%d ", i, j, in[i], temp[in[i]] );
if(temp[in[i]] > 0 ) {
(*out)[j] = in[i];
(*out)[j+1] = temp[in[i]];
temp[in[i]] = 0; //Reset the occurrences of this digit, as we already pushed this digit into output
j += 2;
}
}
}
int main(void) {
int input[100] = {1, 0, 4, 5, 4, 3, 1};
int *output = NULL, output_length = 0, i = 0;
func(input, 7, &output, &output_length );
for(i=0; i < output_length; i+=2) {
printf("\n %d : %d ", output[i], output[i+1]);
}
return 0;
}

How can I calculate the moving average of the array?

In Question, When an array X of size n and a degree k are input,
Write a program that calculates the k-th moving average of array X.
The kth-order moving average of the array X consisting of primitive data values is the average of the last k elements up to the i-th point of X.
That is, A [i] = (X [i-k + 1] + X [i-k + 2] + ... + X [i]) / k.
If the number of the preceding element (including itself) is smaller than k,
Calculate as an average.
For example, if array X is as follows and k is 3, X = 1 3 2 10 6 8
The third moving average is as follows.
A = 1 2 2 5 6 8 A [1] = (1 + 3) / 2, A [2] = (1 + 3 + 2) / 3
However, the program must have the execution time of O (n), not O (nk).
Round off the decimal point in the average calculation and obtain it as an integer.
For exact rounding, do not use% .f, but round it using the int property.
int main()
{
int i, n1, k;
int *array1;
scanf("%d", &n1);
array1 = (int *)malloc(sizeof(int)*n1);
scanf("%d", &k);
for (i = 0; i < n1; i++)
{
scanf("%d", &array1[i]);
}
double tmp = 0;
for (int i = 0; i < n1; i++)
{
tmp += array1[i];
if (i >= k)
{
tmp -= array1[i - k];
}
if (i >= k - 1)
{
double average = tmp / k;
printf("%2lld ", llrint(average));
}
return 0;
}
The program does not work because the problem is not understood.
I would like to know how to solve it.
add) Thank you for answer but the output required by the problem is as follows.
Input : 9 4 (n = 9, k = 3)
2 7 4 5 6 8 2 8 13
Output : 2 5 4 5 6 6 5 6 8
After Modifying your code
int main()
{
int i, n1, k;
int *array1, *array2;
scanf("%d", &n1);
array1 = (int *)malloc(sizeof(int)*n1);
scanf("%d", &k);
for (i = 0; i < n1; i++)
{
scanf("%d", &array1[i]);
}
double tmp = 0;
for (int i = 0; i < n1; i++)
{
tmp += array1[i];
// now tmp contains exactly k + 1 elements sum
// so subtract elements outside of k sized window(leftmost element)
if(i >= k) {
tmp -= array1[i - k];
}
if(i >= k - 1) {
double average = tmp / k;
printf("%lf\n", average);
}
}
return 0;
}

Resources