Related
Good day everyone,
my task is to remove all negative numbers from an array, and shorten it (return the new length as the amount of positive numbers). I tried doing that by BubbleSort all negative number to the right, and new length would be (old length - number of swap). My code simply freezes up the system.
I would be grateful if you guys could help.
void swap(int *p, int *q) {
int h = *p;
*p = *q;
*q = h;
}
int remove_negatives(int *array, int length) {
int *a;
int n = length;
a = &array[n - 1];
for (int i = 0; i <= n - 1; i++) {
while (array < a) {
if (*array < 0) {
swap(a, array);
a--;
array++;
length--;
}
}
}
printialn(array, n);
return length;
};
int main(void) {
int a[] = {-1, 2, 4, -8, 3, 7, -8, 9, 3};
int l = sizeof(a) / sizeof(a[0]);
printiln(remove_negatives(a, l));
return 0;
}
The while loop never stops, that's probably the reason your code freezes.
Your code only changes the address when the if statement is true. Which the array in your main() will stuck on the second (a[1]) element. So if we change change the address when the if statement is false...
#include<stdio.h>
#include<stdlib.h>
void swap(int *p, int *q) {
int h = *p;
*p = *q;
*q = h;
}
int remove_negatives(int *array, int length) {
int *a, *head;
int n = length;
head = array;
a = &array[n - 1];
for (int i = 0; i <= n - 1; i++) {
while (array < a) {
if (*array >= 0) {
array++;
continue;
}
swap(a, array);
a--;
array++;
length--;
}
}
for (int i=0; i<length; i++) {
printf("%d ", *head);
head++;
}
puts("");
return length;
}
int main(void) {
int a[] = {-1, 2, 4, -8, 3, 7, -8, 9, 3};
int l = sizeof(a) / sizeof(a[0]);
remove_negatives(a, l);
return 0;
}
Now the while loop works, buts as #wovano said, the answer is still wrong. Your code isn't exactly a "bubble sort". you swap all the negative number to the end of the array and didn't actually sort the array.
So, let's start from the beginning.
To simplify the process, let bubble sort first, and then find the new array length.
#include<stdio.h>
#include<stdlib.h>
void swap(int *p, int *q) {
int h = *p;
*p = *q;
*q = h;
}
int bubble_sort(int *array, int length) {
int i, j;
// Bubble sort
for (i=0; i<length-1; i++) {
for (j=i+1; j<length; j++) {
if (array[i]<array[j]) swap(&array[i], &array[j]);
}
}
// Find new array length
for (i=length-1; i>=0; i--) {
if (array[i]>=0) break;
length--;
}
return length;
}
int main(void) {
int a[] = {-1, 2, 4, -8, 3, 7, -8, 9, 3};
int l = sizeof(a) / sizeof(a[0]);
l = bubble_sort(a, l);
for (int i=0; i<l; i++) printf("%d ", a[i]);
puts("");
return 0;
}
This is related to an earlier question of mine. I tried expanding the code a little bit and to play around with different ways of returning pointers to local static variables, especially returning two-dimensional arrays. (This is seriously just to understand how pointers to arrays work and how they behave in function environments. It has not even the slightest intent of returning arrays the smart way using structs.) I wrote two functions both transpose matrices. The function transpose() only transposes 2x4-matrices and the function transpose_generic() is supposed to transpose matrices of arbitrary size. There is no real use to them. After I have declared and defined the functions I call them from int main(int argc, char *argv[]){}. The two matrices that have been transposed are supposed to be printed to stdout in a simple for-loop. And here is something I don't understand. Depending on whether I declare the matrices that are supposed to be transposed as global or local variables I get a segfault or "clean" exit. I can also prevent the compiled program from segfaulting by using a for loop after the for loop that prints the transposed matrices to stdout. But the for-loop needs to use a new index. I'm sure I'm missing something very basic but I cannot figure this out on my own. Even after extensive internet searching I'm still puzzled. So maybe someone can enlighten me. Here is the code:
Will segfault
#include <stdio.h>
int mat1[2][4] = {
{9, 10, 11, 12},
{13, 14, 15, 16}
};
int mat2[2][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8}
};
typedef matx[2];
matx *transpose(int matrix[][4]);
typedef maty[];
maty *transpose_generic(int nrow, int ncol, int matrix1[nrow][ncol], int matrix2[nrow][ncol]);
int main(int argc, char *argv[]) {
/* This may need a little bit of clarification. Here we want to declare a
* pointer to an array and we need the round brackets () for this. If we
* were simply to write *mat_transpose[2] we would declare an array of
* pointers since [] has higher precedence than *. */
int (*mat_transpose)[2];
int tmat[2][4];
int i;
int j;
mat_transpose = transpose(mat1);
transpose_generic(2, 4, mat2, tmat);
for (j = 0; j < 2; j++) {
for (i = 0; i < 4; i++) {
printf("mat_transpose[%d][%d] = %d\n", i, j, mat_transpose[i][j]);
printf("tmat[%d][%d] = %d\n", i, j, tmat[i][j]);
}
}
return 0;
}
matx *transpose(int matrix[][4]) {
static int mat[4][2];
int i;
int j;
printf("Transpose a 2x4 matrix\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 4; j++) {
mat[j][i] = matrix[i][j];
}
}
return mat;
}
maty *transpose_generic(int nrow, int ncol,
int matrix1[nrow][ncol],
int matrix2[nrow][ncol]) {
int i;
int j;
printf("Transpose a matrix\n\n");
for (i = 0; i < nrow; i++) {
for (j = 0; j < ncol; j++) {
matrix2[j][i] = matrix1[i][j];
}
}
return matrix2;
}
Will exit clean
#include <stdio.h>
typedef matx[2];
matx *transpose(int matrix[][4]);
typedef maty[];
maty *transpose_generic(int nrow, int ncol, int matrix1[nrow][ncol], int matrix2[nrow][ncol]);
int main(int argc, char *argv[]) {
int mat1[2][4] = {
{9, 10, 11, 12},
{13, 14, 15, 16}
};
int mat2[2][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8}
};
/* This may need a little bit of clarification. Here we want to declare a
* pointer to an array and we need the round brackets () for this. If we
* were simply to write *mat_transpose[2] we would declare an array of
* pointers since [] has higher precedence than *. */
int (*mat_transpose)[2];
int tmat[2][4];
int i;
int j;
mat_transpose = transpose(mat1);
transpose_generic(2, 4, mat2, tmat);
for (j = 0; j < 2; j++) {
for (i = 0; i < 4; i++) {
printf("mat_transpose[%d][%d] = %d\n", i, j, mat_transpose[i][j]);
printf("tmat[%d][%d] = %d\n", i, j, tmat[i][j]);
}
}
return 0;
}
matx *transpose(int matrix[][4]) {
static int mat[4][2];
int i;
int j;
printf("Transpose a 2x4 matrix\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 4; j++) {
mat[j][i] = matrix[i][j];
}
}
return mat;
}
maty *transpose_generic(int nrow, int ncol,
int matrix1[nrow][ncol],
int matrix2[nrow][ncol]) {
int i;
int j;
printf("Transpose a matrix\n\n");
for (i = 0; i < nrow; i++) {
for (j = 0; j < ncol; j++) {
matrix2[j][i] = matrix1[i][j];
}
}
return matrix2;
}
Will exit clean
#include <stdio.h>
int mat1[2][4] = {
{9, 10, 11, 12},
{13, 14, 15, 16}
};
int mat2[2][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8}
};
typedef matx[2];
matx *transpose(int matrix[][4]);
typedef maty[];
maty *transpose_generic(int nrow, int ncol, int matrix1[nrow][ncol], int matrix2[nrow][ncol]);
int main(int argc, char *argv[]) {
/* This may need a little bit of clarification. Here we want to declare a
* pointer to an array and we need the round brackets () for this. If we
* were simply to write *mat_transpose[2] we would declare an array of
* pointers since [] has higher precedence than *. */
int (*mat_transpose)[2];
int tmat[2][4];
int i;
int j;
int k;
mat_transpose = transpose(mat1);
transpose_generic(2, 4, mat2, tmat);
for (j = 0; j < 2; j++) {
for (i = 0; i < 4; i++) {
printf("mat_transpose[%d][%d] = %d\n", i, j, mat_transpose[i][j]);
printf("tmat[%d][%d] = %d\n", i, j, tmat[i][j]);
}
}
for (k = 0; k < 1; k++) {
printf("H");
}
return 0;
}
matx *transpose(int matrix[][4]) {
static int mat[4][2];
int i;
int j;
printf("Transpose a 2x4 matrix\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 4; j++) {
mat[j][i] = matrix[i][j];
}
}
return mat;
}
maty *transpose_generic(int nrow, int ncol,
int matrix1[nrow][ncol],
int matrix2[nrow][ncol]) {
int i;
int j;
printf("Transpose a matrix\n\n");
for (i = 0; i < nrow; i++) {
for (j = 0; j < ncol; j++) {
matrix2[j][i] = matrix1[i][j];
}
}
return matrix2;
}
In this line,
printf("tmat[%d][%d] = %d\n", i, j, tmat[i][j]);
When i>1 your code causes undefined behaviour since you tmat is declared as int tmat[2][4];.
The same problem exists in all three code snippets and you just happen to get segfault only for the first one. This is not at all related to whether you return a a pointer to a function scoped static variable.
I'm trying to find the union of two sets of 10 digit numbers, I'm passing along three int arrays: first, second, and comp (this will hold the union set).
So far, I've added first and second into one array. I was thinking about finding the matching indices in comp[] then filter through deleting them. I figure there's a much easier way. Can anyone give me a hint?
Basically I'm taking
first[] = [1,2,3,4,5,6,7,8,9,10];
second[] = [1,2,3,4,11,12,13,14,15,16];
and I want to return
comp[] = [5,6,7,8,9,10,11,12,13,14,15,16];
The numbers won't necessarily be in order.
int compound(int first[],int second[],int comp[]){
int i=0;
int indicies[20];
for(int j = 0; j<SIZE; j++){
comp[i]=first[j];
i++;
}
for(int k = 0; k<SIZE; k++){
comp[i]=second[k];
i++;
}
int z=0;
for(int l = 0; l<SIZE*2; l++){
for(int m = 0; m<SIZE*2; m++){
if(comp[l]==comp[m]){
indicies[z]=m;
z++;
}}}
return 0;
}
A first good step is (nearly) always sorting.
Sort both input-sets (unless you know they are already sorted).
Then iterate over both at once (two indices) and only add those elements to the output which fulfill your criteria (seems to be union minus intersection, thus only in one).
Bonus: The output-set will be sorted.
I suggest you start by writing a contains(int[], int) method like
#include <stdio.h>
#include <stdbool.h>
bool contains(int arr[], int val) {
int offset;
for (offset = 0; arr[offset] != '\0'; offset++) {
if (arr[offset] == val) return true;
}
return false;
}
Then your compound method could be implemented using it with something like
int compound(int first[],int second[],int comp[]){
int i=0;
int j;
for(j = 0; first[j] != '\0'; j++){
int val = first[j];
if (contains(second, val) && !contains(comp, val))
comp[i++] = val;
}
return i;
}
Finally, you can test it like
int main(int argc, char *args[]) {
int a[] = {1,2,3,'\0'};
int b[] = {2,3,4,'\0'};
int c[3];
int count = compound(a,b,c);
int i;
for (i = 0; i < count; i++) {
printf("%i\n", c[i]);
}
}
Output is
2
3
If the numeric range is small you could do this:
#include <stdio.h>
#define MAX 20 // small numeric range
#define sz(a) (sizeof(a)/sizeof(*(a)))
int xunion(int *a, int sa, int *b, int sb, int *c) {
int n[MAX] = {0};
for (int i=0; i<sa; i++) n[a[i]] = 1;
for (int i=0; i<sb; i++) n[b[i]] = 1;
int j=0;
for (int i=0; i<MAX; i++) if (n[i]) c[j++] = i;
return j;
}
void prn(int *a, int s) {
while (s-- > 0) printf("%d ", *a++);
putchar('\n');
}
int main() {
int a[] = {6, 3, 4, 7, 5};
int b[] = {2, 4, 5, 7, 6, 3};
int c[MAX];
prn(a, sz(a));
prn(b, sz(b));
int n = xunion(a, sz(a), b, sz(b), c);
prn(c, n);
return 0;
}
i have been trying to complete figure out this part of my assignment to no avail for the past day, and require some help or guidance to help understand the problem.
so far i have this:
swap(int A, int B){
int temp;
temp = A;
A = B;
B = temp;
}
int max_array(int array[], int arraySize)
{
int i, max=-32000;
for (i=0; i<arraySize; i++)
{
if (array[i]>max)
{
max=array[i];
}
}
printf("%d \n Max array: ", max)
return(max);
}
int nextPermutation(int array[], int arraySize){
int i;
n = max_array(array, arraySize);
if (int i; n == array[i] && i > 1; i++){
swap(array[i], array[i-1]);
}
else if(int i; n == array[i]; i++){
}
}
void main(){
int intArray[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
//int intArray[10] = {1, 10, 3, 9, 8, 6, 7, 2, 4, 5};
nextPermutation(intArray, 10);
int i = 0;
for(i = 0; i < 10; i++){
printf("%d ",intArray[i]);
}
}
But the question that i'm struggling to understand is
"If a1,...,an is an arbitrary permutation (where a1,...,an are the numbers 1, 2, …, n in a probably different order) then the “next” permutation is produced by the
following procedure:
(i) If the maximal element of the array (which is n) is not the first element of the
array, say n=ai , where i>1 , then to produce the "next" permutation you
need to swap ai and ai−1 .
(ii) If the maximal element of the array is in the first position, i.e. n=a1 , then to
produce the “next” permutation to the permutation (a1,...,an)
, first find the “next” permutation to the (n-1)-element permutation (a2,...,an
), and then append a1 to the end of thus obtained array of (n-1) elements."
so it needs to permutate every single possible combination with the array of 1,2,3,4,5,6,7,8,9,10 and then finish when it reaches this point "(n, …, 2, 1). And this is
the only permutation that does not have the "next" permutation to it."
And the function int 'nextPermutation(int array[], int arraySize){' needs to stay the same.
Any help or tips will be excellent!
There are some errors in your program,
swap() function will not affect the program as it doesn't use pass by reference.
max_array() should find the index of the maximum value, not the maximum value itself.
There is no recursion in your program as far as I can see.
main() should return int.
The program fragement given below might give you an idea,
int ct=-1,n=10,temp[10]={0,0,0,0,0,0,0,0,0,0};
int intArray[10]={1,2,3,4,5,6,7,8,9,10};
permute(int k)
{
int i;
temp[k]=++ct;
if(ct==n-1)
{
for(i=0;i<n;i++)
{
printf("%d",intArray[temp[i]]);
}
printf("\n");
}
for(i=0;i<n;i++)
{
if(temp[i]==0)
{
permute(i);
}
}
ct--;
temp[k]=0;
}
int main()
{
permute(0);
}
for swap sample
#include <stdio.h>
void swap(int* A, int* B){
int wk;
wk = *A;
*A = *B;
*B = wk;
}
int main(void){
int array[] = { 1,2,3 };
swap(&array[0], &array[2]);
printf("array[0]=%d, array[2]=%d\n", array[0], array[2]);
return 0;
}
I am trying to multiply two 3x3 matrices. The first 2 numbers in the first
and second row are the only correct answer. What am I doing
wrong? Is the stuff I need declared in mult_matrices?
#include <stdio.h>
void mult_matrices(int a[][3], int b[][3], int result[][3]);
void print_matrix(int a[][3]);
int main()
{
int p[3][3] = {{1, 2, 3},{4, 5, 6}, {7, 8, 9}};
int q[3][3] = {{10, 11, 12}, {13, 14, 15}, {16, 17, 18}};
int r[3][3];
mult_matrices(p, q, r);
print_matrix(r);
}
void mult_matrices(int a[][3], int b[][3], int result[][3])
{
int i, j, k;
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
for(k = 0; k < 3; k++)
{
result[i][j] += a[i][k] * b[k][j];
}
}
}
}
void print_matrix(int a[][3])
{
int i, j;
for (i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
printf("%d\t", a[i][j]);
}
printf("\n");
}
}
Make sure you initialize r to all zeros before you use it.
int r[3][3] = { 0 };
Looks like you're not initializing your result matrix.
i.e. Change:
int r[3][3];
to
int r[3][3] ={{0,0,0},{0,0,0},{0,0,0}};
One thing that I notice that you don't do is initialize you're r[3][3] array. I am not sure if this is the root of you're problem but it very well could be. Essentially what the values of r are set to is whatever was "left over" in memory in that location. Sometimes they will all be 0 but most likely they will not be. So it could be the issue you are having, but even if it isn't it is good to always get in a habit of initializing all of you're variables.
int main(){
int A[3][3],B[3][3],C[3][3],i,j;
printf("Please Enter 9 Numbers for First Matrix")
for(i=0;i<=2;i++){
for(j=0;j<=2;j++){
scanf("%d",A[i][j]);
}
}
printf("Please Enter 9 Numbers for Second Matrix")
for(i=0;i<=2;i++){
for(j=0;j<=2;j++){
scanf("%d",B[i][j]);
}
}
for(i=0;i<=2;i++){
for(j=0;j<=2;j++){
C[i][j]=A[i][j]+B[i][j]
printf("%d "C[i][j]);
}
printf("\n");
}
}