Recently I was reading a Programming book and found this question:
I have an array :
array = [2,3,6,7,8,9,33,22];
Now, Suppose I have deleted the element at 4th position i.e. 8 .
Now I have to rearrange the array as:
Newarray = [2,3,6,7,9,33,22];
How Can I do this. And I have to also minimize the complexity.
Edit I have no choice to make another copy of it.I have to only modify it.
You can "remove" a value from an array by simply copy over the element by the next elements, that's easy to do with memmove:
int array[8] = {2,3,6,7,8,9,33,22};
memmove(&array[4], &array[5], sizeof(int) * 3);
The resulting array will be {2,3,6,7,9,33,22,22}.
And from that you can see the big problem with attempting to "remove" an element from a compile-time array: You can't!
You can overwrite the element, but the size of the array is fixed at time of compilation and can't actually be changed at run-time.
One common solution is to keep track of the actual number of valid elements in the array manually, and make sure you update that size as you add or remove elements. Either that or set unused elements to a value that's not going to be used otherwise (for example if your array can only contain positive numbers, then you could set unused elements to -1 and check for that).
If you don't want to use a library function (why not?) then loop and set e.g.
array[4] = array[5];
array[5] = array[6];
and so on.
Do this, just use these two functions and it will work fine
index=4;//You wanted to delete it from the array.
memcpy(newarray,array,sizeof(array));
memmove(&newarray[index], &newarray[index + 1], sizeof(newarray)-1);
now the newarray contains your exact replica without the character that you wished to remove
You can simply displace each element from the delIdx(deletion index) one step forward.
for(int i=delIdx; i<(arr_size-1);i++)
{
arr[i]= arr[i+1];
}
If required you can either set the last element to a non-attainable value or decrease the size of the array.
Related
I have created a static array in c
int array[15];
For example, I "filled in" the first 5 elements of my array.
This means that I still have 10 free elements, right?
What should I do to know that I have already "used" five elements of my array?
How would I know the number of elements that I have used?
What should I do to know that I have already "used" five elements of my array? How would I know the number of elements that I have used?
There are couple of options.
Use a sentinel value that indicates the elements that have been filled up.
Let's say you use 99999 for the sentinel value. If the n-th element of the array has the value 99999, you know that you have filled up n-1 elements.
Use another variable to keep track of that.
size_t numFilledElements = 0;
for ( ... )
{
// Fill up an element
// Increment the counter.
++numFilledElements;
}
My personal preference would be to use the second approach. Then, you won't have to worry about a sentinel value.
Im beginner in programming. My question is how to count number sequences in input array? For example:
input array = [0,0,1,1,1,1,1,1,0,1,0,1,1,1]
output integer = 3 (count one-sequences)
And how to calculate number sequences first and last indexes in input array? For example:
input array = [0,0,1,1,1,1,1,1,0,1,0,1,1,1]
output array = [3-8,10-10,12-14] (one first and last place in a sequence)
I tried to solve this problem in C with arrays. Thank you!
Your task is a good exercise to familiarize you with the 0-based array indexes used in C, iterating arrays, and adjusting the array indexes to 1-based when the output requires.
Taking the first two together, 0-based arrays in C, and iterating over the elements, you must first determine how many elements are in your array. This is something that gives new C programmers trouble. The reason being is for general arrays (as opposed to null-terminated strings), you must either know the number of elements in the array, or determine the number of elements within the scope where the array was declared.
What does that mean? It means, the only time you can use the sizeof operator to determine the size of an array is inside the same scope (i.e. inside the same block of code {...} where the array is declared. If the array is passed to a function, the parameter passing the array is converted (you may see it referred to as decays) to a pointer. When that occurs, the sizeof operator simply returns the size of a pointer (generally 8-bytes on x86_64 and 4-bytes on x86), not the size of the array.
So now you know the first part of your task. (1) declare the array; and (2) save the size of the array to use in iterating over the elements. The first you can do with int array[] = {0,0,1,1,1,1,1,1,0,1,0,1,1,1}; and the second with sizeof array;
Your next job is to iterate over each element in the array and test whether it is '0' or '1' and respond appropriately. To iterate over each element in the array (as opposed to a string), you will typically use a for loop coupled with an index variable ( 'i' below) that will allow you to access each element of the array. You may have something similar to:
size_t i = 0;
...
for (i = 0; i< sizeof array; i++) {
... /* elements accessed as array[i] */
}
(note: you are free to use int as the type for 'i' as well, but for your choice of type, you generally want to ask can 'i' ever be negative here? If not, a choice of a type that handles only positive number will help the compiler warn if you are misusing the variable later in your code)
To build the complete logic you will need to test for all changes from '0' to '1' you may have to use nested if ... else ... statements. (You may have to check if you are dealing with array[0] specifically as part of your test logic) You have 2 tasks here. (1) determine if the last element was '0' and the current element '1', then update your sequence_count++; and (2) test if the current element is '1', then store the adjusted index in a second array and update the count or index for the second array so you can keep track of where to store the next adjusted index value. I will let you work on the test logic and will help if you get stuck.
Finally, you need only print out your final sequence_count and then iterate over your second array (where you stored the adjusted index values for each time array was '1'.
This will get you started. Edit your question and add your current code when you get stuck and people can help further.
Suppose we have an expanding array that doubles in size when we try to add something to it but it is filled.
According to the bottom of the slide "Amortization: Expanding Vectors" the worst-case time for adding one element is 2N, not N? Why is this?
I thought it would be N because copying N elements to the new, double sized array, would take N time.
For example, say I'm adding just one element to a filled array of size 4. It would go like this:
Make new array of size 8 (double of 4).
Copy all of elements of original array to new array (copy 4 times).
Set 5th element of the new array to the additional element (copy 1 time).
So that would copy elements 5 times, which is N + 1, not 2N?
The operations needed for adding an element to an exanding array is O(2N) because first you need to go through the whole array and check for empty space with O(N). Because this is the worst case there isn't any and you have to create a new array and copy the whole content from the first to the new array with O(N). Both operations combined result in O(2N).
When you think of array length the length is actually the size that is reserved for the array and not the number of elements inside. That is why you need to loop through the whole array for an empty space if you did not save the number of elements anywhere. I am speaking of 'empty space' because it is not stated that just elements were added and none were deleted inside the array.
Concatenating an element x to an array items is easy in D, it's as if it were an array list:
arr ~= x;
but how do I remove an element at index i from items?
(Caveat: If I remove an element and then add a new element, the array must not be reallocated. So a simple slice won't work.)
Update:
Based on CyberShadow's answer about using assumeSafeAppend, I wrote this code:
static void removeAt(T)(ref T[] arr, size_t index)
{
foreach (i, ref item; arr[index .. $ - 1])
item = arr[i + 1];
arr = arr[0 .. $ - 1];
arr.assumeSafeAppend();
}
However, the problem happens when you have something like:
auto superArr = [0, 1, 2, 3, 4]; //Must not be modified
auto arr = superArr[0 .. $ - 1];
writeln(superArr);
arr.removeAt(0); //Should copy the slice and modify the copy
writeln(superArr); //but obviously doesn't
The base array of slice should not be modified if an element is removed from the slice; instead, the slice needs to be copied.
But I have no way of knowing if an array is a slice of a bigger array... so that doesn't work.
Any suggestions?
Copying my answer on digitalmars.D (thanks for forwarding):
As has been mentioned, std.algorithm.remove can be of help. You may want to look at three of its capabilities in particular: (a) remove multiple offsets in one pass, e.g. remove(a, 0, 4) removes the first and fifth element, (b) you can remove subranges, e.g. remove(a, tuple(1, 3)) removes the second through fourth element, and (c) if you don't care about the order in which elements are left after removal you may want to look into unstable remove, which does considerably less work.
Andrei
(Caveat: If I remove an element and then add a new element, the array must not be reallocated. So a simple slice won't work.)
The assumeSafeAppend function will tell the runtime not to reallocate the array when appending to it (i.e. it is an affirmation from the user that there aren't other slices which might be stomped by an append).
remove from std.algorithm does an in-place remove. If you're using std.container, there's also Array.linearRemove.
Well if order is of no importance you can copy the last element to the location of removal then reduce the array length by one.
If you just want to remove the first or last elements use slices:
array = array [1..$]
array = array [0..$-1]
Or a general way which works for a middle one as well:
array = array [0..unlucky] ~ array [unlucky+1..$]
If the elements aren't basic elements such as structs, floats, ints then arrays are implicitly arrays of pointers and this is an efficient operation.
There's no automated way of doing this, you'll have to shuffle the array items along, reset .length and then catenate.
so far, i m working on the array with 0th location but m in need to change it from 0 to 1 such that if earlier it started for 0 to n-1 then now it should start form 1 to n. is there any way out to resolve this problem?
C arrays are zero-based and always will be. I strongly suggest sticking with that convention. If you really need to treat the first element as having index 1 instead of 0, you can wrap accesses to that array in a function that does the translation for you.
Why do you need to do this? What problem are you trying to solve?
Array indexing starts at zero in C; you cannot change that.
If you've specific requirements/design scenarios that makes sense to start indexes at one, declare the array to be of length n + 1, and just don't use the zeroth position.
Subtract 1 from the index every time you access the array to achieve "fake 1-based" indexing.
If you want to change the numbering while the program is running, you're asking for something more than just a regular array. If things only ever shift by one position, then allocate (n+1) slots and use a pointer into the array.
enum { array_size = 1000 };
int padded_array[ array_size + 1 ];
int *shiftable_array = padded_array; /* define pointer */
shiftable_array[3] = 5; /* pointer can be used as array */
some_function( shiftable_array );
/* now we want to renumber so element 1 is the new element 0 */
++ shiftable_array; /* accomplished by altering the pointer */
some_function( shiftable_array ); /* function uses new numbering */
If the shift-by-one operation is repeated indefinitely, you might need to implement a circular buffer.
You can't.
Well in fact you can, but you have to tweak a bit. Define an array, and then use a pointer to before the first element. Then you can use indexes 1 to n from this pointer.
int array[12];
int *array_starts_at_one = &array[-1]; // Don't use index 0 on this one
array_starts_at_one[1] = 1;
array_starts_at_one[12] = 12;
But I would advise against doing this.
Some more arguments why arrays are zero based can be found here. Infact its one of the very important and good features of the C programming language. However you can implement a array and start indexing from 1, but that will really take a lot of effort to keep track off.
Say you declare a integer array
int a[10];
for(i=1;i<10;i++)
a[i]=i*i;
You need to access all arrays with the index 1. Ofcourse you need to declare with the size (REQUIRED_SIZE_NORMALLY+1).
You should also note here that you can still access the a[0] element but you have to ignore it from your head and your code to achieve what you want to.
Another problem would be for the person reading your code. He would go nuts trying to figure out why did the numbering start from 1 and was the 0th index used for some hidden purpose which unfortunately he is unaware of.