I am here to get some advice on how to continue my program. It is a homework assignment and the idea is to have another method called int is_sorted(int array[], int length);
With these pre and post conditions.
Precondition: array will be an array of integers of length length.
Postcondition: returns true if the array is in sorted(nondecreasing) order, or false otherwise.
So far I have been able to put together the user input array and how long it should be.
#include <stdio.h>
#include <math.h>
int is_sorted(int array[], int lenght);
int is_sorted(int array[], int lenght)
{
int swap;
int smallest;
int index = 0;
scanf("%d", &lenght);
int list[lenght];
int i;
for (i = 0; i < lenght; i++)
{
scanf("%d", &list[i]);
}
return 0;
}
int main()
{
}
How would I go about asking for a user input to swap two elements at a time within the given array?
The final product should look similar to this:
Sample Run: User input in bold
4 <- The length that the array should be.
1 1 1 2 <- user input these 4 numbers.
WHAT IS THE NEXT SWAP? 2 3
EVAN HAS UNSORTED THE ARRAY.
WHAT IS THE NEXT SWAP? 2 0
WHAT IS THE NEXT SWAP? 0 3
EVAN HAS SORTED THE ARRAY.
WHAT IS THE NEXT SWAP? -1 -1
STEVE WAS RIGHT!
-1 -1 end the swapping process and check if the array is sorted.
while(i != -1 && j != -1){
scanf("%d %d", &i, &j);
swap(&array[i], &array[j]);
}
and swap() looks like this:
void swap(int* a, int* b){
int c = *a;
*a = *b;
*b = c;
}
There's probably a nifty trick for swaping two variables doing some bitwise xor-ing that I don't remember about.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
void function(int first[], int second[], int third[]) {
int i;
for(i=0;i<64;i++) {
third[i] = first[i] - second[i];
}
}
I want to subtract the second array from the first one. The first one contains 32 numbers and the second one has 13 numbers. It works fine for the first 13 numbers. Once the second array "runs out" of elements, I want to use the numbers from the beginning of the second array. So I want to subtract the second array's first element from the 14th element of the first one, and so on... How could I achieve it?
you can use % to get the remainder of the index from length of the array, this way, you can iterate through the second array in a circular way!
I changed your code to do as you asked for
// get the length of array before you pass it to the function like this:
// int second_len = sizeof(second) / sizeof(second[0]);
void function(int first[], int second[], int third[], int second_len) {
int i;
for(i=0;i<64;i++) {
third[i] = first[i] - second[i % second_len];
}
}
The elements of the first and second array are sequences of positive
numbers and they are both closed with -1
You could just do as below.
Maintain two indexes i and j.
Where i will index larger array and j will index smaller array and once smaller array reaches -1 reset the j to 0 and once larger array reaches -1 break the loop.
void function(int first[], int second[], int third[]) {
int i =0,j=0;
for(i=0; i<64 ; i++;j++) {
if(second[j] == -1)
{
j =0; //Reset the j=0 to start from beginning
}
if (first[i] == -1)
{
third[i] = -1; //Terminate third with -1
break; //Break the loop
}
third[i] = first[i] - second[j];
}
}
One option is to add an additional looping variable:
void function(int first[], int second[], int third[],
int first_size, int second_size)
{
int i=0, k=0;
for(i=0; i<first_size; i++) {
third[i] = first[i] - second[k];
k++;
if (k==second_size)
k = 0;
}
}
i tracks the size of the first array and the output like in your program, and k follows the size of the second array and resets whenever the size is reached. Instead of hardcoded array sizes the function now takes two additional arguments: sizes of the first and second arrays.
For future reference, the rest of this code could look like this:
#include <stdio.h>
void print_array(int arr[], int);
void function(int arr_1[], int arr_2[], int arr_3[], int, int);
int main()
{
int arr_1[] = {1,2,3,4,5};
int arr_2[] = {1,2};
int n_1 = sizeof(arr_1)/sizeof(arr_1[0]);
int n_2 = sizeof(arr_2)/sizeof(arr_2[0]);
int arr_out[n_1];
function(arr_1, arr_2, arr_out, n_1, n_2);
print_array(arr_1, n_1);
print_array(arr_2, n_2);
print_array(arr_out, n_1);
return 0;
}
void print_array(int arr[], int n_elem)
{
int i = 0;
for (i=0; i<n_elem; i++)
printf("%d ", arr[i]);
printf("\n");
}
With print_array as a function to avoid repeating the same lines of code for each print.
For the example input, the output will be 0 0 2 2 4.
I don't know how to clean an array from the elements which indexes stored in the other array. I need to complete the following C-program consisting of main(…) and function
void clear_MSBs( unsigned char dest_array[], unsigned char array_indices []).
Beginning of code:
#define N 8
#define M 5
int main()
{
unsigned char dest_array[N] = {248,249,250,251,252,253,254,255};
unsigned char array_indices[M] = {0,2,3,6,7}; // contains M=5 elements
clear_MSBs(dest_array, array_indices);
// print the modified dest_array[] here
return 0;
}
Note: It is guaranteed that all indices stored in the second array are within the
allowed range.
I would really appreciate your help.
If by cleaning, you mean marking the element as invalid (which is probably what you want), then you could just loop over the indices array, and use the i-th element of the indices array as the index for the destination array.
Example:
#include <stdio.h>
#define N 8
#define M 5
void clear_MSBs(unsigned char dest_array[], unsigned char array_indices [])
{
for(int i = 0; i < M; ++i)
dest_array[array_indices[i]] = 0;
}
int main()
{
unsigned char dest_array[N] = {248,249,250,251,252,253,254,255};
unsigned char array_indices[M] = {0,2,3,6,7}; // contains M=5 elements
clear_MSBs(dest_array, array_indices);
// print the modified dest_array[] here
for(int i = 0; i < N; ++i)
if(dest_array[i] != 0)
printf("%d ", dest_array[i]);
printf("\n");
return 0;
}
Output:
249 252 253
PS: The code assumes that an invalid element has the 0 value.
You just need to overwrite what you're deleting with the next value in the array, propagate that change, and then keep in mind where the new end is.
In C++, though, it would be better to use a std::vector:
std::vector<int> array; // initialize array... // delete element at index 2
array.erase(array.begin() + 2);
I'm trying to use the qsort() function in order to sort only the even numbers of an array (the odds remains in their positions).
For instance if I have the array:
5 122 3 26 48
After sorting one would get:
5 26 3 48 122
My intuition was only to make a sort when both numbers pointed by a and b are even.
This is my attempt:
#include <stdio.h>
#include <stdlib.h>
int comp_even(const void *a, const void *b) {
int l = *(int *)a;
int r = *(int *)b;
if ( !(l&1) && !(r&1) ) //if both are even, then sort them in ascending order
return (l-r);
return 0;
}
int main() {
int i, n;
int a[1001];
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
qsort(a, n, sizeof(int), comp_even);
for (i = 0; i < n; i++) {
printf("%d ", a[i]);
}
return 0;
}
Unfortunately, qsort doesn't support anything like that; for any two elements, the comparison function must return one of three results:
a negative integer, meaning that its first argument should end up before its second;
a positive integer, meaning that its first argument should end up after its second;
zero, meaning that either ordering is fine (in which case qsort makes no guarantees about which element ends up before the other).
And, crucially, the function must do this using only the values of its two arguments; it doesn't know the array-indices that they came from.
Instead, you can take one of two approaches:
copy all of the even elements into an array, sort that array using a straightforward comparison function, and then copy the elements of that array back over the even elements in the original array.
create an int[][2] that stores not just the values in the array, but also their original indices. You can then sort the elements such that if either value is odd, then the element with the lesser original index comes first.
It seems impossible to design a comparison function for your purpose, but you can make a copy of the even numbers, sort that with qsort and dispatch the sorted subset over the even numbers of the original array:
#include <stdio.h>
#include <stdlib.h>
int comp_int(const void *a, const void *b) {
const int *ap = a;
const int *bp = b;
return (*ap > *bp) - (*ap < *bp);
}
int main(void) {
int i, j, n, n_even;
int a[1001];
int even[1001];
if (scanf("%d", &n) != 1 || n <= 0 || n > 1001)
return 1;
n_even = 0;
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
if ((a[i] & 1) == 0) {
even[n_even++] = a[i];
}
}
qsort(even, n_even, sizeof(int), comp_int);
for (i = j = 0; i < n; i++) {
if ((a[i] & 1) == 0) {
a[i] = even[j++];
}
for (i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
Note also that your original comparison function uses a trick to compare integers that fails for large values. The difference of 2 integers may be outside the range of int. So returning l - r may be incorrect for many values of l and r.
For example l=INT_MIN and r=1 will return INT_MIN-1, the subtraction causes an arithmetic overflow, which invokes undefined behavior and in current 2s complement architectures evaluates to INT_MAX, a positive value although INT_MIN < 1.
I have started an introductory class to C. I cannot explain the output that I get from running the code below
./a.out 6
Output is:
Array A elements: 0 1 2 3 4 5
Array B elements: 1 2 3 4 5 796830176
What I think the code is doing:
When manup_array is executed, each value of the respective pointers will be incremented, but since it is post-fix, this takes effect only later on after the original value is returned.
True enough, when we print array A first, we get 0 1 2 3 4 5 (i.e. before incrementation).
Subsequently when we print array B, the incrementation takes effect, so we get 1 2 3 [...]
What really puzzles me is why the last number is 796830176. Also, running this on various computers produces a different last number every time, suggesting that the pointer addressing is somehow responsible for this.
Could someone explain this to me?
Note:
The outputs of each array are identical (1 2 3 4 5 6) if I use the pre-fix operator. This is consistent with what I think is going on -> the pointers don't change; only the values get updated.
#include <stdio.h>
#include <stdlib.h>
void manup_array(int *array[], int n); // Forward declaration.
int main(int argc, char *argv[])
{
// The size N of 2 arrays are the same; obtain them from cmd line.
int N = atoi(argv[1]); // Convert from str to int in C.
int arrayA[N]; // Declare integer array.
int *arrayB[N]; // Declare integer pointer array.
for (int i = 0; i < N; i++)
{
arrayA[i] = i;
arrayB[i] = &arrayA[i]; // Assign address of each element in A to element in B.
}
manup_array(arrayB, N);
printf("Array A elements: ");
for (int i = 0; i < N; i++)
{
printf("%d ", arrayA[i]);
}
printf("\n");
printf("Array B elements: ");
for (int i = 0; i < N; i++)
{
printf("%d ", *arrayB[i]);
}
printf("\n");
return 0;
}
void manup_array(int *array[], int n) { // Take in B as input, then increase each elem by 1
for (int i = 0; i < n; i++)
{
*array[i]++;
}
}
This is really obscure code. What is does:
The function takes an array of pointers as parameter. Since the parameter to the function had type int *array[], any change of the items of array will affect the caller and alter arrayB.
The interesting part of the function is *array[i]++;. The operator precedence rules in C state that [] has higher prio than postfix ++, which has higher prio than unary *.
Since array is an array of pointers, array[i] gives you a pointer. Not a the value it points at. Then ++ increments the pointer to point at the next item in the arrayA of main.
And then finally there is a * which takes the contents of what that pointer pointed at, and then does nothing with them. The * is superfluous and just there to confuse the reader.
So back in main, you have changed all the pointers of arrayB. arrayB[0] now points at arrayA[1] and so on. The last item of arrayB will point one item past the end of arrayA, so for the last item, you access the array out-of-bounds and get a garbage value.
void manup_array(int *arr[], int n) { // Take in B as input, then increase each elem by 1
for (int i = 0; i < n; i++)
{
int val = (*arr[0]); // get the value pointed to by the current value of arr
val++; // increment it
*(arr[0]) = val; // assign it back
arr++; // increase the pointer
}
}
Incredibly obtuse, but it demonstrates what you mean to do and how your obscure code muddled up the operators.
To add, makes debugging way easier!
manup_array() increments the pointer, not the value as expected.
Modified manup_array().
void manup_array(int *array[], int n) { // Take in B as input, then increase each elem by 1
for (int i = 0; i < n; i++)
{
//*array[i]++;
(*array[i])++;
}
}
I suggest to refer Pointer Arithmetic: ++*ptr or *ptr++?
i tried the brute force way:
#include <stdio.h>
int sum(int a [],int b[], int m);
int main (void)
{
int a [] = {1,2,3,4,5};
int b [] = {4,3,5,2,6};
int i;
printf("Enter to find a given number:\n");
scanf("%d",&i);
printf("%s\n",sum(a,b,i) ? "True":"False");
return 0;
}
int sum(int a[], int b[],int m)
{
int i=0,j=0;
for (i=0;i<=sizeof(a)/sizeof(int)+1;i++)
for(j=0;j<=sizeof(b)/sizeof(int)+1;j++)
if (a[i]+b[j]==m)
return 1;
return 0;
}
as you can see the run time is O(n^2), are there any clever way to minimise this?
The faster possible solution (O(n)) is to use hash table. Just put all the elements from the first array in it and then while iterating over the second one check if the difference between the target number and the current one is in the hash table.
Here is implementation in C++:
int main(){
int a [5] = {1,2,3,4,5};
int b [5] = {4,3,5,2,6};
int m;
printf("Enter to find a given number:\n");
scanf("%d",&m);
set<int> s;
for (int i = 0; i < 5; i++)
s.insert(a[i]);
for (int i = 0; i < 5; i++)
if (s.count(m-b[i]) > 0) {
printf("True\n");
return 0;
}
printf("False\n");
}
This is just another formulation of "Find all pairs of elements (a1,b1) such that a1 belongs to Array A and b1 belongs to Array B whose sum a1+b1 = k".
In short, use a hash table.
No need for an hash table!!
You could sort the arrays (one increasing the other one decreasing) and then compare the first elements of the arrays. At each step then move on the first array increasing and on the second decreasing (if the sum is too large you should move on the decreasing array, if the sum too small you have to move on the increasing array)
This algorithm is 2N log(N) + 2 N
You can precompute the "sums" array, put it in size order, and then bsearch(3) the array:
int sums = { /* list of sorted sums */ };
int compare(void *a, void *b) { return ((int *)a - (int *)b); }
if (bsearch((void *)int_to_test, (void *)sums, number_of_items_in_sums, sizeof(int), compare) == NULL)
errx(1, "not in list!");
printf("found it\n!");
The bsearch syntax is from memory, so double-check that in your man pages.