C: How to delete adjacent duplicates in 1D array? - c

Say I have an array:
int {2, 2, 2, 6, 6, 2, 2, 5, 5, 5}
and I want to delete all the adjacent duplicates so that it becomes
int {2, 6, 2, 5}
How can I do this?

Not sure what you have tried. My idea would be like this.
int i, num[] = {2, 2, 2, 6, 6, 2, 2, 5, 5, 5};
// Prepare new array for the result (result never larger than num[])
int *newNum = malloc(sizeof(num));
int used = 0, last = 0;
// Get number of elements in num[], which is 10 in this example
size_t n = sizeof(num) / sizeof(int);
for (i = 0; i < n; i++)
{
if (num[i] != last)
{
newNum[used++] = num[i];
}
last = num[i];
}
printf("new array: \n");
for (i = 0; i < used; i++)
{
printf("%i ", newNum[i]);
}

like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
int size = 10;
int *array = memcpy(malloc(size * sizeof(*array)), (int[]){2, 2, 2, 6, 6, 2, 2, 5, 5, 5}, size * sizeof(*array));
int i, new_size;
for(i = new_size = 1; i < size; ++i){
if(array[new_size-1] != array[i])
array[new_size++] = array[i];
}
if(size > new_size){
size = new_size;
array = realloc(array, size * sizeof(*array));
}
for(i = 0; i < size; ++i)
printf("%d ", array[i]);//2 6 2 5
free(array);
return 0;
}

Related

To prints the element that is in the fourth row and second column of matrix

#include <stdio.h>
int main( ){
int matrix[][4] = {{14, 10, 6, 4}, {3, 7, 18, 11}, {13, 9, 5, 17}, {19, 12, 2, 1}};
int sum = 0;
for (int i = 0; i < 1; i++)
{
for (int j = 0; j < 1; j++)
{
int num = matrix[i + 3][j + 1];
printf("%i\n", num);
}
}
}
// 4th row and 2nd column
But told to access by doing so , i am unable to do so array[rowNumber - 1][columnNumber - 1]. Please help
The description is a little bit ambiguous. Here is a demo showing access elements and iterative elements operations.
BTW, for the c language, the indexes are all 0-based. For example index 3 means the 4th element.
int main( ){
int matrix[][4] = {{14, 10, 6, 4}, {3, 7, 18, 11}, {13, 9, 5, 17}, {19, 12, 2, 1}};
int sum = 0;
printf("%d\n",matrix[3][1]); // access 4th row and 2nd column
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
sum += matrix[i][j]; // iterative all elements
}
}
printf("sum: %d\n",sum);
return 0;
}

How to transpose a 2 dimensional array on C via call by reference?

As the title says, I am trying to transpose a 2 dimensional matrix by calling by reference.
I have attached my code below. When I run the code, the 2 dimensional array is unchanged.
#include <stdio.h>
#define SIZE 4
void transpose2D(int ar[][SIZE], int rowSize, int colSize);
int main()
{
int testArr[4][4] = {
{1, 2, 3, 4},
{5, 1, 2, 2},
{6, 3, 4, 4},
{7, 5, 6, 7},
};
transpose2D(testArr, 4, 4);
// print out new array
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d ", testArr[i][j]);
}
printf("\n");
}
return 0;
}
void transpose2D(int ar[][SIZE], int rowSize, int colSize)
{
for (int i = 0; i < rowSize; i++)
{
for (int j = 0; j < colSize; j++)
{
int temp = *(*(ar + i) + j);
*(*(ar + i) + j) = *(*(ar + j) + i);
*(*(ar + j) + i) = temp;
}
}
}
Have been stuck for a couple of hours, any help is greatly appreciated, thank you!
To fix your function I suggest:
switch element only once, the previous version swapped elements for i=a, j=b and i=b,j=a, so the matrix remained unchanged
use a common a[i][j] syntax
let the non-square matrix be embedded into a larger matrix whose inner dimensions is set to stride.
using VLAs to make the interface a bit more generic
void transpose2D(size_t rows, size_t cols, size_t stride, int ar[][stride]) {
assert(rows <= stride);
assert(cols <= stride);
for (size_t i = 0; i < rows; i++) {
for (size_t j = i + 1; j < cols; j++) {
int tmp = ar[j][i];
ar[j][i] = ar[i][j];
ar[i][j] = tmp;
}
}
}
Exemplary usage:
int testArr[4][4] = {
{1, 2},
{5, 1},
{6, 3},
};
transpose2D(3, 2, 4, testArr);
The algorithm is still very inefficient due to terrible cache miss rates on access to a[j][i]. It can be fixes by tiling and transposing smaller 8x8 blocks, but it is a topic for another day.

How to shift array elements 2 times to the right by two values in C?

I have an array [1, 2, 3, 4, 5, 6, 7, 8] and I need to get [__, __, 1, 2, 3, 4, 5, 6] where I can put my new elements in the blank spaces. I tried to do it in a standard way:
int temp1 = arr[len - 1];
int temp2 = arr[len - 2];
for (int i = len - 1; i > 1; i -= 2) {
arr[i] = arr[i - 1];
arr[i - 1] = arr[i - 2];
}
arr[0] = temp1;
arr[1] = temp2;
but it seems to do nothing at all.
You're only moving elements by one space, not by two. Take a look at the following:
#include <stdio.h>
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
int len = sizeof(arr) / sizeof(int);
printf("len = %d\n", len);
int temp1 = arr[len - 1];
int temp2 = arr[len - 2];
printf("temp1 = %d\n", temp1);
printf("temp2 = %d\n", temp2);
for(int i = len-1 ; i > 1 ; --i)
{
printf("Moving arr[%d] to arr[%d]\n", i-2, i);
arr[i] = arr[i-2];
}
arr[0] = temp1;
arr[1] = temp2;
for(int i = 0 ; i < len ; ++i)
printf("arr[%d] = %d\n", i, arr[i]);
}
onlinegdb here
EDIT
And if you'd rather do away with the loop and just copy the memory in one shot you can use:
#include <stdio.h>
#include <string.h>
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
int len = sizeof(arr) / sizeof(int);
printf("len = %d\n", len);
int temp1 = arr[len - 1];
int temp2 = arr[len - 2];
printf("temp1 = %d\n", temp1);
printf("temp2 = %d\n", temp2);
memmove(((int *)arr)+2, arr, (len-2)*sizeof(int));
arr[0] = temp1;
arr[1] = temp2;
for(int i = 0 ; i < len ; ++i)
printf("arr[%d] = %d\n", i, arr[i]);
}
Note here that I've used memmove instead of memcpy because the source and destination buffers overlap. memmove handles this correctly, while memcpy is not required to do so.
onlinegdb here
I suppose that code rewrite right this way
int arr[8] = { 1,2,3,4,5,6,7,8 };
for( int i = 0 ; i < 8 ; i++ ){
arr[7-i] = arr[7-i-1];
}
for( int i = 0 ; i < 8 ; i++ ){
arr[7-i] = arr[7-i-1];
}
//here, arr[8] = { 1,1,1,2,3,4,5,6 }
//so, you can put new two elements in arr[0], arr[1]
the below might be useful for you,
#include <stdio.h>
#include <memory>
int main()
{
int temp1[8] = {1, 2, 3, 4, 5, 6, 7, 8};
int temp2[10] = { 0 }; // to avoid garbage values in 0 & 1 positions or you may find a place holder to indicate empty
memcpy(&temp2[2], temp1, sizeof(temp1));
for (int i = 0; i < 10; ++i)
printf("%d ", temp2[i]);
}

Finding all the Palindromes in int array C

It might seem like long but I over explained it.
So I have my problem is not necessarily finding the palindromes it is just the finding the length of the palindrome I can't figure out and my code doesn't work for single digit palindromes (yes we count them too) so here is the code and the explanation:
#include <stdio.h>
#define LEN 9
int *lastEqual(int *p, int *q) {
int *rightmost;
int *temp;
int *zero = p;
while (p <= q) {
if (*zero == *(p + 1)) {
temp = p + 1;
if (temp < q) {
rightmost = temp;
}
}
p++;
}
return rightmost;
}
What this funtion does or suppose to do:
*For the given array: {3,6,7,8,7,6,5,3,5} If lastEqual is called by the references of the
bold numbers, it returns a pointer to 3.(The one closest to the end of array)*
*For the given array: {3,6,7,8,7,6,5,3,5} If lastEqual is called by the references of the
bold numbers it returns a pointer to 6.*
Here is the second function:
int isPalindromic(int *p, int *q) {
int *left = p;
int *right = q;
int pali;
while (left < right) {
if (*left == *right) {
pali = 1;
} else {
pali = 0;
}
left++;
right--;
}
return pali;
}
Here is what it does or is supposed to do:
For the given array: {3,6,7,8,7,6,5,3,5} If isPalindromic is called by the references of
the bold numbers it returns 0, since the numbers between those addresses do not
represent a palindrome.
For the given array: {3,6,7,8,7,6,5,3,5} If isPalindromic is called by the references of
the bold numbers it returns 1, since the numbers between those addresses represent
a palindrome.
And here is the main function:
int main() {
int *p, *q, *rightmost;
int arr[LEN] = { 3, 6, 7, 8, 7, 6, 5, 3, 5 };
p = arr;
q = p + (LEN - 1);
for (int i = 0; i < LEN; i++) {
if (isPalindromic(p + i, lastEqual(p + i, q)) == 1) {
rightmost = lastEqual(p + i, q);
printf("Palindrome at index %d, length %ld\n", i, &p - &rightmost);
}
}
return 0;
}
And the output should be like these but I cant figure out how to find lenght and why it doesnt count the single digit number as a palindrome like this 8 :
{3,6,7,8,7,6,5,3,5} so 3 to 3 is not a palindrome 6 to 6 is 7 to 7 is and 8 should be counted as well because there is not a pair of 8
The output Should be like these:
Input Array: {1}
Output: “palindrome at index 0, length: 1”
Input Array: {5, 6, 7, 8, 7, 6, 5, 2, 5}
Output: “palindrome at index 0, length: 7”
Input Array: {2, 7, 6, 11, 10, 11, 6, 5, 3}
Output: “palindrome at index 2, length: 5”
Input Array: {7, 8, 9, 8, 7}
Output: “palindrome at index 0, length: 5”
Input Array: {2, 7, 4, 3, 2, 6, 1, 2, 1}
Output: “palindrome at index 6, length: 3”
Here is a simpler version of isPalindromic with the same arguments, and a much simpler version of main() to find all palindromes:
#include <stdio.h>
int isPalindromic(int *p, int *q) {
while (p < q) {
if (*p++ != *q--)
return 0;
}
return 1;
}
int main() {
int arr[] = { 3, 6, 7, 8, 7, 6, 5, 3, 5 };
int len = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < len; i++) {
for (int j = i; j < len; j++) {
if (isPalindromic(arr + i, arr + j))
printf("Palindrome at index %d, length %d\n", i, j - i + 1);
}
}
return 0;
}
If you just want to output the longest palindrome, change the main function to this:
int main() {
int arr[] = { 3, 6, 7, 8, 7, 6, 5, 3, 5 };
int len = sizeof(arr) / sizeof(arr[0]);
int max_pos = 0, max_len = 1;
for (int i = 0; i < len; i++) {
for (int j = i + max_len; j < len; j++) {
if (isPalindromic(arr + i, arr + j)) {
max_pos = i;
max_len = j - i + 1;
}
}
}
printf("Longest palindrome at index %d, length %d\n", max_pos, max_len);
return 0;
}

Code that compares two non-sorted int arrays. C

I need to create a code that compares two in arrays without sorting them. They have to be the same length and contain the same elements in any order.
every integer in a[] is also in b[]
every integer in b[] is also in a[]
all such common values appear exactly the same
number of times in both a[] and b[]
Examples:
a = {1, 2, 3}, b = {2, 3, 4} return 0
a = {1, 2, 3}; b = {2, 3, 1} return 1
a = {1, 2, 2}; b = {2, 2, 1} return 1
a = {1, 2, 2}; b = {2, 1, 1} return 0
a = {1, 1, 2, 2, 2}; b = {2, 1, 2, 1, 2} return 1
I just don't know what to do for this one...
You will end up with a quadratic algorithm if the arrays are not sorted. You can check array lengths at the beginning of your algorithm and if they are equal, say N, you would do something like this
int result = 1;
for (int j=0;j<N;j++) {
bool found = false;
for (int i=0;i<N && !found;i++) {
if (a[j] == b[i]) found = true;
}
if (!found) return 0;
}
I took sometime away and got it within a minute:D
int same_contents(int a[], int b[], int n){
int maxA=0,maxB=0,counterA=0,counterB=0;
int i,k,j,x;
for(i=0; i<n; ++i)
if (a[i]>maxA)maxA=a[i];
for(i=0; i<n; ++i)
if (b[i]>maxB)maxB=b[i];
if (maxA != maxB) return 0;
for(j=0;j<n;++j){
counterA=0;
counterB=0;
for(k=0;k<n;++k){
if(maxA==b[k])counterA++;
if(maxA==a[k])counterB++;
}
if (counterA != counterB) return 0;
else continue;
}
return 1;
}
You can try this!
#include<stdio.h>
int check_same_array(int a[], int b[],int lenA,int lenB)
{
int result = 0;
bool flag = false;
int i = 0,j=0;
if (lenA != lenB)
return 0;
for (i = 0; i < lenA; i++)
{
flag = false;
for (j = 0; j < lenB; j++)
{
if (a[i] == b[j])
flag = true;
}
if (!flag)
{
result = 0;
break;
}
}
if (flag)
result = 1;
return result;
}
int main()
{
int a[5] = { 2, 2, 3, 3 ,5};
int b[5] = { 3, 3, 2, 2 ,5};
int lenA = sizeof(a) / sizeof(int);
int lenB = sizeof(b) / sizeof(int);
printf("%d\n", check_same_array(a, b, lenA, lenB) && check_same_array(b, a, lenB, lenA));
return 0;
}
check_same_array is used to check if each item in array A is in array B.
So if each item in array A is in array B,and each item in array B is in array A.
the item of the two array is same.

Resources