Swapping elements in 2d array of varying lenghts c - c

I need to swap a 2d array of variable length but for some reason when the function to swap the elements is called it returns false. The swap code appears logical to me it does not work. Here is a snippet of the code.
bool swap(int tile)
{
for(j = 0; j < d; j++)
{
if (game[i][j]==tile && game[i][j + 1]==0)//swap tile left of zero
{
a = game[i][j +1];
b = game[i][j] ;
int temp = a;
a = b;
b = temp;
game[i][j] = a;
game[i][j+1] = b;
}
}
}
What is wrong here and how can I correct. The reason is just as important as the guidance to resolving. Thanks much!

You are doing a double swap, in effect making no swap at all.
It can be really simple since you already know the value of game[i][j+1] to be zero. All you have to do is
game[i][j+1] = game[i][j];
game[i][j] = 0;

You don't have any return
You should do like the following code
bool swap(int tile)
{
bool worked = false;
for(j = 0; j < d; j++)
{
if (game[i][j]==tile && game[i][j + 1]==0)//swap tile left of zero
{
int temp = game[i][j +1];
game[i][j+1] = game[i][j];
game[i][j] = temp;
worked = true;
}
}
return worked;
}

Related

What is wrong with my C selection sort code below? what should I do in my void selection sort

so this is the command, create an array of structs (a total of 15 elements) consisting of variables of type int and string. sort the array and perform a search on the array based on one of the elements with a variable of type int. use straight selection sort and interpolation search. i'm very new on learning Selection Sort, please correct the code below, I've reached my limit.
#include <stdio.h>
#include <string.h>
#include <conio.h>
void swap(int *xp, int *yp) {
int temp = *xp;
*xp = *yp;
*yp = temp;
}
void selectionSort(int angka[], int n) {
int i, j, k;
for (i = 0; i < n-1; i++) {
k = i;
for (j = i+1 ; j < n; j++) {
if (angka[j] < angka[k]);
k = j;
}
swap(&angka[k], &angka[i]);
}
}
void printArray(int angka[], int size) {
int i;
for (i=0; i < size; i++) {
printf("%d", angka[i]);
}
printf("\n");
}
struct dat {
int angka;
const char* name;
};
int main () {
struct dat nama_var[15];
nama_var[0].angka = 4;
nama_var[0].name = "Farina";
nama_var[1].angka = 12;
nama_var[1].name = "Rima";
nama_var[2].angka = 7;
nama_var[2].name = "Jihan";
nama_var[3].angka = 1;
nama_var[3].name = "Audi";
nama_var[4].angka = 14;
nama_var[4].name = "Tantri";
nama_var[5].angka = 5;
nama_var[5].name = "Farhan";
nama_var[6].angka = 15;
nama_var[6].name = "Tedi";
nama_var[7].angka = 6;
nama_var[7].name = "Husain";
nama_var[8].angka = 9;
nama_var[8].name = "Laudia";
nama_var[9].angka = 13;
nama_var[9].name = "Sari";
nama_var[10].angka = 2;
nama_var[10].name = "Ardi";
nama_var[11].angka = 10;
nama_var[11].name = "10";
nama_var[12].angka = 8;
nama_var[12].name = "Johan";
nama_var[13].angka = 11;
nama_var[13].name = "Misbah";
nama_var[14].angka = 3;
nama_var[14].name = "CIndy";
I'm stuck about the code here
int n = sizeof(nama_var.angka)/sizeof(nama_var.angka[]);
selectionSort(nama_var[15], n);
printf("Sorted : \n");
printArray(angka, n);
getch();
}
In your nama_var array you have names and integers and you want to sort the array based on the integers, however you made a function that sorts an array of integers. Let's change your function a bit so it sorts structs instead :
void selectionSort(struct dat names[], int n);
void swap(struct dat *xp, struct dat *yp); /* struct dat *temp = *xp; */
You want to sort the structures according to their angka value, so you have to extract them from the structures in order to compare them :
if (angka[j] < angka[k])
becomes :
if (names[j].angka < names[i].angka)
Finaly I think you made two typos, the if statement was bypassed each time : a single semicolon is a valid statement in C.
for (j = i+1 ; j < n; j++) {
if (angka[j] < angka[k]) /* ; <---- */
k = j;
}
And you call the function which is supposed to take an array but by putting square brackets you are giving the element at index 15 (which is outside the array) :
selectionSort(nama_var[15], n);
What you were trying to do was :
selectionSort(nama_var, n);

How to use 2d array with mutable length as a function's parameters

Here is the function with magic numbers as lengths of the 2d arrays:
bool function(int char_block_a[7][2], int char_block_b[6][2])
{
for (int i = 0; i = 7; i++)
{
for (int j = 0; j = 6; j++)
{
if (char_block_a[i][0] == char_block_b[j][0] && char_block_a[i][1] == char_block_b[j][1])
{
return true;
}
}
}
return false;
}
Here is the function with mutable length of 2d array that I wanted to implement (Just to show what I meant):
bool function(int char_block_a[a][2], int char_block_b[b][2])
{
for (int i = 0; i = a; i++)
{
for (int j = 0; j = b; j++)
{
if (char_block_a[i][0] == char_block_b[j][0] && char_block_a[i][1] == char_block_b[j][1])
{
return true;
}
}
}
return false;
}
How could I implement this? Thank you all!
The 2D array arguments can be passed with unspecified numbers of rows and pass the respective numbers of active rows separately. Make sure the loops use the correct tests too:
/* check if 2D arrays have a row with identical values */
bool function(int char_block_a[][2], size_t a, int char_block_b[][2], size_t b) {
for (size_t i = 0; i < a; i++) {
for (size_t j = 0; j < b; j++) {
if (char_block_a[i][0] == char_block_b[j][0]
&& char_block_a[i][1] == char_block_b[j][1]) {
return true;
}
}
}
return false;
}
bool function(int char_block_a[7][2], int char_block_b[6][2])
^^^ ^^^
The first dimension is ignored
You just have to pass first dimensions as addition arguments:
bool function(int char_block_a[][2], int char_block_b[][2], int a, int b)
~~~~~~~~~~~~

c Program crashing using 2d array comparing values

Hi im having problems with my c code it keeps crashing with no error and im not sure why. i am trying to find the value at a point inside a 2d array for example [1][1] and see what the value is there (only 1 or a 0) and then process the value depending on if its 1 or a 0 but the program keeps crashing with no error and im not sure why.please help
typedef struct gol{ // structure containing a square board
int **board; // pointer to a pointer
size_t size; //size_t = unnasigned value
}gol;
the struct is created in main using
struct gol *GAME;
GAME = create_gol(30);
using an if menu options if option is selected it will just call
next pattern function but it crashes
gol* create_gol(size_t size){
struct gol *Game_Of_Life;
Game_Of_Life = (struct gol*)malloc(sizeof(struct gol*)); //dynamically create the struct the ptr is pointing to **IMPORTANT
Gameboard = new int*[size];
for (int i = 0; i < size; ++i) {
Gameboard[i] = new int[size];
// each i-the pointer is now pointing to dynamic array (size 20) of actual int values
}
for (int i = 0; i < size; ++i) { // for each row
for (int j = 0; j < size; ++j) { // for each column
Gameboard[i][j] = 0;
}
}
Game_Of_Life->board=Gameboard;
Game_Of_Life->size=size;
return Game_Of_Life;
}
void next_pattern(gol* g)
{
for (int i = 0; i < 20; ++i) { // for each row
for (int j = 0; j < 20; ++j) { // for each column
int sum = neighbour_sum(g,i,j);
if (g->board[i][j]==1){
if (sum<2){
g->board[i][j]=0;
}
if (sum==3 || sum==2 ){
g->board[i][j]=1;
}
if (sum>3){
g->board[i][j]=0;
}
}
if (g->board[i][j]==0 && sum==3){
g->board[i][j]=1;
}
}
}
}
updates neighbour sum so it cant go out of bounds program still crashing
int neighbour_sum(gol* g, int i, int j)
{ int sum;
if ((g->board[(i-1+g->size)%g->size][j])==1){ // left
sum++;
}
if ((g->board[(i-1+g->size)%g->size][(j-1+g->size)%g->size])==1){//left up
sum++;
}
if ((g->board[i][(j-1+g->size)%g->size])==1){ //up
sum++;
}
if ((g->board[(i+1)%g->size][(j+1)%g->size])==1){ //right up
sum++;
}
if ((g->board[i][(j+1)%g->size])==1){ //right
sum++;
}
if ((g->board[(i+1)%g->size][(j+1)]%g->size)==1){//right bottom
sum++;
}
if ((g->board[i][(j+1)%g->size])==1){//bottom
sum++;
}
if ((g->board[(i-1+g->size)%g->size][(j+1)%g->size])==1){// bottom left
sum++;
}
return sum;
}
These lines
for (int i = 0; i < 20; ++i) { // for each row
for (int j = 0; j < 20; ++j) { // for each column
int sum = neighbour_sum(g,i,j);
means that you first call neighbour_sum with both i and j being zero.
Inside neighbour_sum you do:
if ((g->board[(i-1)][j])==1){ // left
^^^^
So since both i and j are zero, it is actually:
if ((g->board[-1][0])==1){ // left
^^^^
ups
So you access the array out of bounds. That may cause a crash. In any case it is illegal.
The general problem seems to be that you don't handle when the point is at the edge of the board.
edit after OP posted more code
This is wrong
Game_Of_Life = (struct gol*)malloc(sizeof(struct gol*));
^^^
do
Game_Of_Life = malloc(sizeof(struct gol));
I found the solution in the end there where a number of issues including i was looking for value outside of the array that was solved using
if ((g->board[(i-1+g->size)%g->size][j])==1){ // left
sum++;
}
i also was using c++ syntax instead of c syntax witch was resolved using the malloc function
Game_Of_Life = (struct gol*)malloc(sizeof(struct gol));
and the last issue causing the crashing still was the function neighbour sum was returning -2 because it wasn't initialized at 0 properly
int sum = 0;

Function to resize arrays and assign values

I'm having some trouble with a function that I'm trying to write as part of a project in C. I'm trying to write a function that not only resizes an array, but also assigns values to the new elements of the array.
For example if A = [a, b, c] and it needs to be doubled. The array needs to be re-sized to
[a, a+b/2, b, b+c/2, c, 3c/2]. If A = [a, b, c, d, e, f] the array should be re-sized to [a, c, e]. Any re-factoring of arrays is by some multiple of 2.
This is the offending bit of code.
void re_size_array(double *A, long n, long nx){
double *T;
long i, j;
long m;
T = (double *)malloc(sizeof(double)*nx);
if(nx > n){
m = nx/n;
double k;
for(i = 0; i < n - 1; i++){
k = (A[i+1] - A[i])/m;
for(j = 0; j < m; j++){
T[i*m + j] = A[i] + j*k;
}
}
k = A[n-1]/m;
for(i = 0; i < m; i++){
T[(n-1)*m + i] = A[n-1] + i*k;
}
A = (double*)realloc(A, sizeof(double)*nx);
if(A == NULL){
printf("Array has failed to re-size\n");
exit(1);
}
double *tmp = T;
A = T;
T = tmp;
free(T);
}
if(nx < n){
m = n/nx;
for(i = 0; i < nx; i++){
T[i] = A[i*m];
}
A = (double*)realloc(A, sizeof(double)*nx);
if(A == NULL){
printf("Array has failed to re-size\n");
exit(1);
}
double *temp = T;
A = T;
T = temp;
free(T);
}
}
I'm stuck as to why this doesn't work, I've printed out the values which are supposed to be assigned and they are all correct. I have tried swapping the pointers differently but I still get no viable result.
Instead when I try to re-size the data to a larger nx it results in the same process as A = realloc(A, nx*sizeof(double)). If I try to decrease the size, nothing happens.
Two things here:
A = T is not visible outside of the function. If you want that, then pass a pointer to the double pointer (double **) in your function signature.
You should return A; at the very end and call the function like A = re_size_array(A, n, nx)
hth :)

Swapping structures

# include <stdio.h>
# include <stdlib.h>
typedef struct
{
int Employee_id;
char Employee_Name[50];
float Employee_salary;
} employee;
void swap(employee *a,employee *b);
int main(int argc,char* argv[])
{
int n;
int iter,iter2,iter3,iter4;
scanf("%d",&n);
employee *start = (employee *)malloc(n*sizeof(employee));
employee temp;
for (iter = 0; iter < n;iter++)
{
scanf("%d",&((*(start+iter)).Employee_id));
scanf("%s",(*(start+iter)).Employee_Name);
scanf("%f",&((*(start+iter)).Employee_salary));
}
//USING BUBBLE SORT TO SORT ON BASIS OF IDS
for (iter2 = 1; iter2 <=n; iter2++)
{
for (iter3 = 0; iter3 <n-iter2 ; iter3++)
{
if ((start[iter3]).Employee_id > (start[iter3+1]).Employee_id)
{
swap(&start[iter3+1],&start[iter3]);
}
}
}
//PRINTING
for (iter4 = 0; iter4 < n; iter4++)
{
printf("%d\n",(*(start+iter4)).Employee_id);
printf("%s\n",(*(start+iter4)).Employee_Name);
printf("%f\n",(*(start+iter4)).Employee_salary);
printf("\n");
}
free(start);
return EXIT_SUCCESS;
}
void swap(employee *a,employee *b)
{
employee temp = *a;
*a = *b;
*b = temp;
}
I am trying to swap structures on the basis of employee id,I get no errors on compilation.But when I try to swap structures the program terminates abruptly. The same swap works well for ints and other basic types but not for structs.Thanks for help.
In your for loop for sorting.
for (iter2 = 0; iter2 <n; iter2++)
{
for (iter3 = 0; iter3 <n-iter2 ; iter3++) //LINE A
{
if ((start[iter3]).Employee_id > (start[iter3+1]).Employee_id)
{
swap(&start[iter3+1],&start[iter3]);
}
}
}
At LINE A, when iter2 is 0, then inner loop will from 0 to n-1. When, iter3 is n-1, you are accessing an item at n which will lead to undefined behaviour (out of bound index).
So, change your code as follows:
for (iter2 = 0; iter2 <n; iter2++)
{
for (iter3 = 0; iter3 <n - 1 -iter2 ; iter3++)
{
if ((start[iter3]).Employee_id > (start[iter3+1]).Employee_id)
{
swap(&start[iter3+1],&start[iter3]);
}
}
}
Please make sure that at any iteration of the loop, there should be not out of bound access.
Pay attention to this line, where n is being used without initialization.
employee *start = malloc(n*sizeof(employee));
To solve this, you need to swap these two lines:
employee *start = malloc(n*sizeof(employee));
scanf("%d",&n);
In addition, you need to add explicit type casting here, change this line to:
employee *start = (employee *)malloc(n*sizeof(employee));
Edit: swap() is no problem. See the following test:
employee a, b;
a.Employee_id = 1;
a.Employee_Name[0] = 'a';
a.Employee_salary = 10.0;
b.Employee_id = 2;
b.Employee_Name[0] = 'b';
b.Employee_salary = 20.0;
swap(&a, &b);
After this, a.Employee_id=2 and b.Employee_id=1, etc.
This line
swap(&start[iter3+1], ...
accesses the array start out of bounds for iter3==n (iter2 == 0).
So the program invokes undefined behaviuor.

Resources