Check sorting of an array - c

I'm trying to write a code that can check whether a dynamic array is sorted, but I get an error. The code has to be recursive.
When I input an unsorted array there seems to be no problem, but when I input a sorted array the program halts abruptly with:
Process return -1073741571
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int ordenado(int*);
int main() {
int i = 0, res = 0;
int*arr = NULL;
arr = (int*) malloc(sizeof (int));
while (arr[i] != 0) {
i++;
arr = (int*) realloc(arr, (i + 1) * sizeof (int));
scanf("%d", &arr[i]);
}
res = ordenado(arr);
printf("\n%d ", res);
return 0;
}
int ordenado(int* arr) {
if (arr[0] == 0) {
return 1;
}
if (arr[0] <= arr[1]) {
return ordenado(arr++);
}
else return 0;
}

Sorry my first answer was not right. I corrected below.
Explanation
I added scanf("%d", &arr[i]); before the loop to fill arr[0]
I changed the ordenado function
When you hit 0 then return 1
When you hit x but the next element is 0 then return 1 (Note the || is a short circuit. If you don't hit 0 then there is a next element. So you can check it for 0 here too.)
As soon as two numbers are not in order return 0 (I think that's faster)
Otherwise there is a next element that is not 0 and call ordenado(++arr) (prefix, not postfix)
Note about prefix and postfix:
The difference between prefix and postfix in many programming languages it the execution order. Assume i and j being 0 before execution in both statements.
i += ++j;
The above code is equivalent to this
j = j + 1;
i = i + j;
While the below code
i += j++;
is equivalent to this
i = i + j;
j = j + 1;
I.e. in prefix the increment takes place before the expression is evaluated, while in postfix the increment takes place after the expression is evaluated. This usually holds true not matter the data type (i.e. includes pointer).
Your line of code
return ordenado(arr++);
is equivalent with
return ordenado(arr);
a++;
which leads to infinite number of function calls as #BLUEPIXY pointed out.
Corrected code
#include <stdio.h>
#include <stdlib.h>
int ordenado(int*);
int main() {
int i = 0, res = 0;
int* arr = NULL;
arr = (int*) malloc(sizeof (int));
scanf("%d", &arr[i]);
while (arr[i] != 0) {
i++;
arr = (int*) realloc(arr, (i + 1) * sizeof (int));
scanf("%d", &arr[i]);
}
res = ordenado(arr);
printf("\n%d ", res);
return 0;
}
int ordenado(int* arr) {
if (arr[0] == 0 || arr[1] == 0)
return 1;
if (arr[0] > arr[1])
return 0;
else
return ordenado(++arr);
}
Example inputs and outputs:
Input: 0
Output: 1
Input: 1 newline 0
Output: 1
Input: 1 newline 2 newline 3 newline 0
Output: 1
Input: 2 newline 1 newline 0
Output: 0
Input: 1 newline 2 newline 3 newline 2 newline 3 newline 0
Output: 0

In these lines:
arr = malloc(sizeof (int));
while (arr[i] != 0)
You cannot count on malloc'd memory having any particular value. It is uninitialized.
It looks like you are using an input zero as a sentinel. The proper way to do this is:
int i = 0;
int *arr = malloc(sizeof (int));
do {
i++;
arr = realloc (arr, (i + 1) * sizeof (int));
scanf ("%d", &arr[i-1]);
} while (arr[i-1] != 0);
I have also fixed element zero not having been assigned a value.
I suspect the error you experienced was caused by runaway recursion.

Your code has multiple problems:
you read the first element of the array before storing it: it is uninitialized, even just reading it invokes undefined behaviour.
you never store the first element in the array (at offset 0)
if the array has at least one non zero element, when you compare the last 2 elements, you will get an potential mismatch since the last element is 0;
when you recurse, you pass arr before incrementing it, hence causing an infinite recursion. The fact that you get an error proves that the compiler does not handle tail recursion, and your code eventually fails with a stack overflow.
If you can change the API for the ordenado function, you should pass it the number of actual elements in the array. This function is supposed to be recursive, choose an algorithm that will limit the recursion to avoid stack overflow if the compiler does not detect tail recursion.
Here is my suggestion:
#include <stdio.h>
#include <stdlib.h>
int ordenado(int *array, int count);
int main() {
int i = 0, n, res;
int *arr = NULL;
while (scanf("%d", &n) == 1 && n != 0) {
arr = realloc(arr, (i + 1) * sizeof(int));
if (!arr) {
printf("out of memory\n");
return 1;
}
arr[i++] = n;
}
res = ordenado(arr, i);
printf("%d\n", res);
return 0;
}
int ordenado(int *arr, int n) {
int m = n >> 1;
return (m == 0) ||
(ordenado(arr, m) && arr[m - 1] <= arr[m] && ordenado(arr + m, n - m));
}
NB: Reallocating the array one int at a time is painfully inefficient, but is not the topic of this discussion.

Related

printing 2 characters and keeping them through dynamically allocated 2d array

Hello I am trying to print something like this with 2d array.
Note that when user enters the same number, character should be printed above existing char.
EXPECTED RESULTS:
Input 1: 3 //user1 inputs 3
****
****
**x*
Input 2: 1 //user2 inputs 1
****
****
y*x*
Input 3: 1 //user1 inputs 1
****
x***
y*x*
current results:
enter first: 3
3***
***
**x
enter second: 1
1******
******
xx****
enter first: 2
2*********
*********
***xxx***
But keeping printed values on its previous places.
The problem is that they don't get printed in right order. And also it seems that I haven't done the best job with 2d array which is dynamically allocated.
Here is something what I've tried:
#include <stdio.h>
#include <stdlib.h>
int num(int term)
{
int number1;
int number2;
if(term==1)
{
scanf("%d", &number1);
return number1;
}
if (term==2)
{
scanf("%d", &number2);
return number2;
}
return 0;
}
void function(int a, int b, int result[], int size)
{
int i = 0;
int j = 0;
int desired_num = 0;
int count = 0;
int *arr[a];
for (i = 0; i < a; i++)
arr[i] = (int *)malloc(a * sizeof(int));
for (i = 0; i < a; i++)
for (j = 0; j < b; j++)
arr[i][j] = ++count;
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (int counter = 0; counter < size; counter++)
{
if (arr[i][j] == arr[a - 1][result[counter] - 1])
{
arr[i][j] = desired_num;
}
if (arr[i][j] == desired_num)
{
printf("%s", "x");
}
else
{
printf("*");
}
}
}
printf("\n");
}
}
int main()
{
int counter = 1;
int i = 0;
int given_number;
int array[20];
for (;;)
{
if (counter % 2 != 0)
{
printf("enter first: ");
given_number = num(1);
printf("%d", given_number);
}
else
{
printf("enter second: ");
given_number = num(2);
printf("%d", given_number);
}
array[i] = given_number;
function(3, 3, array, counter);
counter++;
}
return 0;
}
array[i] = given_number;
i is never changed from the value of 0. You are only ever overwriting the first element of array each iteration. The other 19 elements remain in an indeterminate state.
counter and array are passed to function, as size and result respectively:
This means as size is incremented, it is used as a bounds for accessing elements of result; elements that contain indeterminate values.
for (int counter = 0; counter < size; counter++)
{
if (arr[i][j] == arr[a - 1][result[counter] - 1])
This will surely lead to Undefined Behaviour as those indeterminate values are used to index arr, effectively accessing random memory offsets. This fact alone makes it hard to reason about the output you are seeing, as really anything is valid.
While perfectly valid, the variable-length array of dynamic allocations is a somewhat perplexing choice, especially considering you fail to free the memory allocated by malloc when you are done with it.
int *arr[a];
for (i = 0; i < a; i++)
arr[i] = (int *)malloc(a * sizeof(int));
int arr[a][b]; would work, given a and b are not stack-crushingly large values (or non-positive). You are, or would be, bounded by the size of array in main anyway.
The triply nested loop is confused at best. There is only logic for printing the x and * characters, so you obviously will never see a y.
For each element of arr, you iterate through each element of result. If the current element of arr equals the value of the column selected by the current value of result ([result[counter] - 1]) in the last row (arr[a - 1]) you print x, otherwise *.
Again UB from utilizing indeterminate values of result, but you can see you are printing a * b * size characters, plus newlines, each iteration.
This is severely flawed.
Some other things of note:
The two branches of the if .. else statement in the num function do the exact same thing, just with different identifiers.
The two branches of the if .. else statement in main are identical, other than the first printf in each, and the integer value passed to num, which have the same effect.
This means the only thing that needs to branch is the printf argument.
A generic function for getting an integer would work fine
int get_num(void)
{
int n;
if (1 != scanf("%d", &n)) {
fprintf(stderr, "Could not read input.\n");
exit(EXIT_FAILURE);
}
return n;
}
for use inside main
if (counter % 2 == 0)
printf("enter first: ");
else
printf("enter second: ");
given_number = get_num();
A small issue: printf("%d", given_number); is muddling the output slightly.
There is no reason to repeatedly generate the array. Initialize an array in main to serve as the state of the program. Over time, fill it with the users' selections, and simply print the array each iteration.
Make sure to always check the return value of scanf is the expected number of conversions, and ensure the integers provided by the users will not access invalid memory.
Here is a cursory example.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EMPTY '*'
#define PLAYER_ONE 'X'
#define PLAYER_TWO 'O'
int get_num(void)
{
int n;
if (1 != scanf("%d", &n)) {
fprintf(stderr, "Could not read input.\n");
exit(EXIT_FAILURE);
}
return n;
}
int main(void)
{
const size_t rows = 6;
const size_t cols = 7;
char board[rows][cols + 1];
memset(board, EMPTY, sizeof board);
/* our rows are now strings */
for (size_t i = 0; i < rows; i++) {
board[i][cols] = '\0';
puts(board[i]);
}
unsigned char turn = 1;
while (1) {
printf("Player %s, Enter column #(1-%zu): ",
turn & 1 ? "One" : "Two", rows);
int input = get_num();
if (1 > input || input > cols) {
printf("Invalid column [%d]. Try again...\n", input);
continue;
}
size_t sel = input - 1;
if (board[0][sel] != EMPTY) {
printf("Column [%d] is full! Try again...\n", input);
continue;
}
size_t n = rows;
while (n--) {
if (board[n][sel] == EMPTY) {
board[n][sel] = turn & 1 ? PLAYER_ONE : PLAYER_TWO;
break;
}
}
for (size_t i = 0; i < rows; i++)
puts(board[i]);
turn ^= 1
}
}

Stuck in a for loop entering values to an array in C language

I am trying to practice with C by making a bubble sort program. The problem until now seems to be that the for loop that is giving values to the cells of the array is stuck after the condition is no longer fulfilled but it doesn't seem to be executing the commands in the loop. I don't know what is happening exactly and I have added some extra lines to see what is happening an these were my conclusions. Here is the code:
#include <stdio.h>
#include <stdlib.h>
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int *sort(int *array)
{
int finish = 1;
while (finish = 1)
{
finish = 0;
for (int i = 0; i <= sizeof(array); i++)
{
if ((array + i) > (array + i + 1))
{
swap(array + i, array + i + 1);
finish = 1;
}
}
}
return array;
}
int main()
{
int s, res;
printf("Give me the size of the array being sorted(larger than 1) : ");
do
{
res = scanf("%d", &s);
if (res != 1)
{
printf("Wrong Input!\n");
exit(1);
}
if (s < 2)
printf("Only numbers equal or larger than 2\n");
} while (s < 2);
int array[s];
for (int i = 0; i < s; i += 1)
{
scanf("%d", array + i);
printf("%d %d %d\n\n", *(array + i), i, i < s); // I used this to check if my values were ok
}
printf("end of reading the array"); //I added this line to see if I would exit the for loop. I am not seeing this message
sort(array);
printf("\n");
for (int i = 0; i < sizeof(array); i++)
printf("%d\n\n", array + i);
printf("Array has been sorted! Have a nice day!\n\n************************************************************");
return 0;
}
See the annotations in the code:
#include <stddef.h> // size_t 1)
#include <stdio.h>
#include <stdlib.h>
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int *sort(int *array, size_t size) // needs an extra parameter to know the size of the array
{
int finish = 1;
while (finish /* = 1 * you don't want assignment, you want comparison: */ == 1)
{
finish = 0;
for (int i = 0; i /* <= sizeof(array) */ < size - 1; i++) // i should be of type size_t
{
// if ((array + i) > (array + i + 1)) you are not dereferencing:
if(array[i] > array[i + 1])
{
// swap(array + i, array + i + 1); // easier to read imho:
swap(&array[i], &array[i + 1]);
finish = 1;
}
}
}
return array; // why does this function return anything? it is never used.
}
int main()
{
int s; /* , res; no need for an extra variable res */
printf("Give me the size of the array being sorted(larger than 1) : ");
do
{
// res = scanf("%d", &s);
// if (res != 1)
if (scanf("%d", &s) != 1)
{
printf("Wrong Input!\n");
// exit(1); // should be EXIT_FAILURE. Use return instead of exit() when in main().
return EXIT_FAILURE;
}
if (s < 2)
printf("Only numbers equal or larger than 2\n");
} while (s < 2);
int array[s];
for (int i = 0; i < s; /* i += 1* idiomatic: */ ++i) // size_t would be the correct type for s and i.
{
scanf("%d", /* array + i use indexes: */ &array[i]);
printf("%d %d %d\n\n", array[i], i, i < s); // again: indexes. i < s is allready ensured by the condition of the for-loop
}
printf("end of reading the array");
// sort(array); // sort will have no idea about the size of array use
sort(array, s); // instead.
printf("\n");
for (int i = 0; i < /* sizeof(array) 2) */ s; i++)
printf("%d\n\n", /* array + i * again you don't dereference */ array[i]);
printf("Array has been sorted! Have a nice day!\n\n************************************************************");
return 0;
}
1) size_t is the type that is guaranteed to be big enough to hold all sizes of objects in memory and indexes into them. The conversion specifier for scanf() is "%zu".
2) sizeof(array) in main() will yield the number of bytes in array, but you want the number of elements so you'd have to use sizeof(array) / sizeof(*array). But thats not needed since you already know its size. It is s.
This line
printf("end of reading the array");
has no line feed at the end of the string. This is a problem because printf is part of the family of functions called "buffered IO". The C library maintains a buffer of the things you want to print and only sends them to the terminal if the buffer gets full or it encounters \n in the stream of characters. You will not see, end of reading the array on your screen until after you have printed a line feed. You only do this after calling sort(). So all you know is your program is getting into an infinite loop at some point before the end of sort.
So there are actually three loops that could be infinite: the for loop you identified, the while loop in sort and the for loop inside the while loop. As the other answers point out, you have made the classic mistake of using assignment in the while conditional
while (finish = 1)
// ^ not enough equals signs
Unless your C compiler is really old, it is probably outputting a warning on that line. You should heed warnings.
Also, you should learn to use a debugger sooner rather than later. Believe me, it will save you a lot of time finding bugs.
In the sort function sizeof(array) returns the size of the pointer. (you can check it by yourself using printf("%d", sizeof(array).
The solution is to change your function to:
int sort(int* array, size_t size) { ... }
and call it with the correct array size:
sort(array, s);

Void function: removing elements from an array?

I want to make a function that removes elements from an array.
I attempted making the function myself, however, not fully successful:
void remove_element(int* array, int number, int array_length)
{
int i, j;
for (i = 0; i < array_length; i++){
if (array[i] == number) {
for (j = i; j < array_length; j++)
array[j] = array[j+1];
array_length--;
}
}
}
first thing I noticed is after function is called in main, array_lenght is not changed, therefore length of an array remains the same after removing element(s).
So the first question is how to change length of an array inside the void function?
Second thing which doesn't work properly is if in an array are two or more same numbers next to each other, for example if array contains 1,1,3,4,5,6 and user wants to remove 1 function will remove only one element.
Example of my output (wrong):
1,1,3,4,5,6 after fucntion 1,3,4,5,6
Thanks
In the current signature you cannot modify the array, as returning the new array you also need to return the new length.
There are many ways to do it, here is a way with a single loop:
void
remove_element(int* array, int number, int *array_length)
{
int i, j;
for (i = 0, j=0; i < *array_length; i++) {
if (array[i] != number)
array[j++] = array[i];
}
*array_length = j;
}
Doing so, this will mutate both the initial array and the variable keeping its length in the caller and you must pass the value of array_length by reference, somthing like
int* some_array, some_array_length, n;
remove_element(some_array, n, &some_array_length)
Other method would be to return the new length and mutate the array or allocate a new array in the heap and return both the allocated array and the new length.
The other answers to your question aside, if you're likely to do more than one removal on average (or more than one per call ever, actually), it's better not to shift all the subsequent values again and again. Try this:
void remove_element(int *array, int number, int *array_length) {
for(int iRead = 0, iWrite = 0; iRead < *array_length; iRead++) {
if(array[iRead] == number)
continue; /* skip without increasing iWrite */
if(iWrite < iRead) /* it works without this line, too, what's better depends */
array[iWrite] = array[iRead];
iWrite++;
}
*array_length = iWrite;
}
How this works, e.g., with array = {1,1,2,2,3} and number = 2:
1 1 2 2 3
^ iRead
^ iWrite
(increases both, writes nothing)
1 1 2 2 3
^ iRead
^ iWrite
(increases both, writes nothing)
1 1 2 2 3
^ iRead
^ iWrite
(continue happens: increases only iRead)
1 1 2 2 3
^ iRead
^ iWrite
(continue happens: increases only iRead)
1 1 2 2 3
^ iRead
^ iWrite
(writes 3 to iWrite, increases both)
1 1 3 2 3
^ iRead = 5
^ iWrite = 3
(iRead is no longer < *array_length, loop stops, 3 == iWrite is the new length)
Based now on your Comments, I'll do it like this:
#include <stdio.h>
void remove_element(int number, int *arr, size_t *size);
int main(void){
int arr[] = {1,1,3,4,5,6};
long unsigned int arrSize;
int number = 1;
arrSize = sizeof arr / sizeof arr[0];
printf("Before:\n");
for ( size_t i = 0 ; i < arrSize ; i++ ){
printf("%d ", arr[i]);
}
printf("\nAfter:\n");
remove_element( number, arr, &arrSize );
for ( size_t j = 0 ; j < arrSize ; j++ ){
printf("%d ", arr[j]);
}
printf("\n");
}
void remove_element(int number, int *arr, size_t *size){
int arrTemp[*size];
long unsigned int j = 0,c;
for ( size_t i = 0 ; i < *size ; i++ ){
if ( arr[i] == number ){
continue;
}else{
arrTemp[j] = arr[i];
j++;
}
}
for ( size_t k = 0 ; k < j ; k++ ){
arr[k] = arrTemp[k];
}
c = j;
while ( *size > c ){
arr[c] = 0;
c++;
}
*size = j;
}
Output:
Before:
1 1 3 4 5 6
After:
3 4 5 6
By the way in your Question you said:
Examples of output:
1,1,3,4,5,6 after fucntion 1,3,4,5,6
And in your Comment you said:
It doesn't matter how many same numbers there are, in that case above if user wants to remove 1, all 1 's should be removed.
Please make up your mind.
Because array_length is not passed as pointer you're having copy of it on stack, so after you're getting outside of this function you're still having old value. You could use here memmove or memcpy instead of iteration over whole array after you find the same number. The reason why you didn't delete the next 1 in your array is, because when you're on i = 0 -> array[0] == 1, but when you move all of the numbers back then you move second 1 to array[0], without checking it afterwards because after you finished iteration you just increment i, without checking if what you moved to current value of array[i] is the same as previous one.
void remove_element(int *array, int number, int *array_length){
int sameValues = 0;
for(int i = 0; i < *array_length; i++){
while(array[i] == number){
*array_length--;
sameValues++;
}
if(sameValues > 0){
if(i < *array_length){
memmove(&array[i], &array[i + sameValues], (*array_length - i) * sizeof(int));
}
sameValues = 0;
}
}
}
To make it even more dynamic you could use realloc (and actually resize the space occupied by your array after you remove members, but then either you need to return new pointer or you need to point to pointer on your stack from where you call the function:
void remove_element(int **array, int number, int *array_length){
int sameValues = 0;
for(int i = 0; i < *array_length; i++){
while((*array)[i] == number){
*array_length--;
sameValues++;
}
if(sameValues > 0){
if(i < *array_length){
memmove(&(*array)[i], &(*array)[i + sameValues], (*array_length - i) * sizeof(int));
}
realloc(*array, *array_length);
sameValues = 0;
}
}
}
P.S. To use memmove you need to include string.h
When you declare an array the compiler will affect an amount of memory, and with array structure you can't change it. There is 2 solutions, change your array length but you still could access to the last "box" or redefine an array with the size wanted.
1st case :
void remove_element(int* array, int number, int * array_length){
int i = 0,j = 0;
while( i < *(array_length)-1){
if(array[i] == number && !find){
i++; //we step over
find = 1; //we find 1 element stop remove
}
array[j] = array[i];
i++;
j++;
}
*(array_length)--;
}
The int * array_length is a pointer to the memory, so your changes are keep when you go back in main. In your example, before remove_element array_length is equal to 6, and after it's 5. But you still could do array[5] (6th element cause notation 0 to 5 in c).
2nd case
int * remove_element(int * array, int number, int * array_length){
int * new_array = malloc((array_length -1) * sizeof(int)); // len - 1 cause we want to delet only 1 element
int i = 0;
int j = i;
int find = 0;
while( i < *(array_length)-1){
if(array[i] == number && !find){
i++; //we step over
find = 1; //we find 1 element stop remove
}
new_array[j] = array[i];
i++;
j++;
}
if (array[array_length] != number && !find){ //if we didn't find att all the element return array
return array;
} else {
*(array_length)--;
return new_array;
}
}
Here you have to return the new_array because int array[6] in your main is a constant : you can't change it with array = new_array.
Edit : yes of course when you don't need anymore your array you have to free it with free(array) (or it's automatically done at the end of the processus, but it's not proper code)
There is also a shorter method with addtion of pointers but it seems quite too complicated with your c lvl :)

Given an array of single digit, positive integers, convert to a whole number, multiply by 2, return an array of new product with each digit in array

For example:
[1,2,3] -> [2,4,6]
[9,1] -> [1,8,2]
[6,7,5] -> [1,3,5,0]
I got this question on my first tech interview yesterday (did it in C because that's my best language, so a C answer would be help more) and completely blanked :(
This is what I was thinking:
Start at the end of the array and keeping moving left
At every arr[i], multiply by 2 and see if there're 2 digits (if arr[i]/10 != 0) and if there is a left most digit, carry it over to arr[i-1] as long as a[i-1] != NULL.
I just could not figure out how to actually do this in C. I had something like:
int* multTwo(int* arr, int len) {
int *newarr; // I know i have to malloc, but not sure what size because
// wouldnt the size depend on the new number's size?
int temp, i;
for (i=len-1; i>=0; i--) {
temp = arr[i]*2;
newarr[i] = temp%2;
if(temp/10 != 0)
newarr[i-1] = temp/2;
}
return newarr;
}
But there are a lot of bugs in my code. Is there a better way or am I on the right track?
Some pseudo code. The main idea is to show the depth of C knowledge as part of the interview, not Code golf.
What signature?
// arr is not changed, use `const`
// array indexing best done with `size_t`
int* multTwo(const int* arr, size_t len) {
Size needed and show error handling. Maybe also detect arr == NULL when len > 0
need = len;
// if lead element is 5 or more, add 1.
// Error if element is not in 0-9 range
Allocate memory. Allocating to size of variable de-referenced type is less error prone, easier to review and maintain than coding the variable type. Showing maintenance concerns during a C interview is a good thing. Think if later code changed to unsigned char* multTwo(const unsigned char* arr, size_t len) {, no need to change newarr = malloc(sizeof *newarr * need).
newarr = malloc(sizeof *newarr * need)
Check allocation. An allocation of 0 is OK to return NULL. Yet maybe this routine should still allocate 1 byte, a tad wasteful, to insure a NULL return is an error. Discussing issues like with the interviewer is good. Shows you want to clearly understand the customer's need not just in the meat of the function, but the corner cases.
if (newarr == NULL && need > 0) fail()
Loop though and populate the new array much like OP coded with meaningful variable names and using unsigned array indexing.
size_t arr_i=len;
size_t newarr_i=need;
int carry = 0;
while (arr_i > 0)
sum = arr[--arr_i]*2 + carry;
newarr[--newarr_i] = sum%10;
carry = sum/10;
}
if (carry) {
newarr[--newarr_i] = carry;
}
Return newarr
Best I can think in a short time, like an interview
#include <stdio.h>
#include <stdlib.h>
void invert (int *head, int *tail)
{
int temp;
if (head < tail)
{
temp = *head;
*head = *tail;
*tail = temp;
invert(++head, --tail);
}
}
int* multTwo(int* arr, size_t len)
{
int value = 0;
int n_digits =0 ;
// CONVERT THE ARRAY TO NUMBER
while(len--)
{
value += *arr;
value *=10;
arr++;
}
value /= 10;
// DOUBLE THE NUMBER
value *= 2;
// CONVERT IT TO BUFFER
int *digits = malloc(sizeof(*digits));
while ((value>0) && (digits != NULL))
{
digits[n_digits++] = value%10;
value /= 10;
digits = realloc( digits, sizeof(*digits) * (n_digits+1) );
}
if (digits != NULL)
{
invert(digits, &digits[n_digits-1]);
printf("[ ");
for (int i=0; i<n_digits; i++)
printf("%d, ", digits[i]);
printf("]\n");
}
return digits;
}
int main(void)
{
int array[] = {6,7,5};
multTwo(array, sizeof(array)/sizeof(array[0]));
return 0;
}
I would start by looking to see if either the first digit in arr is 5 or more to check if the newarr array needs to be 1 larger than the original array.
So something like this for initialization:
int* newarr;
int newlen;
if (*arr >= 5)
newlen = len + 1;
else
newlen = len;
newarr = (int*)malloc(sizeof(int) * newlen);
memset(newarr, 0, newlen); //initialize all newarr values to 0
Now obviously we have to do our multiplication now. To get the 1's digit we do use the modulo operator %, and to get the 10's digit we use the division operator /. Of course we only need to do the division if our multiplied value is 10 or greater. So our loop to populate newarr will look something like this:
int i, temp;
for (i = 1; i <= len; i++) {
temp = *(arr + i - 1) * 2;
if (temp < 10) {
*(newarr + i - 1) += temp;
}
else {
*(newarr + i - 1) += temp / 10; //inset 10's digit
*(newarr + i) += temp % 10; //inset 1's digit
}
}
So our full function ends up being
#include <stdlib.h>
#include <string.h>
int* multTwo(int* arr, int len)
{
int* newarr;
int newlen;
if (*arr >= 5)
newlen = len + 1;
else
newlen = len;
newarr = (int*)malloc(sizeof(int) * newlen);
memset(newarr, 0, newlen); //initialize all newarr values to 0
int i, temp;
for (i = 1; i <= len; i++) {
temp = *(arr + i - 1) * 2;
if (temp < 10) {
*(newarr + i - 1) += temp;
}
else {
*(newarr + i - 1) += temp / 10; //insert 10's digit
*(newarr + i) += temp % 10; //inset 1's digit
}
}
return newarr; //don't forget to free once you're done with newarr!
}

C program - How to check array elements [duplicate]

This question already has answers here:
C sizeof a passed array [duplicate]
(7 answers)
Closed 6 years ago.
I have a function repsEqual that takes an array and integer and returns 1 if the array contains only digits of the number in the same order that appear in the same number. Otherwise it returns 0.
int repsEqual(int a[], int len, int n)
If a is {3,2,0,5,3} and n is 32053 return 1 because the array contains only the digits of the number in same order as they are in the number.
If a is {0,3,2,0,5,3} and n is 32053 return 1; we can ignore leading zeros.
I tried like this
int repsEqual(int a[], int len, int n)
{
int len = sizeof(a)/sizeof(a[0]);
//storing elements in array
for(int i=0;i<len;i++)
{
scanf("%d", &a[i]); //eg storing:3 2 0 5 3
}
//asking user integer number and storing in next array
scanf("%d",&a2[num]);//eg 32053
}
Now I need to check if a2 elements are in same order as a1, but do not know how to get started.
This is what you want
int repsEqual(int a[], int len, int n)
{
for (int i = 0; i < len; i++)
{
if (a[len - i - 1] == n % 10)
n /= 10;
else
return 0;
}
//For cases where your number-length is longer than your array length
if (n != 0) return 0;
return 1;
}
First you have your array, say like a[5] = { 5, 2, 3, 1, 4}
Basically what i do is looping the array from end to start, thats a[len - i - 1]
Then i check it with the last character of n thats n%10
So example with n = 52314, the first if statement check if (52314 % 10) which is 4 equal with a[4] which is also 4
if the 2 character match then the loop continue first by remove the last character of n: 52314 / 10 = 5231.
And the next loop will check for 5231 % 10 and a[3]
else the loop break mid-way and return 0 indicate that a mis-match is found
finally after all the character in array is checked and no mismatch is found, it will return 1, as the pattern match
Note: a function should only does what its name says
In your case, check if an array and an integer have the same pattern
User input should be put outside somewhere else, after you have the inputs (the array, the len, and n) you then pass-in to repsEqual for checking
Try matching the number (n) backwards against the array 'a'. To do this you'll want to modulus the smallest digit from 'n', by getting the remainder from dividing by 10. Then remove the smallest digit from 'n' by dividing by 10.
int repsEqual(int a[], int len, int n)
{
int i;
int temp;
if (0 == len || NULL == a)
return 0; // no array, or elements, doesn't match a real number (n).
temp = n;
for (i = len - 1; i >= 0; --i)
{
if (a[i] != (temp % 10))
return 0; // remainder mismatch against array element.
temp = temp / 10; // removes the smallest digit.
}
return 1;
}
By modulus 10 on your n you get the remainder of dividing by 10. IE 452 % 10 = 2. Then by dividing be ten we remove the smallest digit IE 452 / 10 = 45.
This seems to be some homework, haha. Anyway I gave u a quick/ugly sample to start with.
#include <stdio.h>
int repsEqual(int a[],int len , int n)
{
char str[100];
sprintf(str, "%d", n);
int i;
int nonzeroIndex;
for(i=0; i<len; i++){
if (a[i] != 0)
break;
}
nonzeroIndex = i;
printf("nonzeroIndex is %d\n", nonzeroIndex);
for(i= nonzeroIndex; i <len; i++){
if (a[i] != str[i - nonzeroIndex] - 48) {
printf("diff at %d\n", i);
return 0;
}
}
return 1;
}
int main()
{
int a[5];
a[0] = 0;
a[1] = 2;
a[2] = 0;
a[3] = 5;
a[4] = 3;
int output = repsEqual(a, 5, 2053);
printf("result: %d\n", output);
}

Resources