Vectors and dynamic arrays in D - arrays

I was thinking that dynamic arrays were a replacement for vectors in D, but it seems they have no remove function (only associative arrays do) which is rather a limitation for a vector so I'm wondering if I've got that right. If a have an array like follows,
uint[] a;
a.length = 3;
a[0] = 1;
a[1] = 2;
a[2] = 3;
Then the only way I've found to remove, say, the second element is,
a = a[0..1] ~ a[2];
But that doesn't seem right (but maybe only because I don't understand this all yet). So is there a vector and is there another way of removing an element from a dynamic array?
Thanks.

You could use std.algorithm.remove(), which works not only with arrays but with generic ranges. Example:
import std.algorithm;
void main() {
uint[] a = [1, 2, 3];
a = a.remove(1);
assert(a == [1, 3]);
}

In std.container there is an Array!T template, which appears to be much like std::vector from C++.
Array!int a = [0, 1, 2, 3];
a.linearRemove(a[1..3]);
assert(equal(a, [0, 3]));
Unfortunately it does not appear to have an individual remove method, although you could always use linearRemove with a singleton range.

Related

determine if array contains specific integer in octave

I have an array which looks like
test = {1,2,3};
I want to determine if an integer belongs in the array. I tried using ismember() and any() but they both return this:
binary operator '==' not implemented for 'cell' by 'scalar' operations
How will I do this? Thanks in advance
If you want to check if an integer exists in a matrix:
test = [1, 2, 3];
any (test == 2)
ans = 1
But in your question you use a cell array. In this case I would first convert it to a matrix, then do the same:
b = {1,2,3};
any (cell2mat (b) == 2)
ans = 1
You're asking about checking if an array has a given integer but you're using a cell. They're quite different.
If you want to stick to cells you can iterate over it like so
test = {1, 2, 3};
number = 2;
hasNumber = false;
for i = 1:size(test,2)
if(test{i} == number)
hasNumber = true;
break;
end
end
For arrays, on the other hand, you could do just this, for example
test = [1, 2, 3];
number = 2;
hasNumber = ~isempty(test(test == number));

Fastest way to list diagonal elements of a 2D array from a given point

In a 2D array, for a given point what is the fastest way to get the diagonal elements in Scala? I understand that I can simply use a for loop to walk through the elements from a given point, but it feels very java-like. One of the ways I have come up with is to use a recursive function which accepts a function as an argument that calculates the next cell. However I feel such a method is very inefficient. What is the most idiomatic way in Scala to walk through a diagonal?
Fast functional code in Scala generally involves tail-recursive functions, and fast array access generally involves indexing. So your options are limited.
In this case,
def diag(xss: Array[Array[Double]]): Array[Double] = {
val ans = new Array[Double](xss.length)
#annotation.tailrec def inner(i: Int) {
if (i < xss.length) {
ans(i) = xss(i)(i)
inner(i+1)
}
}
inner(0)
ans
}
Personally, I find this less clear than the corresponding while loop
def diag(xss: Array[Array[Double]]): Array[Double] = {
val ans = new Array[Double](xss.length)
var i = 0
while (i < xss.length) {
ans(i) = xss(i)(i)
i += 1
}
ans
}
but your preferences may vary.
There are optimization frameworks that will take higher-order index traversal (e.g. for (i <- xss.indices) ans(i) = xss(i)(i)) and change it into the while loop. (ScalaBlitz is one.)
You can also use Tail recursion and Immutable data-structures like List as functional programming and immutability just go along very well. it offers two operations head and tail which takes constant time and Time-complexity of both operation is O(1).
#annotation.tailrec
def f(arr: List[List[Int]], res: List[Int] = Nil): List[Int] = {
if (arr.isEmpty) res
else
f(arr.tail.map(_.tail), res :+ arr.head.head)
}
val x = List(List(1, 2, 3, 4), List(5, 6, 7, 8), List(9, 10, 11, 12), List(13, 14, 15, 16))
scala> f(x)
res0: List[Int] = List(1, 6, 11, 16)
Just for fun, some (arguably) more colloquial Scala, noticing that diagonal elements are issued from a rotation of lines, you may use code as follows. It'll be less efficient than a for loop though.
def diag(m: Array[Array[Int]]) = {
val (m1, m2) = m.zipWithIndex.
map{case (l, i) => val (l1, l2) = splitAt(l.size-i); l1 ++ l2}.
transpose.zipWithIndex.
map{case (l, i) => l.splitAt(i+1)}.
unzip
m1 ++ m2.init
}

Copying array while excluding element(s)

Is there a standard way to copy an array excluding elements equal to an object? My current naive solution:
T[] without(T)(T[] array, T what){
T[] a;
foreach(element; array)
if(element != what)
a ~= element;
return a;
}
Removing elements from an array seems unnecessarily difficult in D and the immutable approach seems pretty nice, so I'd like to create a new one instead of modifying the existing array.
std.array.replace would work well, but it does not accept [] as second argument.
It sounds like you want std.algorithm's filter.
For example:
import std.algorithm, std.array;
void main() {
auto a = [1, 2, 3, 3, 4];
auto without3 = a.filter!(x => x != 3).array;
assert(without3 == [1, 2, 4]);
}
note that filter returns a FilterResult (a type of range), not an array. The call .array at the end (from std.array) converts the FilterResult into an array.
You should call .array if you want to create and store a separate 'copy'. If you just want to iterate over the FilterResult, you can use foreach like you would with any range.

creating 2 dimensional array of unspecified (varying) size

Newbie question: I want to dynamically create an integer 2D array M[i,j], whose sizes (in both dimensions) are unknown beforehand. Moreover, for each index i, the size of the i-th row may vary.
Question 1: How do I declare such an array (do I even have to)? I have tried Array[], Array(Int64,1...), and Array((Int,Int),0)as in this hint and others.
Question 2: once created, how to I populate the array in a smart and concise way? Say my i-th row is suppose to be equal to a given 1-dimensional B, I would like to write
A[i] = B
or
A[i,:] = B
or even
A[i,1:n] = B
where n is the size of B. All of these give me a BoundsError(). Slicemight do the trick, but I cannot make it agree with my declaration.
You don't want a 2D array here, because in a 2D array all rows are of the same size. Instead, you want a vector-of-vectors. For example:
A = Array(Vector{Int}, 5)
A[1] = rand(1:10, 3)
A[2] = rand(1:100, 22)
If you inspect A, you'll see something like this:
julia> A
5-element Array{Array{Int64,1},1}:
[5,7,7]
[1,63,40,86,61,39,98,5,68,97 … 78,49,44,89,48,63,90,90,86,83]
#undef
#undef
#undef
Another great tool is to use a comprehension:
julia> A = Vector{Int}[ [1:m] for m = 1:5]
5-element Array{Array{Int64,1},1}:
[1]
[1,2]
[1,2,3]
[1,2,3,4]
[1,2,3,4,5]
The main thing you'll want to be careful about is that each element of A is a reference to a vector; if you assign
A[1] = b
A[2] = b
then any change to b will affect both A[1] and A[2]. If you don't want that, use
A[1] = copy(b)
A[2] = copy(b)

Calculating indexes in a filtered array

Suppose I have an array A = {a,b,c,d,e,f,g} and a set of (zero-based) indexes I={1,3,5} in A. Now suppose that I actually don't have A, but only the array which is the result of removing the indexes specified in I from A, i.e. B = {a,c,e,g} (I also have I itself).
Given an index in B, can I analytically calculate the corresponding index in A? For example, for the index 3 in B the answer should be 6.
It's easy to think of a O(|A|) solution, but it's unacceptable as A can get pretty big. A O(|I|) solution should be fine. Also note that I may periodically change (more indexes removed).
Perhaps use an array that for each of the elements in B would have the number of elements before that index that were removed {0,1,2,3} then one would take the index into B and look up in that array and add that value to the index into B to get the index into A. This would take additional space equal to the size of B but would be O(1).
"I" splits original array into some slices. We can get B concatenating these slice. With I={1,3,5} we get slices {0, 0}, {2,2}, {4,4}, {6,lastA} We can create an ordered map where the keys are indices in B and the values are slices.
{ 0: {0,0}, 1: {2, 2}, 2: {4, 4}, 3: {6,lastA} }
Actually, we don't need to keep upper bound of each slice
{ 0: 0, 1: 2, 2: 4, 3: 6 }
In C++ code make look like this:
std::function<size_t (size_t)> getIndexConverter(size_t sizeOfA, std::vector<size_t> I)
{
std::map<size_t, size_t> abIndices;
size_t sliceStart = 0;
for (size_t i = 0, imax = I.size(); i < imax; ++i) {
if (sliceStart < I[i])
abIndices.emplace(sliceStart - i, sliceStart);
sliceStart = I[i] + 1;
}
if (sliceStart < sizeOfA)
abIndices.emplace(sliceStart - I.size(), sliceStart);
return [abIndices](size_t bIndex) -> size_t {
auto slice = abIndices.lower_bound(bIndex);
assert(slice != abIndices.end()); // it is impossible because of algorithm we use to construct abIndices
return bIndex - slice->first + slice->second;
};
}
full example on Ideone
This method requires additional memory equal to number of slices and executes with logarithmic time.

Resources