Combining two given sequences into a new increasing sequence - arrays

I am doing the following problem:
Giving the sequence a consisting of n integer numbers and the sequence b consisting of m integer numbers, two sequences are arranged in increasing order. Combining two above sequences into a new sequence c such that c is also an increasing sequence. Printing c.
Input:
3
1 3 4
4
1 2 3 5
Output:
1 1 2 3 3 4 5
My idea is first combining two sequences into sequence c, then sorting sequence c in increasing order. This is my code:
#include <stdio.h>
int main() {
//Inputting sequence a and b
int n, m;
int a[1001], b[1001];
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
scanf("%d", &m);
for (int i = 0; i < m; i++) {
scanf("%d", &b[i]);
}
//Combine two sequence into c
int c[1001];
for (int i = 0; i < n; i++) {
c[i] = a[i];
}
for (int i = 0; i < m; i++) {
c[i + n] = b[i];
}
//Arrange sequence c in increasing order
int mid;
for (int i = 0; i < (n + m - 1); i++) {
for (int j = 1; j < (n + m); j++) {
if (c[i] > c[j]) {
mid = c[i];
c[i] = c[j];
c[j] = mid;
}
}
}
//Printing c
for (int i = 0; i < (n + m); i++) {
printf("%d ", c[i]);
}
return 0;
}
However, when I test with the test case [1,2,4],[1,2,5], the result is 1 4 2 2 1 5. Can anyone point out the error in my code? I truly appreciate that.

It is wrong to search for the minimum value in the range of 1 to n+m-1 regardless of the value i. This may move the minimum value to the latter part of the array.
The line
for (int j = 1; j < (n+m); j++)
should be
for (int j = i + 1; j < (n+m); j++)

To merge 2 sorted arrays, you can write 3 loops as in the classic implementation of mergesort:
#include <stdio.h>
int main() {
//Inputting sequence a and b
int a[1000], b[1000], c[2000];
int n, m, i, j, k;
if (scanf("%d", &n) != 1 || n <= 0 || n > 1000)
return 1;
for (i = 0; i < n; i++) {
if (scanf("%d", &a[i]) != 1)
return 1;
}
if (scanf("%d", &m) != 1 || m <= 0 || m > 1000)
return 1;
for (i = 0; i < m; i++) {
if (scanf("%d", &b[i]) != 1)
return 1;
}
//Combine both sequences into c
i = 0, j = 0, k = 0;
while (i < n && j < m) {
if (a[i] <= b[j])
c[k++] = a[i++];
else
c[k++] = b[j++];
}
while (i < n) {
c[k++] = a[i++];
}
while (j < m) {
c[k++] = a[j++];
}
//Printing c
for (i = 0; i < n + m; i++) {
printf("%d ", c[i]);
}
printf("\n");
return 0;
}

Related

Sorting a matrix

Im trying to sort a matrix by the sum of its row's digits, from highest to lowest. I dont know if i explained that correctly so here's some photos explaining it.
This is what my code outputs. Basically, it asks you for m and n, which are the dimensions of the matrix. In this example it's a 3x4, 3 rows and 4 columns. Then, the matrix should be sorted by rows, by the sum of row's digits. Which means, instead of what's being outputted in the picture above, the correct result should be this:
I have no idea how to sort this from highest to lowest, i have been trying for hours to no avail.
Here's my code:
#include <stdio.h>
#define N 30
void main(){
double a[N][N], s[N], p;
int i, j, m, n, max;
while(1){
printf("\nm, n? ");
scanf("%d%d", &m, &n);
if(m <= 0 || m > N || n <=0 || n > N)
break;
for(i = 0; i < m; i++){
printf("%2d. row? ", i+1);
for(j = 0; j < n; scanf("%lf", &a[i][j++]));
}
for(i = 0; i < m; i++)
for(s[i] = j = 0; j < n; s[i] += a[i][j++]);
for(j = 0; j < n - 1; j++){
for(max = i, j = i+1; j < n; j++)
if(s[j] > s[max])
max = i;
if(max != j){
p = s[j];
s[j] = s[max];
s[max] = p;
for(j = 0; j < m; j++){
p = a[j][i];
a[j][i] = a[j][max];
a[j][max] = p;
}
}
}
printf("New matrix: \n");
for(i = 0; i < m; i++){
for(j = 0; j < n; printf("%8.2lf", a[i][j++]));
printf("\n");
}
for(j = 0; j < m; j++)
printf("-------------");
printf("\n");
for(j = 0; j < m; printf("%8.2f \n", s[j++]));
printf("\n");
}
}
You can sort the rows of the matrix from highest to lowest, using a simple bubble sort algorithm.Your code modified below:
int main() {
double a[N][N], s[N], p;
int i, j, m, n, max;
while (1) {
printf("\nm, n? ");
scanf("%d%d", & m, & n);
if (m <= 0 || m > N || n <= 0 || n > N)
break;
for (i = 0; i < m; i++) {
printf("%2d. row? ", i + 1);
for (j = 0; j < n; scanf("%lf", & a[i][j++]));
}
for (i = 0; i < m; i++)
for (s[i] = j = 0; j < n; s[i] += a[i][j++]);
for (i = 0; i < m - 1; i++) { // modified here
for (j = i + 1; j < m; j++) { // modified here
if (s[j] > s[i]) { // modified here
p = s[i];
s[i] = s[j];
s[j] = p;
for (int k = 0; k < n; k++) {
p = a[i][k];
a[i][k] = a[j][k];
a[j][k] = p;
}
}
}
}
printf("New matrix: \n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; printf("%8.2lf", a[i][j++]));
printf("\n");
}
for (j = 0; j < m; j++)
printf("-------------");
printf("\n");
for (j = 0; j < m; printf("%8.2f \n", s[j++]));
printf("\n");
}
return 0;
}
Here's how i modified your code to achieve that:
Initialize a loop variable i to 0.
In the outer loop, run the inner loop j from i+1 to m-1.
In the inner loop, compare the sum of the row i with the sum of row
j. If the sum of row j is greater than the sum of row i, swap the
rows using a temporary variable.
After the inner loop finishes, increment the value of i by 1. Repeat
the outer loop until i becomes equal to m-1.
Output:
You can just use qsort to let it handle the sorting and item swapping. Then you only need to write the code for comparing two rows with each other.
Given something like this:
int matrix[3][4] =
{
{1,2,3,4},
{5,6,7,8},
{9,1,2,3},
};
You'd call qsort as:
qsort(matrix, 3, sizeof(int[4]), compare);
The only complexity is implementing the comparison callback function. There's two things to consider there:
We've told qsort that we have an array of 3 items, each of type int[4]. So the void pointers it passes along to us will actually be pointers to type int[4]. That is: int(*)[4].
qsort sorts in ascending order by default, where the item considered "less" ends up first. So we need to tweak that to get the largest item first.
Example:
int compare (const void* obj1, const void* obj2)
{
const int (*ptr1)[4] = obj1;
const int (*ptr2)[4] = obj2;
size_t sum1=0;
size_t sum2=0;
for(size_t i=0; i<4; i++)
{
sum1 += (*ptr1)[i];
sum2 += (*ptr2)[i];
}
if(sum1 > sum2) // largest sum considered "less" for qsort
return -1;
else
return 1;
return 0;
}
sum1 < sum2 would have placed the smallest row first.
Full example:
#include <stdio.h>
#include <stdlib.h>
int compare (const void* obj1, const void* obj2)
{
const int (*ptr1)[4] = obj1;
const int (*ptr2)[4] = obj2;
size_t sum1=0;
size_t sum2=0;
for(size_t i=0; i<4; i++)
{
sum1 += (*ptr1)[i];
sum2 += (*ptr2)[i];
}
if(sum1 > sum2) // largest sum considered "less" for qsort
return -1;
else
return 1;
return 0;
}
void print_matrix(size_t col, size_t row, int matrix[col][row])
{
for(size_t i=0; i<col; i++)
{
for(size_t j=0; j<row; j++)
{
printf("%d,", matrix[i][j]);
}
puts("");
}
}
int main (void)
{
int matrix[3][4] =
{
{1,2,3,4},
{5,6,7,8},
{9,1,2,3},
};
print_matrix(3,4,matrix);
puts("");
qsort(matrix, 3, sizeof(int[4]), compare);
print_matrix(3,4,matrix);
}

Delete duplicate rows and columns of matrix

I need to delete (not skip while printing) the rows and columns of a matrix that appear more than once in program, and I should print only first row from the top that appears more than once or the first column from the left that appears more than once.
Example input:
1 2 3 2
4 5 6 5
1 2 3 2
7 8 9 8
After deleting:
1 2 3
4 5 6
7 8 9
Here's my code:
#include <stdio.h>
int main() {
int i, j, m, n,row,col, mat[200][200];
scanf("%d %d", &m, &n);
row = m; col = n;
for (i = 0; i < m; i++)
for (j = 0; j < m; j++)
scanf("%d", &mat[i][j]);
for (i = 0; i < m; i++)
for (j = 0; j < m; j++) {
if (mat[i][j] == mat[i++][j++])
row--;
if (mat[j][i] == mat[j++][i++])
col--;
}
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
return 0;
}
Do you have any idea how to make the algorithm work for this task? Mine has mistakes.
Would you please try the following:
#include <stdio.h>
#define ROWS 200
#define COLS 200
#define TRUE 1
#define FALSE 0
/*
* delete k'th row from the m x n matrix
*/
void deleterow(int mat[ROWS][COLS], int m, int n, int k)
{
int i, j;
for (i = k; i < m - 1; i++) {
for (j = 0; j < n; j++) {
mat[i][j] = mat[i + 1][j];
}
}
}
/*
* delete k'th columns from the m x n matrix
*/
void deletecol(int mat[ROWS][COLS], int m, int n, int k)
{
int i, j;
for (j = k; j < n - 1; j++) {
for (i = 0; i < m; i++) {
mat[i][j] = mat[i][j + 1];
}
}
}
int main() {
int i, j, m, n,row,col, mat[ROWS][COLS];
int iref, jref; // reference indexes to compare
int match; // flag to show if the row/col duplicates
// read input matrix
scanf("%d %d", &m, &n);
row = m; col = n;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &mat[i][j]);
// examine row by row
for (iref = 0; iref < m; iref++) {
// compare rows below iref and remove the row if duplicates
for (i = iref + 1; i < m; i++) {
match = TRUE;
for (j = 0; j < n; j++) {
if (mat[i][j] != mat[iref][j]) {
match = FALSE;
break;
}
}
if (match) {
deleterow(mat, m, n, i);
m--;
}
}
}
// examine column by column
for (jref = 0; jref < n; jref++) {
// compare columns more right than jref and remove the col if duplicates
for (j = jref + 1; j < n; j++) {
match = TRUE;
for (i = 0; i < m; i++) {
if (mat[i][j] != mat[i][jref]) {
match = FALSE;
break;
}
}
if (match) {
deletecol(mat, m, n, j);
n--;
}
}
}
// see the result
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("%2d%s", mat[i][j], j == n - 1 ? "\n" : " ");
}
}
return 0;
}
Output with the provided example:
1 2 3
4 5 6
7 8 9
[Explanation]
As for the operations of rows:
First, focus on the top row as a "reference". The row is indexed by
the variable iref which is assigned to 0 at first.
Then compare the remaining rows with the reference, changing
the row index i from iref+1 (just below the reference row) to n-1
(the bottom row).
If a row duplicates with the reference, remove the row with the
deleterow() function and decrement the row size m by one.
The modification of m affects the for loops which compare the
loop variables with m, meaning the matrix size is updated immediately.
This is a preferable nature of the for loop (IMHO).
If the comparizon reaches the bottom row, increment iref and repeat
the comparisons again.
Finally every row has been compared to each other and the duplicates have
been deleted.
Then perform the similar operations with columns.

Inserting elements to array in C

My task is: If we look at any two neighbour values in an array, if the one on the right is two times greater than the one on the left, their average should be inserted between them and the new array consisting of old and new elements should be printed. I have a problem with moving the other elements after average.And using special functions or libraries is not allowed.I am beginner, and I hope you could help.
#include <stdio.h>
int main() {
int n, i, j;
double a[100], average;
printf("Enter the number of elements: ");
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%lf", &a[i]);
}
for (i = 0; i < n; i++) {
if ((a[i + 1] / a[i]) == 2) {
for (i = j = 0; i < n; ++i)
b[j++] = a[i];
if (a[i + 1] / a[i] == 2)
average = (a[i + 1] + a[i]) / 2;
b[j++] =average;
}
}
for (i = 0; i < j; ++i) {
printf("%lf\n", b[i]);
}
}
A simple way to solve your problem is adding double b[199];, and copying everything over:
for (i = j = 0; i < n; ++i) {
b[j++] = a[i];
if (...) b[j++] = ...; /* Append the average to b. */
}
for (i = 0; i < j; ++i) {
printf("%lf\n", b[i]);
}
If you really want to move the elements forward within a itself, then you can do it by adding an inner for loop (and an additional loop variable int k;) which copies the elements one-by-one:
for (k = n++; k > i; --k) {
a[k] = a[k - 1];
}
In order to insert an element in an array, you must copy the elements with higher index from the last one down.
Also avoid dividing by a[i] that can be zero, and properly handle 0,0 that match the criteria for inserting the average, and skip the inserted value to avoid inserting more zeros.
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, i, j;
printf("Enter the number of elements: ");
if (scanf("%d", &n) != 1 || n <= 0)
return 1;
double *a = malloc(sizeof(*a) * (2 * n - 1)); // allocate the array to the maximum size
if (a == NULL)
return 0;
for (i = 0; i < n; i++) {
if (scanf("%lf", &a[i]) != 1)
return 1;
}
for (i = 1; i < n; i++) {
if (a[i] == a[i - 1] * 2) {
for (j = n; j > i; j--)
a[j] = a[j - 1];
a[i] = (a[i - 1] + a[i]) / 2;
n++; // increase number of elements
i++; // skip the new value
}
}
for (i = 0; i < n; ++i) {
printf("%f\n", a[i]);
}
free(a);
return 0;
}
To insert an element in a specific position you would need to move the rest of the array. However doing it many times is expensive and you may prefer to use an array to store the position at which you want to insert the elements and then insert them all at once.
Alternatively you can create a new array where to copy the original plus the new values.
However there's an easier and faster way, that is adding the new values straight away, while you fill the original array. Here's a program that does that.
#include <stdio.h>
#define SIZE 100
int main() {
int i, n, avg = 0;
double a[SIZE];
while( puts("Enter the number of elements:") && (scanf("%d", &n) != 1 || n < 1 || n > SIZE) );
scanf("%lf", &a[0]);
for(i = 1; i < n+avg && i < SIZE-1 && scanf("%lf", &a[i]) == 1; i++) {
if( a[i] == a[i-1] * 2 ) {
a[i+1] = a[i];
a[i] = (a[i] + a[i-1]) / 2;
++avg;
++i;
}
}
for(i = 0; i < n+avg; i++) {
printf("%lf\n", a[i]);
}
return 0;
}

Why are random values shown as output to find determinant of a matrix?

I wanted to find determinant of a M*M matrix by using recursion in C.
Here is the code I have tried in Ubuntu.
// Computing determinant of a MXM matrix
#include <stdio.h>
int determinant(int M, int A[10][10]) { //Function to calculate det(A)
int i, j, k, m, n, p, q, pow = 1;
int B[10][10];//assuming M does not cross 10
if (M == 1)
return A[0][0];
else {
det = 0;
for (k = 0; k < M; k += 1) {
m = 0;
n = 0; //m,n are indices of subdeterminant of A
for (i = 0; i < M; i += 1) {
for (j = 0; j < M; j += 1) {
if (i != 0 && j != k) {
B[m][n] = A[i][j]; //finding submatrix
if (n < (k - 2))
n += 1;
else {
n = 0;
m += 1;
}
}
}
}
det += pow * (A[0][k] * determinant(M - 1, B));
pow = -1 * pow;
}
return det;
}
}
int main() {
int M, i, j; // M is order of matrix A for which determinant has to be found
printf("Enter the order of matrix: ");
scanf("%d", &M);
int A[10][10];
printf("Enter matrix A: ");
for (i = 0; i < M; i += 1) {
for (j = 0; j < M; j += 1) {
scanf("%d", &A[i][j]); //Entering elements of matrix A
}
}
printf("Given matrix A is: \n");
for (i = 0; i < M; i += 1) {
for (j = 0; j < M; j += 1) {
printf("%d ", A[i][j]);
}
printf("\n");
}
int det = determinant(M, A);
printf("The determinant of given matrix is %d\n", det);
return 0;
}
This code works fine for a matrix of order 2. But for higher orders, the output is some random number. I am unable to identify any mistake in this. Can anyone explain why the output is not as expected and how to rectify the code to get the expected output?
The inner loop that extracts the submatrix B from A seems broken.
Here is a simpler version:
for (i = 1, m = 0; i < M; i++, m++) {
for (j = 0, n = 0; j < k; j++, n++)
B[m][n] = A[i][j];
for (j = k + 1; j < M; j++, n++)
B[m][n] = A[i][j];
}

Is there a way that I can scan the value of int before I implement it into the array?

I want here to implement the value of array[i][j] into itself, but firstly I have to check if it is in range between example: -99 and 99. If the input is out of these boundaries, it should stop the program.
I tried it with a do-while loop and just now I tried while loop.
#include <stdio.h>
#include <stdlib.h>
int main(){
int array[2][2], i, n, j;
/*
do
{
printf("Value= ");
scanf("%d", &n);
array[i][j] = n;
i++;
j++;
}
while(n < 99 && n > -99);
*/
while(array[i][j] < 99 && array[i][j] > -99){
for(i = 0; i < 2; ++i){
for(j = 0; j < 2; ++j){
printf("Value= ");
scanf("%d", &array[i][j]);
}
}
}
// Print the result
for(i = 0; i < 2; ++i){
for(j = 0; j < 2; ++j){
printf("\n[%d][%d]: ", array[i][j]);
}
}
}
I got a endless loop which doesn't exit if the value is incorrect (out of these boundaries).
Try this, tested and works:
int *array, i, val, n, m;
printf("Put in array size in the form of n-m where n is number of rows and m is number of columns: ");
scanf("%d-%d", &n, &m);
array = (int *) malloc(sizeof(int) * n * m);
i = 0;
while (i < n * m) {
printf("Value for row: %d, column: %d: ", i / m + 1, i % m + 1);
scanf("%d", &val);
if (val > 99 || val < -99) continue;
*(array + i) = val;
i++;
}
for (i = 0; i < n * m; i++) {
if (i > 0 && i % n == 0) printf("\n");
printf("%d\t", *(array + i));
}
free(array);
Without pointers (Variable sized arrays does not work on C90, needs newer standard, or you may use fixed sized arrays):
int i, val, n, m;
printf("Put in array size in the form of n-m where n is number of rows and m is number of columns: ");
scanf("%d-%d", &n, &m);
int array[n][m];
i = 0;
while (i < n * m) {
printf("Value for row: %d, column: %d: ", i / m + 1, i % m + 1);
scanf("%d", &val);
if (val > 99 || val < -99) continue;
array[i / m][i % m] = val;
i++;
}
for (i = 0; i < n * m; i++) {
if (i > 0 && i % n == 0) printf("\n");
printf("%d\t", array[i / m][i % m]);
}
In your array undefeated values, in the first while you try to check random number in your memory. And so your i j will be random number.
Put if statement in your for loop to check the value in array, and delete while loop

Resources