Why does this sorting doesn't work ? (C) - c

I am trying to create a sorting method based on selection sort algorithm
With this current code, the array [10, 9, 8 .. 1] is "sorted" to
[9, 8 .. 2, 10, 1]
I mean like, it doesn't even put 10 in the right place
10 9 8 7 6 5 4 3 2 1
"sorted" to
9 8 7 6 5 4 3 2 10 1
What's the problem ?
void selectionSort(int array[], int length)
{
int i = 0, j = 0, temp = 0, swap = 0;
for(i = 0; i < length; i++)
{
temp = i;
for(j = 0; j < length; j++)
{
if(array[temp] > array[j])
{
temp = j;
}
}
swap = array[temp];
array[temp] = array[i];
array[i] = swap;
}
}

The inner loop should be written like
for(j = i + 1; j < length; j++)
^^^^^^^^^

After each iteration of i, the array upto i , should be sorted. You can print the array after each iteration of i and can see the logical error.

Related

Right rotation for 2D array

I tried to code a right rotation for a 2D array.
Here is the main code:
for (int k = 0; k < rotate; k++) { //rotate is the no of times to shift right
for (int i = 0; i < n1; i++) { //n1 is no: of rows
for (int j = 0; j <n2; j++) { //n2 is no: of columns
//Shifting right
int temp = A[i][n2 - 1];
A[i][n2 - 1] = A[i][j + 1];
A[i][j + 1] = A[i][j];
A[i][j] = temp;
}
}
}
for (int i = 0; i < n1; i++) {
for (int j = 0; j < n2; j++) {
printf("%d", A[i][j]);
}
printf("\n");
}
It is working for size 2x2 where:
Input:
1 2
3 4
Output:
2 1
4 3
But it's not working for size 3x3 and above.
Input:
1 2 3
4 5 6
7 8 9
Output:
3 2 1
6 5 4
9 8 7
Where expected output is:
3 1 2
6 4 5
9 7 8
Please guide me about where I'm wrong and I apologize for any mistakes in my question.
See:
https://www.programiz.com/c-programming/examples/matrix-transpose ;)
You can change that solution to use one array.
In your code you are referring to both left and right neighbours (though left one is wrongly referred because it should be last cell only for first interation) and don't keep value for next iteration.
It should be implemented as follows:
For each row left is initalized with the value of very last item in the row, because it is on the left of 0th item. Then while iterating over row items we first save current value to temp to use it later, then save left to current item, and then use previosly saved temp as new left for next iteration.
for (int k = 0; k < rotate; k++) { //rotate is the no of times to shift right
for (int i = 0; i < n1; i++) { //n1 is no: of rows
int left = A[i][n2 - 1];
for (int j = 0; j < n2; j++) { //n2 is no: of columns
//Shifting right
int temp = A[i][j];
A[i][j] = left;
left = temp;
}
}
}

How to delete a row from a 2D array in C?

How do I remove a specific row from a matrix, keeping the same order?
Example:
1 1 1
2 2 2
3 3 3
Let's say I need to remove the row with all even elements, so after deleting it should look like:
1 1 1
3 3 3
I tried writing code myself, (condition not the same as i mentioned above!) but it doesn't actually work properly:
for (i = 0 ; i < no_of_rows ; i++) {
if (abs(prosjeci[i] - prosjek) < 0.1) { /* condition */
for (k = i ; k < no_of_rows - 1 ; k++) {
for (j = 0 ; j < no_of_columns ; j++) {
matrica[k][j] = matrica[k+1][j];
}
}
i--;
no_of_rows--;
}
}
I don't see anything wrong with your code.
In the comments, someone asked you to post a "Minimal, Complete, and Verifiable example". Here's what that means. I fleshed out your program, adding a declaration and initialization of your matrica array and other variables, changing the condition to match your example, and printing out the array at the end. I ended up with this:
#include <stdio.h>
int matrica[][3] = {
{1, 1, 1},
{2, 2, 2},
{3, 3, 3}
};
int no_of_columns = 3;
int no_of_rows = 3;
int main()
{
int i, j, k;
for (i = 0 ; i < no_of_rows ; i++) {
if (matrica[i][0] % 2 == 0) { /* even row */
for (k = i ; k < no_of_rows - 1 ; k++) {
for (j = 0 ; j < no_of_columns ; j++) {
matrica[k][j] = matrica[k+1][j];
}
}
i--;
no_of_rows--;
}
}
for (i = 0 ; i < no_of_rows ; i++) {
for (j = 0 ; j < no_of_columns ; j++) {
printf("%d ", matrica[i][j]);
}
printf("\n");
}
}
So it would have been better if you had posted something like that in the first place.
But when I compile and run this program, it works perfectly. (I'm not surprised -- as I said, I don't see anything wrong with it.)
So whatever your problem is, it's in something you haven't showed us. What did you mean when you said "it doesn't actually work properly"? What did you expect to see, and what did you see instead?
[P.S. There's one more problem with your question. Until you ask it better, I am not even supposed to answer it. This answer of mine was actually downvoted to remind me of this fact. I'm not complaining; I expected it. But please, ask a more complete and answerable question next time.]
Your method does not work because you modify the matrix in place, update the i index and the number of rows no_of_rows accordingly, but fail to update the separate array prosjeci. Whenever a row matches the filter, all subsequent rows in the matrix are removed.
You can fix this problem by using a separate index for the matrix and the filter array:
int ii; // index into the prosjeci array.
for (i = ii = 0; i < no_of_rows ; i++, ii++) {
if (abs(prosjeci[ii] - prosjek) < 0.1) { /* condition */
for (k = i; k < no_of_rows - 1; k++) {
for (j = 0; j < no_of_columns; j++) {
matrica[k][j] = matrica[k+1][j];
}
}
i--;
no_of_rows--;
}
}
Alternately, if you can update the filtering array, you can do this:
for (i = 0; i < no_of_rows ; i++) {
if (abs(prosjeci[i] - prosjek) < 0.1) { /* condition */
for (k = i; k < no_of_rows - 1; k++) {
for (j = 0; j < no_of_columns; j++) {
matrica[k][j] = matrica[k+1][j];
}
prosjeci[k] = prosjeci[k+1];
}
i--;
no_of_rows--;
}
}
First of all in fact you can not remove elements from an array without creating a new copy of the array. You can only overwrite them with some other values and keep the number of actually used elements in the array.
Here is a demonstrative program that shows how it can be done. The variable with the name n is used to keep the number of actually used rows of elements in the array.
#include <stdio.h>
#define N 10
int all_of_even( const int *row, size_t n )
{
size_t i = 0;
while ( i < n && row[i] % 2 == 0 ) i++;
return i == n;
}
int main(void)
{
int a[][N] =
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
{ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 },
{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
{ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }
};
const size_t M = sizeof( a ) / sizeof( * a );
size_t n = M;
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < N; j++ ) printf( "%d ", a[i][j] );
printf( "\n" );
}
printf( "\n" );
n = 0;
for ( size_t i = 0; i < M; i++ )
{
if ( !all_of_even( a[i], N ) )
{
if ( n != i )
{
for ( size_t j = 0; j < N; j++ ) a[n][j] = a[i][j];
}
++n;
}
}
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < N; j++ ) printf( "%d ", a[i][j] );
printf( "\n" );
}
printf( "\n" );
return 0;
}
The program output is
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9
1 1 1 1 1 1 1 1 1 1
3 3 3 3 3 3 3 3 3 3
5 5 5 5 5 5 5 5 5 5
7 7 7 7 7 7 7 7 7 7
9 9 9 9 9 9 9 9 9 9
As for your approach then it is inefficient because for each iteration with checking the condition you copy all rows of the array after the given row instead of copying only one row.
Also it is a bad practice to change control variables of a for loop in its body and in the for statement itself simultaneously. This makes difficult to read the code.
i tried to do what you meant..
main(){
int matrica[3][3] = { { 1,2,3 },
{ 4,4,4 },
{ 7,8,9 } };
double no_of_rows = 3;
int line_removed = 0;
for (int i = 0; i < no_of_rows; i++) {
double sum = 0;
for (int j = 0; j < no_of_rows; j++)
{
sum = sum + matrica[i][j];
}
for (int j = 0; j < no_of_rows; j++)
{
int checker = 0.1 + (sum / no_of_rows);
if ( checker > matrica[i][j] || checker < matrica[i][j])
{
break;
}
if (j = (no_of_rows-1))
{
for ( int k = i ; k < no_of_rows; k++)
{
for ( j = 0; j < no_of_rows; j++)
{
matrica[k][j] = matrica[k + 1][j];
}
}
line_removed++;
}
}
}
for (int i = 0; i < (no_of_rows-line_removed); i++)
{
for (int j = 0; j < no_of_rows; j++)
{
printf("%d ", matrica[i][j]);
}
printf("\n");
}
printf("\n");
return 0;
}

Sudoku code checker 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 7 years ago.
Improve this question
I'm writing a Sudoku solution checker for a class and I've hit a wall.
I'm at the point where I'm checking if I can see whether or individual columns and rows are unique. For some reason the code works on 4x4 grids but as soon as I get up to a 5x5 grid or higher (goal is to get to a 9x9 grid) the program starts to print out that it had failed even when it should succeed.
Any help would be much needed, I want need a point in the right direction or where I should look into
Here's the code:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int i, j, n, k, p, q;
int fail;
int array[5][5];
int check[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int a = 0;
char *output = NULL;
scanf("%d", &n);
// memory allocated for yes or no at end
output = malloc(sizeof(int) * (n));
while (a < n)
{
fail = 0;
// create this 2D array
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
scanf("%d", &(array[i][j]));
}
}
// seeing if row is unique
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
for (k = 0; k < 5; k++)
{
if (array[i][k] == array[i][k+1])
fail += 1;
}
}
}
// seeing if column is unique
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
for (k = 0; k < 5; k++)
{
if (array[k][j] == array[k+1][j])
fail += 1;
}
}
}
/* for (WHAT DO I DO FOR ROWS)
{
for (WHAT DO I DO FOR ROWS AGAIN BUT REPLACE ROWS WITH COLUMNS)
{
for (NOW IM LOST)
}
}
*/
// success or failure? 0 success, 1 failure
if (fail >= 1)
output[a] = 1;
else
output[a] = 0;
a++;
}
// print out yah or nah
for (i = 0; i < n; i++)
{
if (output[i] == 0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
Forget my for loop for the grids, I'll work on that once I figure out how to get the columns and rows working correctly.
Thanks for the help!
Here is an input that would cause the program to fail when it should succeed
1
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4
output would be
NO
EDIT: It is now working with a 9x9 grid! Thanks for the help!
#include <stdio.h>
#include <stdlib.h>
#define SIDE_LENGTH 9
int main ()
{
int i, j, n, k, p, q;
int fail;
int array[SIDE_LENGTH][SIDE_LENGTH];
int check[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int a = 0;
char *output = NULL;
scanf("%d", &n);
// memory allocated for yes or no at end
output = malloc(sizeof(int) * (n));
while (a < n)
{
fail = 0;
// create this 2D array
for (i = 0; i < SIDE_LENGTH; i++)
{
for (j = 0; j < SIDE_LENGTH; j++)
{
scanf("%d", &(array[i][j]));
}
}
// seeing if row is unique
for (i = 0; i < SIDE_LENGTH; i++)
{
for (j = 0; j < SIDE_LENGTH; j++)
{
for (k = 0; k < SIDE_LENGTH - 1; k++)
{
if (array[i][k] == array[i][k+1])
fail += 1;
}
}
}
// seeing if column is unique
for (i = 0; i < SIDE_LENGTH; i++)
{
for (j = 0; j < SIDE_LENGTH; j++)
{
for (k = 0; k < SIDE_LENGTH - 1; k++)
{
if (array[k][j] == array[k+1][j])
fail += 1;
}
}
}
/* for (WHAT DO I DO FOR ROWS)
{
for (WHAT DO I DO FOR ROWS AGAIN BUT REPLACE ROWS WITH COLUMNS)
{
for (NOW IM LOST)
}
}
*/
// success or failure? 0 success, 1 failure
if (fail >= 1)
output[a] = 1;
else
output[a] = 0;
a++;
}
// print out yah or nah
for (i = 0; i < n; i++)
{
if (output[i] == 0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
input:
1
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 1
3 4 5 6 7 8 9 1 2
4 5 6 7 8 9 1 2 3
5 6 7 8 9 1 2 3 4
6 7 8 9 1 2 3 4 5
7 8 9 1 2 3 4 5 6
8 9 1 2 3 4 5 6 7
9 1 2 3 4 5 6 7 8
#ameyCU helped find the error in my code
Setting k to one less than what i and j were set to allowed the code to successfully run on any X*X sized grid. Because k is one less than i and j, it won't try to access a part of the array that hasn't been allocated yet which is where my problem lied.
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
for (k = 0; k < 5; k++)
{
if (array[i][k] == array[i][k+1])
fail += 1;
}
}
}
Despite the overwriting of the array as already pointed out, your logic is flawed. You don't use j at all. You are just comparing the same values five times.
The problem is the comparison.
if (array[i][k] == array[i][k+1])
I think you are using i as row and column index, then using j to iterate for duplicates. k will be what you compare against so ...
/* compare if j'th value is same as k'th value */
if (j != k && array[i][j] == array[i][k]) /* Don't check same against same */
the second comparison should be
/* compare if j'th value is same as k'th value */
if (j != k && array[j][i] == array[k][i]) /* Don't check same against same */
That would fix your overflow (k+1) bug, and get you going.
The squares could be fixed with
struct co_ords {
int x;
int y;
};
struct co_ords boxes[][9] = {{ {0,0}, {0,1}, {0,2},
{1,0}, {1,1}, {1,2},
{2,0}, {2,1}, {2,2}
},
{ {3,0}, {3,1}, {3,2},
{4,0}, {4,1}, {4,2},
{5,0}, {5,1}, {5,2} },
... /* more boxes go here */
{ {6,6}, {6,7}, {6,8},
{7,6}, {7,7}, {7,8},
{8,6}, {8,7}, {8,8} }};
for( i = 0; i < 9; i++ ){
struct co_ords current_box * = boxes[i];
for( j = 0; j < 9; j++ ) {
for( k = 0; k < 9; k++ ){
if( j != k && array[ current_box[j].x ][ current_box[j].y] == array[ current_box[k].x ][ current_box[k].y] )
fail += 1;
}
}
}
int array[5][5];
so the array is allocated as 5x5
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
scanf("%d", &(array[i][j]));
}
}
and you are indexing from 0 to 5 ..
to use larger, please do replace all those "5"s with a precompiler definition.
#define SUDOKU_SIDE_LENGTH 5
...
int array[SUDOKU_SIDE_LENGTH ][SUDOKU_SIDE_LENGTH ];
...
for (i = 0; i < SUDOKU_SIDE_LENGTH ; i++)
{
for (j = 0; j < SUDOKU_SIDE_LENGTH ; j++)
{
scanf("%d", &(array[i][j]));
}
}
etc.. that will ensure that you always allocate enough space for the array.
adjust size on the definition, not in the code..

C programming. Sorting rows in a 2D array

I'm trying to sort the elements within the individual rows of a 2D array. I understand how to sort the elements inside a 1D array, but I am having serious trouble getting it to sort the 2D.
Code for the 1D array:
for (i = 0; i < size; i++)
{
for (j = i +1; j < size; ++j)
{
if (array2[i] > array2[j])
{
swap = array2[i];
array2[i] = array2[j];
array2[j] = swap;
}
}
}
What I want to do: 2D Array before sorting
9 2 0 1 6 3
0 9 1 2 3 8
4 2 5 4 3 6
3 6 4 3 9 3
0 2 1 2 0 4
4 1 9 4 2 7
2D array after sorting:
0 1 2 3 6 9
0 1 2 3 8 9
2 3 4 4 5 6
3 3 3 4 6 9
0 0 1 2 2 4
1 2 4 4 7 9
My code for the 2D so far:
size: the user defined dimensions (in the above case it is 6)
for (i = 0; i < size; i++)
{
for (j = 0; j < size; j++)
{
if(array[i][j] > array[i][j+1])
{
swap = array[i][j];
array[i][j] = array[i][j+1];
array[i][j+1] = swap;
}
}
}
Any help or advice would be much appreciated. Thank you all.
If you want to use your single array sorting algorithm (bubble sort) to sort the two dimensional array then you have to add the another for loop: An outer for loop which will take care of each row. Let's say m is number of row and n is number of column.
for(k=0; k< m; k++) {
for (i = 0; i < n; i++) {
for (j = i +1; j < n; ++j) {
if (array2[k][i] > array2[k][j]) {
int swap = array2[k][i];
array2[k][i] = array2[k][j];
array2[k][j] = swap;
}
}
}
}
But this is not an efficient approach to sort the array, it's time complexity will be O(mn^2)
copy all the elements of the 2d array into an 1d array
then apply any sorting algorithm on 1d array & then copy back the sorted 1d array to the 2d array.
please don't mind
if you have a better solution then post it that will be helpfull for me.
You can simply use STL to sort 2D array row-wise..
for (i=0;i<n;i++){
for ( j=0;j<n;j++){
cin>>a[i][j];
}
sort(a[i],a[i]+n);
}
int tmp,l;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
tmp = a[i][j];
l = j + 1;
for (int k = i; k < 2; k++) {
while (l < 2) {
if (tmp < a[k][l]) {
tmp = a[k][l];
a[k][l] = a[i][j];
a[i][j] = tmp;
}
l++;
}
l = 0;
}
}
}

Integer pointer array sorting in C

I have a global integer pointer array, which is created this way
int * array;
array = (int *) malloc(size * sizeof(int));
I also have a sorting algorithm, which is supposed to sort 4 first numbers of the array which size is larger than 4 (16 in this case). sizeOfArray is defined as 4 in this case:
int temp,i,j;
for(i=0;i<sizeOfArray;i++){
for(j=i;j<sizeOfArray;j++){
if(array[i] > array[j]){
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
}
Output is really weird for some reason:
Unsorted: 7,6,9,3
Sorted: 3,6,5,1
The weirdest part is if I change algorithm to sort numbers in a descending order, it seems to work:
if(array[i] < array[j])
Unsorted: 10,0,1,8
Sorted: 10,8,1,0
What's causing this? I'm completely lost.
Here is your code wrapped to make an MCVE How to create a Minimal, Complete, Valid Example?:
#include <stdio.h>
#include <stdlib.h>
static void print(int n, int a[n])
{
for (int i = 0; i < n; i++)
printf("%2d", a[i]);
putchar('\n');
}
int main(void)
{
int size = 16;
int *array = (int *) malloc(size * sizeof(int));
array[0] = 7;
array[1] = 6;
array[2] = 9;
array[3] = 3;
int sizeOfArray = 4;
printf("Before:");
print(sizeOfArray, array);
int temp, i, j;
for (i = 0; i < sizeOfArray; i++)
{
for (j = i; j < sizeOfArray; j++)
{
if (array[i] > array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
printf("After: ");
print(sizeOfArray, array);
return 0;
}
The output from this program is:
Before: 7 6 9 3
After: 3 6 7 9
Since this is not the same as the output you get, there must be a difference — a crucial difference. Since you don't show the code that initializes the array, nor show the code that demonstrates that the first 4 elements have the unsorted values, nor show the code that demonstrates the sorted values are wonky, it is not possible to say for certain what is wrong — but the problem is not in the code you show.
I've not fixed the code to check that the memory allocation succeeds; nor have I modified the code to release the allocated space. Both should be done.
The code does use C99 features; it is trivial to revise it not to do so:
static void print(int n, int *a)
{
int i;
for (i = 0; i < n; i++)
and move the definition of sizeOfArray before the assignments.
I am sure this will work for your sorting array...in 2nd iteration sizeofarray-1 will work for loop j...
int temp,i,j;
for(i=0;i<sizeOfArray;i++)
{
for(j=0;j<sizeOfArray-1;j++)
{
if(array[i] > array[j])
{
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
}
Let's do some iterations of your code with the values you provide : 7,6,9,3. Also, let's assume that sizeOfArray = 4.
For i = j, your condition will never be executed, because array[i] = array[j].
For i = 0 and j = 1 => 7 > 6 => array = {6, 7, 9, 3}
For i = 0 and j = 2 => 6 < 9 => array = {6, 7, 9, 3}
For i = 0 and j = 3 => 6 > 3 => array = {3, 7, 9, 6}
For i = 1 and j = 2 => 7 < 9 => array = {3, 7, 9, 6}
For i = 1 and j = 3 => 7 > 6 => array = {3, 6, 9, 7}
For i = 2 and j = 3 => 9 > 7 => array = {3, 6, 7, 9}
Thus, I obtained the four first elements of your array sorted correctly (which contains size elements and I assume that size = 16).
If you're not sure about the value of sizeOfArray or size, I suggest you to print them and to check if it's really the value you want.
Hope this helps you.

Resources