Sorting a matrix in descending order in C - c

I need to input a matrix, where the first element of a row is the student ID number, and the other 12 elements are student points and GPA. Each row represents one student. What the program needs to do is calculate the total point amount, and then sort the matrix so it goes in descending order by the amount of points.
This is my code:
#include <stdio.h>
int main() {
int number_of_students,i,j;
double matrix[50][50],GPA,grades,total,GPA_before;
printf("Number of students: ");
scanf("%d", &number_of_students);
printf("Input students: ");
for(i=0; i<number_of_students; i++){
for(j=0; j<12; j++){
scanf("%lf", &matrix[i][j]);
}
}
printf("Final list: \n");
for(i=0; i<number_of_students; i++){
GPA_before=(matrix[i][2]+matrix[i][3]+matrix[i][4]+matrix[i][5])*2.5;
if(GPA_before==50){
GPA=GPA_before+3;
}
else{
GPA=GPA_before;
}
grades=(matrix[i][6]+matrix[i][7]+matrix[i][8]+matrix[i][9]+matrix[i][10]+matrix[i][11])*0.67;
total=GPA+grades+matrix[i][12];
printf("%d. %g | %g\n",i,matrix[i][1],total);
}
return 0;
}
And this is what I get:
Number of students: 4
Input students: 123456 4.00 4.50 5.00 5.00 5 5 5 4 4 5 15
456789 4.50 5.00 4.00 3.50 3 5 4 5 5 2 10
789321 5.00 5.00 4.50 3.00 5 4 5 3 5 3 15
456987 4.50 4.50 4.50 5.00 4 4 4 5 5 5 25
Final list:
1. 123456 | 80.01
2. 456789 | 68.58
3. 789321 | 75.5
4. 456987 | 89.34
The matrix should be sorted from highest number of points to the lowest, not by ID. It is specified not to sort the list while printing it out, the matrix itself must be sorted.
I would really appreciate the help.

Firstly, I saw a few things in your code that I would like to point out and change, if possible.
You are allocating an 2-D Array of 50 rows and 50 columns. However, you're only utilizing 12 of those columns. So, first thing that I would like you to fix is the use of those extra unnecessary array indexes. So, I wrote the following code:
const int MAX = 50;
const int NUM_INPUTS = 12;
int number_of_students, i, j;
double matrix[MAX][NUM_INPUTS + 1], GPA, grades, total;
Note: I added NUM_INPUTS + 1, that we will use to store the total of that you were calculating in the loop and also printing it too.
Now, another thing I would like to point out, is your use of loops. You're iteration is beginning from the index 1. You're not using the 0th index. So, you'll have to fix each loop from this:
for(i=1; i<=number_of_students; i++){
for(j=1; j<=12; j++){
scanf("%lf", &matrix[i][j]);
}
}
to this:
for (i = 0; i < number_of_students; i++) {
for (j = 0; j < NUM_INPUTS; j++) {
scanf("%lf", &matrix[i][j]);
}
}
Now, this indexing from 0 will cause the code that you wrote for the calculations, to not work properly, so, you will have to fix that too:
for(i=1; i<=number_of_students; i++){
GPA_before=(matrix[i][2]+matrix[i][3]+matrix[i][4]+matrix[i][5])*2.5;
if(GPA_before==50){
GPA=GPA_before+3;
}
else{
GPA=GPA_before;
}
grades=(matrix[i][6]+matrix[i][7]+matrix[i][8]+matrix[i][9]+matrix[i][10]+matrix[i][11])*0.67;
total=GPA+grades+matrix[i][12];
You were using this code in-junction with printf. I used this code to calculate the total and then store it in the index matrix[i][NUM_INPUTS].
Now, I slightly changed your code and loop for storing the total in the matrix itself becomes:
for (i = 0; i < number_of_students; i++) {
GPA = (matrix[i][1] + matrix[i][2] + matrix[i][3] + matrix[i][4]) * 2.5;
if (GPA == 50) {
GPA += 3;
}
grades = (matrix[i][5] + matrix[i][6] + matrix[i][7] + matrix[i][8] + matrix[i][9] + matrix[i][10]) * 0.67;
total = GPA + grades + matrix[i][11];
matrix[i][NUM_INPUTS] = total;
}
Now, this made it easy for me to implement a basic Bubble Sort algorithm to sort your matrix:
int k;
for (i = 0; i < number_of_students; i++) {
for (j = 0; j < number_of_students - 1; j++) {
if (matrix[j][NUM_INPUTS] > matrix[j + 1][NUM_INPUTS]) {
double temp;
for (k = 0; k < NUM_INPUTS + 1; k++) {
temp = matrix[j][k];
matrix[j][k] = matrix[j + 1][k];
matrix[j + 1][k] = temp;
}
}
}
}
Now, since the matrix itself has been sorted, we will simply print the final matrix:
for (i = 0; i < number_of_students; i++) {
printf("%d. %g | %g\n", i + 1, matrix[i][0], matrix[i][NUM_INPUTS]);
}
Note: One more thing you can do (totally for input validation) is write an if statement, that would check if the user input for number of students is in the range of 1 <= number_of_students <= MAX (50), if it is greater than that, it would cause an out-of-bounds exception or a Buffer Overflow.
if(number_of_students > MAX || number_of_students <= 0) {
printf("Invalid number of students");
return 1;
}
I hope you understood what I wrote and would love if you'd upvote as this is my first answer here.
Here's the full source code:
#include <stdio.h>
int main() {
const int MAX = 50;
const int NUM_INPUTS = 12;
int number_of_students, i, j;
double matrix[MAX][NUM_INPUTS + 1], GPA, grades, total;
printf("Number of students: ");
scanf("%d", &number_of_students);
if(number_of_students > MAX || number_of_students <= 0) {
printf("Invalid number of students");
return 1;
}
printf("Input students: ");
for (i = 0; i < number_of_students; i++) {
for (j = 0; j < NUM_INPUTS; j++) {
scanf("%lf", &matrix[i][j]);
}
}
// Firstly calculating the total and storing it in the final index of the matrix:
for (i = 0; i < number_of_students; i++) {
GPA = (matrix[i][1] + matrix[i][2] + matrix[i][3] + matrix[i][4]) * 2.5;
if (GPA == 50) {
GPA += 3;
}
grades = (matrix[i][5] + matrix[i][6] + matrix[i][7] + matrix[i][8] + matrix[i][9] + matrix[i][10]) * 0.67;
total = GPA + grades + matrix[i][11];
matrix[i][NUM_INPUTS] = total;
}
// Sorting this based on total:
for (i = 0; i < number_of_students; i++) {
for (j = 0; j < number_of_students - 1; j++) {
if (matrix[j][NUM_INPUTS] > matrix[j + 1][NUM_INPUTS]) {
double temp;
for (int k = 0; k < NUM_INPUTS + 1; k++) {
temp = matrix[j][k];
matrix[j][k] = matrix[j + 1][k];
matrix[j + 1][k] = temp;
}
}
}
}
printf("Final list:\n");
for (i = 0; i < number_of_students; i++) {
printf("%d. %g | %g\n", i + 1, matrix[i][0], matrix[i][NUM_INPUTS]);
}
return 0;
}

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.

How can we replace the higest 5 numbers in an array of 10 with 1 and smallest 5 into 0 in C programing?

Here's the question my teacher gave me
Write a C program to store 10 integers in an array of size 10 and
display the contents of the array. Replace the highest 5 numbers in the array by
1 and lowest 5 numbers by 0 and display the contents of the new array.
[For e.g.
Original Array
44 11 6 99 30 78 32 31 66 55
New Array
1 0 0 1 0 1 0 0 1 1
I have been struggling in this question whole day :(
There are a lot of ways to solve this problem. A good way would be sort the array into another array and then replace the 1st half with 0s and the second half with 1s like this:
#include<stdio.h>
int main(){
const int arraySize = 10;
int i, j;
int arr[arraySize];
int arrSorted[arraySize];
int temp;
// Get input from user
printf("Please enter 10 numbers!\n");
for (i = 0; i < arraySize; i++)
{
scanf("%d", &arr[i]);
// Copy array into another to sort it later
arrSorted[i] = arr[i];
}
// Print input
printf("Input: ");
for (i = 0; i < arraySize; i++)
{
printf("%3d ", arr[i]);
}
printf("\n");
//Sort the array in ascending order
for (i = 0; i < arraySize; i++)
{
for (j = i + 1; j < arraySize; j++)
{
if(arrSorted[i] > arrSorted[j])
{
temp = arrSorted[i];
arrSorted[i] = arrSorted[j];
arrSorted[j] = temp;
}
}
}
// Start replacing procedure
for (i = 0; i < arraySize; i++)
{
for (j = 0; j < arraySize; j++)
{
if (arr[j] == arrSorted[i])
{
if (i < arraySize / 2) // Replace 1st half with 0s
{
arr[j] = 0;
}
else // Replace 2nd half with 1s
{
arr[j] = 1;
}
break;
}
}
}
// Print result
printf("Result: ");
for (i = 0; i < arraySize; i++)
{
printf("%3d ", arr[i]);
}
printf("\n");
return 0;
}
Of course, you can use the C standard library qsort() function if you don't want to sort yourself.
Another solution would be, find the median number of the array then replace any number which is less than it with 0 and any number bigger than it with 1. Although with this solution there will be some challenges regarding what to do with the median number itself and what if there are multiple median numbers (duplicated)?

How to write the algorithm of this matrix in this ascending order in C.Where is error in my code?

I am writing this code to print the following matrix in this spiral order(spiral by column).But my code is printing totally different thing.
a a+7 a+8 a+15
a+1 a+6 a+9 a+14
a+2 a+5 a+10 a+13
a+3 a+4 a+11 a+12
Here is what i did:
int main() {
int a;
int Sum = 0;
int i = 0, j = 0,n;
printf("Insert the value of n: ");
scanf("%d",&n);
printf("Insert the value of a number: ");
scanf("%d",&a);
for(i=0;i<n;i++){
for(j=0;j<n;j++){
printf("%d ",a);
a = a + 7;
printf("\t");
}
printf("%d",a);
a = a + 1 ;
printf("\n");
}
return 0;
}
The way I approached this is to build the matrix of values you actually want, but doing so in column order, where we can relatively easily control the logic of value progression by row. Then, with that matrix in hand, print out the values in row order, as you want the output:
int main()
{
int a = 7;
int n = 4;
int array[4][4];
for (int c=0; c < n; ++c)
{
for (int r=0; r < n; ++r)
{
// values ascending for even columns
if (c % 2 == 0)
{
array[r][c] = a + c*n + r;
}
// values descending for odd columns
else
{
array[r][c] = a + c*n + n-r-1;
}
}
}
for (int i=0; i < n; ++i)
{
for (int j=0; j < n; ++j)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
}
Output:
Demo here:
Rextester
Instead of using this complex mechanism to keep track of all elements you can just calculate the value to add at any time by simple arithmetic.
See this
int row;
int column;
printf("\n");
for (row = 0; row < n; row++) {
for (column = 0; column < n; column++) {
int base;
int flag;
if (column % 2 != 0) {
base = (column+1)/2 * 2*n - 1;
flag = -1;
}else {
base = column/2 * 2*n;
flag = 1;
}
printf( "%d ", a + base + flag * row);
}
printf("\n");
}
I hope you are able to follow this logic. If not feel free to ask.
Demo here:
Ideone
There seem to be two issues with your code as it is. As mentioned in the above comment, you are using the variable a in the loop calculation, so it is constantly being updated. This means your loop becomes invalid after a few iterations. If you define a dummy variable, this would avoid the problem. Secondly the implementation of the spiralling is close to being right, but it's not quite there.
Consider in the case n = 4. When you print along each row, the difference between a new element and the last alternates between values of (2n - 1) = 7 and 1. To take this into account, you could for example check every time you want to print whether the column index (j) is odd or even, and use this to determine which difference to add. Once you have the row machinery fixed, it shouldn't be difficult to extend it to the columns.
Simple solution using a matrix to calculate values before print them
#include <stdio.h>
int main(void)
{
int a;
int i = 0, j = 0, n;
printf("Insert the value of n: ");
scanf("%d", &n);
printf("Insert the value of a number: ");
scanf("%d", &a);
int matrix[n][n];
for (i=0; i< n*n; i++)
{
// even columns ascending
if (((i/n) % 2) == 0)
{
matrix[i%n][i/n] = a++;
}
// odd column descending
else
{
matrix[n-(i%n)-1][i/n] = a++;
}
}
for (i=0; i< n; i++)
{
for (j=0; j< n; j++)
{
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
return 0;
}
Output
Insert the value of n: 4
Insert start value: 1
1 8 9 16
2 7 10 15
3 6 11 14
4 5 12 13

integers are being repeated?

I'm writing a program that reads integers from keyboard input and find the occurrence then sort them in descending order.
I got the occurrence and the descending but when I type same integers, they are repeated if I type 8 7 8
it's like
8 2
8 2
7 1
help please??
This is my code
#pragma warning (disable :4996)
#include <stdio.h>
#include <stdlib.h>
int main(){
int input;
int inputarr[50], count[50] = {0};
int i=0, j;
int last = 0;
printf("Enter numbers \n");
///getting int
while (scanf("%d", &input) > 0)
{
inputarr[i] = input;
i++;
}
last = i;
printf(" N Count\n");
printf("----- -----\n");
int a;
/// increment count
for (i = 0; i < last; i++){
count[inputarr[i]] = count[inputarr[i]] + 1;
}
/////ascending
for (i = 0; i < last; i++)
{
for (j = 0; j < last; j++){
if (inputarr[j]<inputarr[j + 1])
{
int temp = inputarr[j];
inputarr[j] = inputarr[j + 1];
inputarr[j + 1] = temp;
}
}
printf(" %d %d\n", inputarr[i], count[inputarr[i]]);
}
return 0;
}
The problem with this code is that you are printing the array while it's being sorted. Inputing numbers 1 2 3 4 would result in numbers 2 1 4 1 2 1 1 1 being outputed. To accomplish what you wanted you should move the printing part out of the sorting loop. Even then when a number is appearing multiple times in the input the output won't contain it only once (ex. 8 7 8 -> 8 2 8 2 7 2). To do that you should not output the number if it is the same as the previous number you outputed.
Another thing, in the sorting loop you are potentially accessing non existing array elements at the line
for (j = 0; j < last; j++){
When j = last-1 you are accessing last element which might not exsist.
After fixing all this problems code might look like this:
for (i = 0; i < last; i++)
{
for (j = 0; j < last-1; j++){
if (inputarr[j]<inputarr[j + 1])
{
int temp = inputarr[j];
inputarr[j] = inputarr[j + 1];
inputarr[j + 1] = temp;
}
}
}
if (last == 0)
return 0;
printf(" %d %d\n", inputarr[0], count[inputarr[0]]);
for(i = 1; i < last; i++)
if (inputarr[i] != inputarr[i-1])
printf(" %d %d\n", inputarr[i], count[inputarr[i]]);

Rolling Dice Histogram

Hello I have written the code needed for a dice rolling generator base on rand() and time.h.
It basically asks the user to input the number of times he wants the dice to be rolled and then rolls those X times. It saves the times each one of 1-6 number was rolled in an array and the percentage of each number in another array.
Now what I want to do is create a histogram the has the numbers 1-6 and - on the X-axis, the percentages and | on the Y-axis and stars(*) for columns.
Something like this:
10% | *
8% |* * *
6% |* * * * *
4% |* * * * * *
2% |* * * * * *
+------------
1 2 3 4 5 6
I have search throught google to find something to begin with but I have really found anything similar to my case thats gonna help me begin with.
My code thus for is:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int random_number();
float calc_percentage(int totals, int nums);
float calc_maxper(float perc[6]);
float calc_minper(float perc[6]);
float permin;
float permax;
int main(void)
{
int nums;
int i;
int totals[6] = {0};
float percentages[6] = {0};
srand(time(NULL));
printf("How many numbers to generate?");
scanf("%d", &nums);
for (i = 1; i <= nums; i++)
{
int x = random_number();
totals[x-1]++;
}
for (i = 0; i<6; i++)
{
percentages[i] = calc_percentage(totals[i],nums);
printf("The percentage of each number is: %.2f%\n", percentages[i]);
}
permin = calc_minper(percentages);
permax = calc_maxper(percentages);
if (((permax) - (permin)) > 5)
printf("The generator is not good.\n");
printf("The percentage difference is:%.1f\n", permax-permin);
system("pause");
return 0;
}
int random_number()
{
int randnum;
randnum = 1 + (rand() % 6);
return randnum;
}
float calc_percentage(int totals, int numbers)
{
float a;
a = (totals * 100)/numbers;
return a;
}
float calc_minper(float perc[6])
{
int i;
float min;
min = perc[0];
for (i=1; i<6; i++)
{
if (perc[i] < min)
min = perc[i];
}
return min;
}
float calc_maxper(float perc[6])
{
int i;
float max;
max = perc[0];
for (i=1; i<6; i++)
{
if (perc[i] > max)
max = perc[i];
}
return max;
}
Ok I finally got this done.
Kinda long and messy but it definitely gets the job done!!
printf("20%|");
for (i=0; i<6; i++)
{
if (percentages[i] >= 20)
printf("* ");
}
printf("\n");
printf("16%|");
for (i=0; i<6; i++)
{
if (percentages[i] >= 16)
printf("* ");
}
printf("\n");
printf("12%|");
for (i=0; i<6; i++)
{
if (percentages[i] >= 12)
printf("* ");
}
printf("\n");
printf(" 8%|");
for (i=0; i<6; i++)
{
if (percentages[i] >= 8)
printf("* ");
}
printf("\n");
printf(" 4%|");
for (i=0; i<6; i++)
{
if (percentages[i] >= 4)
printf("* ");
}
printf("\n");
printf(" +------------\n");
printf(" 1 2 3 4 5 6\n");
Thanks dude for your ideas!!
If u have any quick ideas to make it shorter am all ears!
For each range (10%, 8%, etc), check if the current dice number (1-6) percentage exceeds it, then print a * (or a space if it doesn't meet the range minimum). At the end, print the graph base.
You could use a for to handle the ranges:
float range;
float interval = (permax-permin)/(NUM_INTERVALS-1);
for (range = permax; range >= permin - EPSILON; range -= interval){
int i;
printf("%2.2f%% | ", range);
for(i=0; i<6; i++){
char *out = percentages[i] >= range ? "*" : " ";
printf("%s ", out);
}
printf("\n");
}
printf(" | 1 2 3 4 5 6\n");

Resources