C: Ignoring a value while scanning an array - c

I'm analyzing an array and, using an struct to save the position and the value of each item, I want to get the three minimum values of this array. The problem with this is that I've to ignore a value, '-5' in this case. And if I try to ignore this value, the index messes up and I don't know how to do it.
This is my try:
#include <cstdlib>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
typedef struct pair {
int value, column;
} Pair;
int cmp(const void *a, const void *b);
int main(int argc, char** argv) {
Pair data_pair[8];
int row[8] = {0, 3, 1, -5, 1, 2, 3, 4};
for (int i=0;i<8;++i){
if (row[i] != -5){ // Ignore the value -5 from the array
data_pair[i].value = row[i];
data_pair[i].column = i;
}
}
printf("\n\nThe three minimum values of this line are:");
qsort(data_pair, 8, sizeof(Pair), cmp);
for(int i=0;i<3;++i)
printf("\nvalue = %d, column = %d", data_pair[i].value, data_pair[i].column);
return 0;
}
int cmp(const void *a, const void *b){
Pair *pa = (Pair *)a;
Pair *pb = (Pair *)b;
return pa->value - pb->value; }
This is the exit I'm having:
The three minimum values of this line are:
value = 0, column = 0
value = 0, column = 0
value = 1, column = 4
When the desired solution is:
The three minimum values of this line are:
value = 0, column = 0
value = 1, column = 2
value = 1, column = 4
What I'm doing wrong? I would like to have a solution just changing some parts of the exposed code. Thanks in advance

Your issue at hand stems from using a shared index i and sorting the array regardless of how many items you actually have in the array (e.g. passing 8 unconditionally as the size).
By not setting the values at all indexes in data_pair, you're sorting some garbage results in the mix!
So you can use a second indexer with data_pair to help filter the results:
/* somewhere above: int j; */
for (i=0, j=0;i<8;++i){
if (row[i] != -5){ // Ignore the value -5 from the array
data_pair[j].value = row[i];
data_pair[j].column = i;
j++; /* indexes data_pair */
}
}
Now j will contain the count of found Pairs in data_pairs:
/* j substitutes for an explicit 8 */
qsort(data_pair, j, sizeof(Pair), cmp);

if (row[i] != -5){ // Ignore the value -5 from the array
data_pair[i].value = row[i];
data_pair[i].column = i;
} else {// add
data_pair[i].value = INT_MAX;//#include <limits.h>
data_pair[i].column = i;
}

Related

How do I clone an array and move the index by +1 in C?

The challenge on CodeSignal is the following:
Given an array of integers, find the pair of adjacent elements that has the largest product and return that product.
My plan is to create a secondArray offset by +1 to the right and then multiple inputArray by secondArray. This will give the product of a pair of adjacent elements. After I will return the max of the productArray as the solution. I can't seem to get past the first hurdle, that is to shift the elements of the array by +1 to give the secondArray.
`
// Arrays are already defined with this interface:
// typedef struct arr_##name {
// int size;
// type *arr;
// } arr_##name;
//
// arr_##name alloc_arr_##name(int len) {
// arr_##name a = {len, len > 0 ? malloc(sizeof(type) * len) : NULL};
// return a;
// }
//
//
int solution(arr_integer inputArray) {
int productArray;
productArray = inputArray[0] * inputArray[0++];
}
`
C does not have any built-in notation that would multiply two arrays nor any built in notation that says to give a view of an array that is offset by one element from its normal base (although pointers can be used to that effect).
To compute the desired products, you should write a loop that iterates over the positions in the array.
It is generally good advice to study C through a primer or textbook rather than attempting to learn it by working on online contests or challenges.
You don't need to waste memory by "cloning" the original array; simply iterate over the number of adjacent pairs, calculate the product, and see if it is the largest so far.
There are easily at least a dozen different specific ways to do it that come to mind immediately, and you could probably gin up some more if you gave it some thought. This way uses pointers to the adjacent elements in each pair.
#include <stdio.h>
#define SIZE 10
int solution(int *arr, int arrayLen);
int main(int argc, char* argv[]) {
int arr[SIZE] = {11, 22, 43, 44, 59, 36, 27, 58, 19, 20};
printf("%d is the largest", solution(arr, SIZE));
return 0;
}
int solution(int *arr, int arrayLen) {
int max = 0;
if (arr) {
int *p1 = arr;
int *p2 = p1 + 1;
// for a given array of size N, there are N - 1 adjacent pairs
// so we iterate over the NUMBER OF PAIRS
for (int i = 0; i < arrayLen - 1; i++) {
int value = *p1++ * *p2++;
if (value > max) {
max = value;
}
}
}
return max;
}

struct and typedef initialization

I am not sure why I am not getting a display on the console for the value of maxProd. I think I am declaring the arr_integer array variable wrong in main?
I ran a couple tests and the program looks like it does not even get to call solution().
Any help would be greatly appreciated. I am trying to get this to work and get rid of the following warnings;
Adjacent_Element_Product.c:31:40: note: (near initialization for 'array')
Adjacent_Element_Product.c:31:43: warning: excess elements in struct initializer
#include <stdio.h>
typedef struct arr_integer {
int size;
int *arr;
} arr_integer;
arr_integer alloc_arr_integer(int len) {
arr_integer a = {len, len > 0 ? malloc(sizeof(int) * len) : NULL};
return a;
}
int solution(arr_integer inputArray) {
int maxProd = inputArray.arr[0] * inputArray.arr[1];
for (int i = 1; i < inputArray.size - 1; i++)
{
int product = inputArray.arr[i] * inputArray.arr[i + 1]; //multiple next door neighbours.
if (product > maxProd)
maxProd = product;
}
return printf("maxProd: %d\n", maxProd);
}
int main()
{
arr_integer array = {3, 6, -2, -5, 7, 3};
solution(array);
return 0;
}
The problem is that you don't allocate memory for the array and that it then tries to use the list of integers as an int*.
A possible remedy:
#define Size(x) (sizeof (x) / sizeof *(x))
int main() {
int ints[] = {3, 6, -2, -5, 7, 3};
arr_integer array = {.size = Size(ints), .arr = ints};
solution(array);
}
Here are the relevant changes:
added <stdlib.h> for malloc
eliminated alloc_arr_integer() which was not used
maxProd is initialized to INT_MIN and tweaked initial loop condition to reduce duplication
to make the solution a little smaller passing the value inline to solution (#TedLyngmo probably gave you a better solution)
Not fixed:
arr_integer doesn't seem to add any value so maybe just pass size and array to solution(). You could create a macro to initialize it using the approach #TedLyngmo shared with you. It has to be a macro as int [] degrades to int * in a function call, and the latter (silently?) gives you the wrong result which makes it error prune.
Does negative size make sense? If not then use an unsigned type.
What is the solution if size < 2?
solution() returns the value from printf() which is strange. You might want to return maxProd and have main() print out the value. This makes your function testable
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct arr_integer {
int size;
int *arr;
} arr_integer;
int solution(arr_integer inputArray) {
int maxProd = INT_MIN; // what is answer if size < 2? error?
for (int i = 0; i < inputArray.size - 1; i++) {
int product = inputArray.arr[i] * inputArray.arr[i + 1]; //multiple next door neighbours.
if (product > maxProd)
maxProd = product;
}
return printf("maxProd: %d\n", maxProd);
}
int main() {
solution((arr_integer) {
6,
(int []) { 3, 6, -2, -5, 7, 3 }
});
return 0;
}
and the output is:
maxProd: 21

Passing arrays as arguments in C

I'm trying to make a function that identifies the maximum value in an array and calculate the sum of each time it appears. That's fine but the problem is that I need to make the function args the size of the array and the array itself.
This is what I've come up this far:
int sum(int a, int size)
{
int i, max, output=0;
//checking every index for max value
for(i=0;i<=tam;i++){
if(i==1){
//setting max on the first index
max=a[i];
}else{
if(a[i]>max){
a[i]=max;
}
}
}
//making the sum
for(i=0;i<size;i++){
if(a[i]==max);
output=output+max;
}
printf("%d", output);
}
The argument "a" is the array and the size is the size of the array. I get errors saying "a" is neither array nor pointer nor vector.
Any help is apreciated.
Replace int sum(int a, int size) to int sum(int *a, int size) or int sum(int a[], int size)
This function declaration
int sum(int a, int size);
declares a function with two parameters of the type int. If you mean that the first parameter should specify a one-dimensional array then the function declaration will look like
int sum(int a[], int size);
or
int sum( int *a, int size);
because a parameter having an array type is adjusted by the compiler to pointer to the array element type.
Also your function returns nothing though its return type is not void.
Moreover the function uses undeclared variables as for example the variable tam.
And if an array has size elements then the valid range of indices is [0, size ).
Also the function should not change the passed array. And to avoid integer overflow the return type should be long long int.
Also the function should not output any message. It is the caller of the function that decides whether to output a message.
The function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
long long int sum( const int a[], size_t n )
{
long long int total = n == 0 ? 0 : a[0];
size_t max = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( a[max] < a[i] )
{
total = a[i];
max = i;
}
else if ( !( a[i] < a[max] ) )
{
total += a[max];
}
}
return total;
}
int main(void)
{
int a[] = { 2, 8, 8, 9, 7, 3, 8, 1, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
printf( "The sum of elements with the maximum value is %lld\n", sum( a, N ) );
return 0;
}
The program output is
The sum of elements with the maximum value is 18
#include<stdio.h>
#include<stdlib.h>
int sum(int *a, int size);
int main()
{
int *a=(int*)malloc(10*sizeof(int));
for(int i=0;i<10;i++)
a[i]=i+1;
sum(a,10);
}
int sum(int *a, int size)
{
int i, max, output=0;
//checking every index for max value
for(i=0;i<size;i++){
if(i==1){
//setting max on the first index
max=a[i];
}else{
if(a[i]>max){
a[i]=max;
}
}
}
//making the sum
for(i=0;i<size;i++){
if(a[i]==max);
output=output+max;
}
printf("%d", output);
}
Well, you can do it in just one pass, as when you identify a new maximum, the accumulated sum of the last is no longer valid (it refers not to the biggest number, but to one smaller)
There's something in your code that is weird... you start the loop at 0, and then compare if (i == 1) which I guess is a mistake (shouldn't it be 0?), as you should want to check if you are at the first (and not at the second cell) to do the initialization of max. Anyway, there's a clever way to do is to initialize max to the minimum number you can have (and for an int you have that value in <limits.h> as the constant INT_MIN). I'll show you now one possible source code to your problem (taken from yours, but changed some variables and added others to show you that in one pass you can do a lot of work:
#include <stdio.h>
#include <limits.h>
/* pretty format of output with location of trace in source file
*/
#define F(_fmt) __FILE__":%d:%s: "_fmt,__LINE__,__func__
/* to pass an array, just declare it as below. The array size is
* unspecified because your don't know it before calling sum,
* and this is the reason to pass the array size. */
int sum(int a[], int size)
{
int i, pos0 = -1, pos1 = -1, max = INT_MIN, output=0;
/* checking every index for max value, and output, you made
* an error here and used tam instead of size. */
for(i = 0; i <= size; i++){
if (a[i] > max) { /* if greater than max */
pos0 = i; /* save position as first */
max = a[i]; /* save max value */
output = max; /* initialize output to max */
} else if (a[i] == max) { /* if equal to max */
pos1 = i; /* save position as last */
output += max; /* add to output */
} /* else nothing */
}
/* print all the values we got */
printf(F("pos0 = %d, pos1 = %d, max = %d, output = %d\n"),
pos0, pos1, max, output);
return output; /* return the requested sum */
}
int list[] = { 3, 2, 5, 6, 5, 4, 7, 3, 7, 4, 7, 2, 1, 6, 2 };
/* max is located ^ ^ ^ in these positions
* 6 8 10 */
/* the following macro gives us the size of the array list by
* dividing the size of the complete array by the size of the
* first element. */
#define n_list (sizeof list / sizeof list[0])
int main()
{
printf(F("result = %d\n"), sum(list, n_list));
}
which should output (if the program is named test from test.c):
$ test
test.c:23:sum: pos0 = 6, pos1 = 10, max = 7, output = 21
test.c:34:main: result = 21
$ _

Finding frequency of an integer in an array and calculating x to the nth power

I am trying to solve two different C problems and would like some help and advice in order to better understand how C works and if I'm on the right track with these.
First problem is: To write a function that counts the number of times the value (x) appears among the first (n) elements of an array and returns that count as the frequency of x in theArray. So, an example would be if the array being passed contained the values {5, 7, 23, 8, 23, 67, 23}. And n was 7 and x was 23, then it would return a value of 3 since 23 occurs 3 times within the first 7 elements of the array.
Here is what I have so far:
#include <stdio.h>
#define SIZE 20 /* just for example - function should work with array of any size */
int frequency (int theArray[], int n, int x)
{
int i;
int count = 0;
for (i = 0; i < n; i++)
{
if (theArray[i] == x)
{
count = count++;
}
}
return (count);
}
int main(void)
{
/* hard code n and x just as examples */
int n = 12; /* look through first 12 items of array */
int x = 5; /* value to find */
int numberFrequency;
long int theArray[SIZE] = {5,2,3,4,5,6,1,2,10,5,10,12,6,8,7};
numberFrequency = frequency (theArray[SIZE], n, x);
printf ("%i", numberFrequency);
return 0;
}
Currently I'm getting a run time error message and believe it has something to do with the for loop function.
Second problem is: Write a function that raises an integer to a positive integer power. Have the function return a long int, which represents the results of calculating x to the nth power. Do not use the C pow library function and do not use recursion!
My code so far:
#include <stdio.h>
int x_to_the_n (int x, int n)
{
int i;
long int result = 1;
if (n == 0)
{
return(result);
}
else
{
for (i = 0; i < n ; ++i)
{
/* equation here - How can I make (x*x*x*x*x*x,etc...? */
result = x*(n*x);
}
}
return (result);
}
int main(void)
{
int x =4;
int n =5;
long int result;
result = x_to_the_n (x, n);
printf ("%i", result);
return 0;
}
I can't use recursion so that is out of the question. So, I thought the next best thing would be a for loop. But I'm a little stuck in how I would go about making a for loop do (xxx*x....) based on value of (n). Any help and advice would be appreciated!
In the first problem you give an element after the array as a parameter to your function.
You define a long int array, and pass it into a function expecting an int array.
long int theArray[SIZE] = {5,2,3,4,5,6,1,2,10,5,10,12,6,8,7};
should be
int theArray[SIZE] = {5,2,3,4,5,6,1,2,10,5,10,12,6,8,7};
Instead of this:
numberFrequency = frequency (theArray[SIZE], n, x);
try this:
numberFrequency = frequency (theArray, n, x);
And replace:
count = count++;
with:
count++;

array modification in C

Not sure what i'm doing wrong here. I'm trying to circularly shift elements of a char array left by one. It seems to work, but not persist. I assume it's a pointer issue, but I still don't get how pointers work so i'm not sure where to begin. Problem is, it only seems to change the value inside the for loop and reset afterwards.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void ip();
int main(){
char d[10] = "010";
char k[10] = "1010000010";
initialPermutation(d, k);
return(0);
}
void ip(char * data, char* key){
int i;
// P10(k1, k2, k3, k4, k5, k6, k7, k8, k9, k10) = (k3, k5, k2, k7, k4, k10, k1, k9, k8, k6)
char P10[10] = {key[2],key[4],key[1],key[6],key[3],key[9],key[0],key[8],key[7],key[6]};
// split P10 into two segments
char left5[5] = {P10[0],P10[1],P10[2],P10[3],P10[4]};
char right5[5] = {P10[5],P10[6],P10[7],P10[8],P10[9]};
// pre shift binary string
printf("Pre-shift: ");
for(i=0;i<5;i++)
printf("%c",left5[i]);
for(i=0;i<5;i++)
printf("%c",right5[i]);
printf("\n");
// circular shift left one bit (here is where the problem is)
for(i=0;i<5;i++){
char templ = left5[4-i];
left5[4-i] = left5[i];
left5[i] = templ;
char tempr = right5[4-i];
right5[4-i] = right5[i];
right5[i] = tempr;
}
printf("Post- (outside for loop): ");
for(i=0;i<5;i++)
printf("%c",left5[i]);
for(i=0;i<5;i++)
printf("%c",right5[i]);
printf("\n");
}
Your loop is not shifting values, it is reversing the array twice.
It swaps index 0 with index 4, then 1 with 3, then 2 with 2, then 3 with 1, and finally 4 with 0. At this point the array is exactly as when you started.
This code does an actual rotary left shift:
char tmp = left5[0];
for(i = 1; i < sizeof(left5); ++i){
left5[i-1] = left5[i]
}
left5[4] = tmp;
If you actually declare the arrays one element too large you can write:
char left5[6] = {P10[0],P10[1],P10[2],P10[3],P10[4]};
left5[5] = left5[0]
for(i=0; i < 5; ++i){
left5[i] = left5[i+1];
}

Resources