The problem starts near the very bottom of the array. I print percent[x] values to make sure they are there, and then after the sort, three of them are filled with zeros. I've been looking around for awhile but I can't find anything.
#include <stdio.h>
int main()
{
int votes[5][4]={192,48,206,37,
147,90,312,21,
186,12,121,38,
114,21,408,39,
267,13,382,29};
char cand[4]={'A','B','C','D'};
int row_totals[5];
int col_totals[4]; //This is left for you to do
//see code below to see how
//row_totals were calculated.
int total_votes;
//use a for loop to calculate
//using either row_totals or col_totals
float percent[4]; //use a for loop to calculate based on
int swap; //total_votes and col_totals
//be sure to print the totals for the candidates
//at the end, you will need to sort the percent array
//bringing along the values from the cand array. That is
//if a swap is made in the percent array, do the same
//swap in the cand array.
//then if percent[3] is greater than 50, declare cand[3] the winner
//if percent[3] is not greater than 50, declare a run-off
//between cand[2] and cand[3]
int row,col;
for(row=0;row<=4;row++) // used to find the row total
{
row_totals[row]=0;
for(col=0;col<=3;col++)
{
row_totals[row] += votes[row][col];
}
}
for(col=0; col <=3; col++)
{
col_totals[col]=0;
for(row =0; row <= 4; row++) // used to find the column total
{
col_totals[col] += votes[row][col];
}
}
for(row =0; row<=4; row++)
{
total_votes += row_totals[row]; //finds the total amount of the votes
}
printf(" Candidate Candidate Candidate Candidate Total\n");
printf(" Precinct: A B C D Votes\n");
for(row=0;row<=4;row++)
{
printf("%6d",row+1);
for(col=0;col<=3;col++)
{
printf("%12d",votes[row][col]);
}
printf("%11d\n",row_totals[row]);
}
printf("Total\nVotes:");
for(col=0; col<=3; col++)
{
printf("%12d", col_totals[col]);
}
printf(" %d", total_votes);
printf("\nPrecentage:");
for(col=0; col <= 3; col++)
{
percent[col] = (col_totals[col] / (double)total_votes); //calculates percentages
printf("%11f", percent[col]);
}
int x,y;
for(x=0; x<=3; x++)
{
printf("\n%f", percent[x]);
}
for(x=0; x<3; x++)
{
for(y=0;y<(3-x); y++)
{
if(percent[y] > percent[y+1])
{
swap = percent[y];
percent[y] = percent[y+1];
percent[y+1]= swap;
}
}
}
for(col=0; col<4; col++)
{
printf("\n%f", percent[col]);
}
return 0;
Your temporary variable for swapping is an integer, but the values you swap are floats between 0 and 1, which will become zero on conversion to int.
The error is hard to spot, because the temporary variable in declared at the top of the long main function, far away from the actual swapping code. You could make the temporary variable a local variable to the swapping scope:
for (x = 0; x < 3; x++) {
for (y = 0; y < (3 - x); y++) {
if (percent[y] > percent[y + 1]) {
float swap = percent[y];
percent[y] = percent[y + 1];
percent[y + 1] = swap;
}
}
}
Other issues:
Your total_votes isn't initialised to zero.
Please consider writing your loops as
for (row = 0; row < nrows; row++) ...
instead of
for (row = 0; row <= nrows - 1; row++) ...
This is a common C idiom. Your loops use hard-coded values, but later you might want to have variable limits as in the two examples above, where the "less than the number of items" variant is more readable.
When you print, new-lines should be at the end of your print formats, not at the beginning. This is the natural way of printing. It also has the benefit that the output buffer will be flushed when printing a newline to the console.
This is minor, but pick one floating-point type. You use float, but calculate your percentage with double. I recommend double, which is the standard floating-point type on modern machines.
Related
I have been trying to compute product of a 2-D array with a 1-D array using bitwise operators. For the 2-D array I have a 512 x 32 size "matrix" and the 1-D array is 32 x 1 size "vector". For my application, I want to multiply the matrix[0][0] with vector[0] and store it as one value and then matrix[0][1] with vector[1] and store that value and so on till I get the first row as 32 values.
Thereafter, I want to repeat the same operations for 512 rows so that at the end I get a 512 x 32 matrix.
I know this is not how a matrix vector multiplication is done. But, for the application I am working on, it is important that I first achieve it this way before moving ahead.
Below is the code snippet in C that I have written:
for(i = 0; i<512; i++)
{
for(j = 0; j<32; j++)
{
while (vector[j] != 0)
{
if (vector[j] & 1)
{
result[i][j] += matrix[i][j];
}
matrix[i][j] <<= 1;
vector[j] >>= 1;
}
}
}
I have declared result[i][j] of size 512 x 32. The values of "matrix" and "vector" are randomized as in I have used rand()%200 to assign random values to these.
The problem I am facing is that upon execution I am getting result[0][j] only i.e. only the first row of the result. Rest all rows it is printing as zeros (0) only.
I have trying to figure this out from a couple of days but I am stuck. Could someone please tell me where am I going wrong? And, what should I do to achieve the desired result?
P.S - Please forgive for any silly mistakes as I not fully conversant with C
You do not decrease the variable if the number is odd.
You need some temporary variables for calculations.
You do not want to vector[j] >>= 1; which divides it by two - you want to subtract 2
It is much easier if you divide the problem into smaller chunks. Use functions for that.
If you multiply signed integers you need to take into the account the sign as well.
unsigned mult(unsigned x, unsigned y)
{
unsigned result = 0;
while(y)
{
if(y & 1)
{
result += x;
y--;
}
else
{
result += x << 1;
y -= 2;
}
}
return result;
}
https://godbolt.org/z/x4dG59cK4
and matrix version
void mult(size_t rows, size_t cols, unsigned (*x)[cols], unsigned (*y)[cols])
{
for(size_t row = 0; row < rows; row++)
{
for(size_t col = 0; col < cols; col++)
{
unsigned result = 0;
unsigned y1 = y[row][col];
while(y1)
{
if(y1 & 1)
{
result += x[row][col];
y1--;
}
else
{
result += x[row][col] << 1;
y1 -= 2;
}
}
x[row][col] = result;
}
}
}
Hi i need to check if the array is symmetry or not. i have a function that takes in a two-dimensional array of integer numbers M and the array sizes for rows and columns as parameters, and returns 1 if M is symmetric or 0 otherwise. I tried many times but the output will be either yes to non-symmetric array or no to symmetric array
Here is my code:
#include <stdio.h>
#define SIZE 10
#define INIT_VALUE -1
int symmetry2D(int M[][SIZE], int rowSize, int colSize);
int main()
{
int M[SIZE][SIZE], i, j, result = INIT_VALUE;
int rowSize, colSize;
printf("Enter the array size (rowSize, colSize): \n");
scanf("%d %d", &rowSize, &colSize);
printf("Enter the matrix (%dx%d): \n", rowSize, colSize);
for (i = 0; i < rowSize; i++)
for (j = 0; j < colSize; j++)
scanf("%d", &M[i][j]);
result = symmetry2D(M, rowSize, colSize);
if (result == 1)
printf("symmetry2D(): No\n");
else if (result == 0)
printf("symmetry2D(): Yes\n");
else
printf("Error\n");
return 0;
}
int symmetry2D(int M[][SIZE], int rowSize, int colSize)
{
int h, k, temp;
int result;
for (h = 0; h < rowSize; h++)
{
for (k = 0; k < colSize; k++)
{
M[h][k] = M[k][h];
}
}
result = 0;
for (h = 0; h < rowSize && result; h++)
{
for (k = 0; k < colSize; k++)
{
//if it is not equal to its transpose
if (M[h][k] != M[h][k])
{
result = 1;
break;
}
}
}
if (result == 0)
{
for (h = 0; h < rowSize; h++)
{
for (k = 0; k < colSize; k++)
{
return result = 0;
}
}
}
else
return result = 1;
}
Several issues:
By your definition, a matrix is symmetric if and only if it is equal to its transpose. That can be the case only for square matrices, yet you accommodate non-square matrices as well, for no apparent reason.
Your symmetry2D() function contains serious logical flaws:
It makes the input symmetric via the loop that performs M[h][k] = M[k][h]
Even if it did not do so, it would never find the input non-symmetric, because its test for that is if (M[h][k] != M[h][k]), which must always fail.
It's unclear what you think the if/else and loop nest at the end of symmetry2D() are achieving for you, but provided that rowSize and colSize are both greater than zero, the actual effect of the whole construct is the same as a simple return result;.
It looks like the idea might have been to create an array containing the transpose of the input, and then compare the input to that. That would have worked, despite being rather grotesquely inefficient, but you never in fact create that separate array for the transpose. If you're going to test without creating the transpose -- which you should -- then
Do not modify the input array (so remove the first loop nest altogether).
Get your indexing right for the symmetry comparisons: M[h][k] != M[k][h]
For best efficiency, avoid redundant and needless comparisons. For example, if you have already tested the M[1][2] == M[2][1] then you do not need to test whether M[2][1] == M[1][2]. And you never need to test elements on the main diagonal. You could achieve this efficiency pretty easily with a better choice of loop bounds.
Also, if indeed the symmetry2D() function is supposed to avoid modifying the input array, consider declaring the element type for its first argument to be const int instead of plain int (but do not modify the type of the corresponding variable in main()). If you had written it that way in the first place then the compiler would have noticed the function's logically erroneous attempt to modify the array elements, and rejected the code.
I have written code that allows you to enter one dimension of a NxN double array. It will then print random numbers in a 2D array and it finds the maximum and minimum number of each row. It then prints them and their coordinates (row and column).
ATTENTION!!!!
I have altered my code in such a way that it finds the minimum number of the maximum. I now don't know how to find it's coordinates
My code is as follows:
int N, i, j, min=1000, max, m , o;
time_t t;
int masyvas[100][100], minmax[100];
printf("Enter one dimension of a NxN array\n");
scanf("%d", &N);
srand((unsigned) time(&t));
for (i=0; i<N; i++)
{
for (j=0; j<N; j++)
{
masyvas[i][j] = rand() % 10;
printf("%4d", masyvas[i][j]);
}
printf("\n");
}
int k, l, idkeymax, idkeymin;
for(k=0; k<N; k++)
{
max=-1000;
for(l=0; l<N; l++)
{
if(max<masyvas[k][l])
{
max=masyvas[k][l];
}
}
minmax[k]=max;
}
for(m=0; m<N; m++)
{if(minmax[m]<min)
min=minmax[m];
}
printf("maziausias skaicius tarp didziausiu yra %d eiluteje %d stulpelyje %d\n",min);
Here's the pseudo code of what you need to do.
for row in grid {
row_max = max_in_row(row)
grid_min = min(grid_min, row_max)
}
Step one is to write a routine that finds the max and location in a list. You could do this as one big function, but it's much easier to understand and debug in pieces.
You also need the index where it was found. Since C can't return multiple values, we'll need a struct to store the number/index pair. Any time you make a struct, make routines to create and destroy it. It might seem like overkill for something as trivial as this, but it will make your code much easier to understand and debug.
typedef struct {
int num;
size_t idx;
} Int_Location_t;
static Int_Location_t* Int_Location_new() {
return calloc(1, sizeof(Int_Location_t));
}
static void Int_Location_destroy( Int_Location_t* loc ) {
free(loc);
}
Now we can make a little function that finds the max number and position in a row.
static Int_Location_t* max_in_row(int *row, size_t num_rows) {
Int_Location_t *loc = Int_Location_new();
/* Start with the first element as the max */
loc->num = row[0];
loc->idx = 0;
/* Compare starting with the second element */
for( size_t i = 1; i < num_rows; i++ ) {
if( row[i] > loc->num ) {
loc->num = row[i];
loc->idx = i;
}
}
return loc;
}
Rather than starting with some arbitrary max or min, I've used an alternative technique where I set the max to be the first element and then start checking from the second one.
Now that I have a function to find the max in a row, I can now loop over it, get the max of each row, and compare it with the minimum for the whole table.
int main() {
int grid[3][3] = {
{10, 12, 15},
{-50, -15, -10},
{1,2,3}
};
int min = INT_MAX;
size_t row = 0;
size_t col = 0;
for( size_t i = 0; i < 3; i++ ) {
Int_Location_t *max = max_in_row(grid[i], 3);
printf("max for row %zu is %d at %zu\n", i, max->num, max->idx);
if( max->num < min ) {
min = max->num;
col = max->idx;
row = i;
}
Int_Location_destroy(max);
}
printf("min for the grid is %d at row %zu, col %zu\n", min, row, col);
}
I used a different technique for initializing the minimum location, because getting the first maximum would require repeating some code in the loop. Instead I set min to the lowest possible integer, INT_MAX from limits.h which is highest possible integers. This allows the code to be used with any range of integers, there are no restrictions. This is a very common technique when working with min/max algorithms.
Alright so I thought my code was working and it seems to do so, it allows the user to choose the size of a magic square where the number one is the start point and starts in the center of the first row. The pattern goes along this line....go up one and over one, if you go up above the first row.....move back to the last row or if you run off the end of the right side of the column than go back to the start of the column...in a magic square if your not familiar with it, all sides are equal when the numbers on that side or diagonal are counted.
An odd number must be entered for this to be written out as a magic square (example: 3x3, 5x5, 7x7, etc..) the problem is it works until I enter 11x11....when done, it comes back around and when the program runs into a slot that has already been filled it is supposed to enter the next number below the last one that was entered into the array...but when 11x11 is entered it overwrites the 1 with a 13 which breaks the cycle and ruins the pattern....I would appreciate it if someone helped me with this, I think maybe the problem has to do with the equation I use to choose the starting point. This works all the way up to 11x11, every odd number entered after that seems to overwrite the starting point.
// Chapter 8 Programming Project #17
#include <stdio.h>
#define N_squared (N * N)
#define MOVE (--row, ++column)
#define RW_SIZE ((int) (sizeof(magic_square) / sizeof(magic_square[0])))
void create_magic_square(int N, int magic_square[N][N], int ROW_SIZE);
void print_magic_square(int N, int magic_square[N][N], int ROW_SIZE);
int main(void)
{
int N, row, column;
printf("This program creates a magic square of a specified size\n");
printf("The size must be an odd number between 1 and 99.\n");
printf("Enter size of magic square: ");
scanf("%d", &N);
int magic_square[N][N];
for (row = 0; row < N; row++) {
for (column = 0; column < N; column++) {
magic_square[row][column] = 0;
}
}
// Create magic square
create_magic_square(N, magic_square, RW_SIZE);
// Print magic square
print_magic_square(N, magic_square, RW_SIZE);
return 0;
}
void create_magic_square(int N, int magic_square[N][N], int ROW_SIZE)
{
printf("Size of N*N = %d\nSize of ROW_SIZE = %d\n", N_squared, ROW_SIZE);
// Here I iterate through the numbers, rows, and columns
int i = 1, row = 0;
int column = (((ROW_SIZE + 1) / 2) - 1);
while (i != N_squared + 1){
// if new position is empty place next number
if (magic_square[row][column] == 0) {
magic_square[row][column] = i;
i++;
// If new position is filled then move back and down
} else if (row + 2 < ROW_SIZE &&
column - 1 >= 0) {
row += 2;
column -= 1;
} else if (row + 2 > ROW_SIZE - 1 &&
column - 1 < 0) {
row = 1;
column = ROW_SIZE - 1;
}
// If current position has been set then move
if (magic_square[row][column] != 0)
MOVE;
// If row runs off the board reset
if (row < 0)
row = ROW_SIZE - 1;
// if column runs off the board reset
if (column > ROW_SIZE - 1)
column = 0;
}
}
void print_magic_square(int N, int magic_square[N][N], int ROW_SIZE)
{
int row, column;
printf("\n");
for (row = 0; row < ROW_SIZE; row++) {
for (column = 0; column < ROW_SIZE; column++) {
if (N > 9)
printf(" %3d ", magic_square[row][column]);
else
printf(" %2d ", magic_square[row][column]);
}
printf("\n\n");
}
}
Thanks for helping. I really appreciate it. I Have been searching for solution on SO, but nothing is exactly what I need. I need it in C.
My task is to find "largest square" of 1's in an array. The array consists of only 0's and 1's and looks, for example, like this:
4 4
0 1 1 1
0 1 0 1
0 1 1 1
1 0 1 0
Output should print [row][col] of "upper left corner" 1, and [row][col] of "lower right corner", So it should be, for my example, [0][1] and [2][3].
I am using my getcolor() function to get value on [row][col] spot.
Also, I have these functions to get longest horizontal and vertical lines. For some reason they only work with arrays with the same number of columns and rows. When I use, for example, an array with 4 cols and 5 rows, it does not work right. Aan you help me please?
void getHline(Bitmap *arr)
{
int i, j, k;
int line, line_start, line_end, line_max = 0;
// Horizontally
for (k = 0; k < arr->rows; k++)
{
for (i = 0; i < arr->rows; i++)
{
if(!getcolor(arr, k, i))
{
continue;
}
for(j = i; j < arr->cols; j++)
{
if(!getcolor(arr, k, j))
{
break;
}
}
j--;
if(j - i + 1 > line_max)
{
line = k;
line_start = i;
line_end = j;
line_max = line_end-line_start+1;
}
}
}
printf("horizontally\n");
printf("start: [%d][%d]\n", line_start, line);
printf("end: [%d][%d]\n", line_end, line);
}
void getVline(Bitmap *arr)
{
int i, j, k;
int col, col_start, col_end, col_max = 0;
for(k = 0; k < arr->cols; k++)
{
for (i = 0; i < arr->rows; i++)
{
if (!getcolor(arr,i,k)) continue;
for (j = i; j <arr->cols; j++)
{
if (!getcolor(arr,j,k)) break;
}
j--;
if (j - i + 1 >col_max)
{
col = k;
col_start = i;
col_end = j;
col_max = col_end-col_start+1;
}
}
}
printf("\nverticaly\n");
printf("start: [%d][%d]\n", col, col_start);
printf("end: [%d][%d]\n", col, col_end);
}
If you're trying to get the largest square this has noting to do with the longest horizontal and vertical lines, because they could be separated and no square associated with them.
When trying to solve a complex problem, don't try to solve it all at once.
The first thing we have, is that each point of the array is associated with a square (the largest one for each point). So we have to find that square: We take a point of the array, then we move by steps through a continuous horizontal and vertical lines. For each step we check if we get a square and repeat the process until we get the largest square associated with that single point.
Each time we get the largest square associated with a point we check if it's largest than the last largest square associated with some previous point.
After connecting these parts we get our final program.
Explanation of the variables used in the program:
Link to the program http://pastebin.com/Yw05Gbtg or view it here:
EDIT:
#include <stdio.h>
main()
{
int lines=4, cols=4;
int arr[4][4] = {
{0,1,1,1,},
{0,1,0,1,},
{0,1,1,1,},
{1,0,1,0,}
};
int x_start, y_start, x_end, y_end, d_max=0;
int i, j, k, l;
int col_start, line_start, col_end, line_end, checker;
for (y_start=0; y_start<lines; y_start++){
for (x_start=0; x_start<cols; x_start++){
x_end = x_start;
y_end = y_start;
for (i=x_start, j=y_start; i<cols && j<lines; i++, j++){ // moving horizontally and vertically
if (!arr[y_start][i] || !arr[j][x_start]){ // checking if the horizontal or vertical lines are not continuous
break;
}
else {
checker = 1;
for (k=x_start, l=y_start; k<i+1 && l<j+1; k++, l++){ // check if square
if (!arr[j][k] || !arr[l][i]){
checker = 0;
break;
}
}
if (checker){ // if square then
x_end = i;
y_end = j;
}
}
}
if ((x_end-x_start)>d_max){
col_start = x_start;
line_start = y_start;
col_end = x_end;
line_end = y_end;
d_max = col_end-col_start;
}
}
}
printf("The largest square is:\n[%d][%d] x [%d][%d]\n", line_start, col_start, line_end, col_end);
// this is only to check if the program is working properly
for (y_start=line_start; y_start<line_end+1; y_start++){
printf("\n ");
for (x_start=col_start; x_start<col_end+1; x_start++){
printf("%d ", arr[y_start][x_start]);
}
}
printf("\n");
}
There is confusion between rows and cols somewhere in your code. To find it, rename your variables i, j and k to something more meaningful, like row, col_start and col_end.
As for finding maximal square, you might want to use prefix sums.