Find duplicates between arrays - c#

Assume you are given two arrays of integers of constant length which is 3, and you are always sure that two elements of the given two arrray will have same values.
so assume array A has three values: a, b, c.
and array B has three values: d, e, f.
we are sure that two of the values will be same. we are asked to put these four different values in an array of size 4, such that output array C, should have in indices 1 and 2 the same values from arrays A and B. and at indices 0 and 3 it should have the different values of array A and B. i have implemented it, but really not satisfied with this solution... does anyone has better solution idea? except the one that would put my counters in array... :)
int[] a = { 1, 201, 354 };
int[] b = { 404, 201, 354 };
int[] c = new int[4];
for (int i = 0; i < c.Length; i++)
{
Console.WriteLine(c[i]);
}

I'm sorry, I re-read more closely and I think this is what you want. Please advise. :)
int[] same = a.Intersect(b).ToArray(); ;
int[] diff = a.Union(b).Except(same).ToArray();
int[] c = new int[] { diff[0], same[0], same[1], diff[1] };

What you are looking for is just a set of the two arrays (set contains every element once at most). The solution in c++:
#include <set>
int main () {
int a[] = { 1,2,3 };
int b[] = { 4,2,3 };
std::set<int> s(a, a+3);
s.insert(b, b+3);
}

If you have LINQ at your disposal, the following code will suffice:
int[] c = a.Union(b).ToArray();
Union checks for duplicates, so no further checking is necessary:
Returns: An
System.Collections.Generic.IEnumerable
that contains the elements from both
input sequences, excluding duplicates.

Replace
// IRQ. 20100211. Deleted unncessary code
with
var c = a.Concat(b).Distinct().ToArray();
Update:
New one:
var same = a.Intersect(b);
var c = a.Except(same).Concat(same).Concat(b.Except(same)).ToArray();
or these
var c = a.Except(b).Concat(a.Intersect(b)).Concat(b.Except(a));
var c = a.Except(b).Concat(a).Concat(b).Distinct();

Here a cool solution in C(++)
int a[3], b[3]; /* the two arrays */
int c[4]; /* target */
int s=0, t=0, k;
int i;
for (i=0;i<3;i++) { k = a[i]-b[i]; s += k; t += k*(a[i]+b[i]); }
/* At this point s is the difference of the two distinct elements
and t is the difference of their squares, i.e. s = x - y and t = x^2 - y^2
because (x-y)(x+y) = x^2-yx+yx-y^2 = x^2-y^2
Because the two elements are distinct, s != 0 and we can easily divide t
by s to get (x + y), from which then we have
s == x - y
t == x + y
i.e. x = (s+t)/2 and y=(t-s)/2 */
t /= s;
int x = (s + t) / 2;
int y = (t - s) / 2;
/* Now x, y are the distinct elements, x from array a and y from array b */
/* Fill in the results */
c[0] = x;
c[3] = y;
/* If a[0] is non-shared, then a[1] must be the first shared element; otherwise a[0] */
c[1] = (a[0] == x ? a[1] : a[0]);
/* If a[2] is non-shared, then a[1] must be the last shared element; otherwise a[2] */
c[2] = (a[2] == x ? a[1] : a[2]);
Example: a = {1, 3, 5}, b = {3, 5, 2}
s = (1-3)+(3-5)+(5-2) = -2-2+3 = -1
t = (1-3)*(1+3)+(3-5)*(3+5)+(5-2)*(5+2) = -8-16+21 = -3
t / s = 3
x = (-1 + 3) / 2 = 1
y = (3 - (-1)) / 2 = 2
c[0] = 1
c[3] = 2
c[1] = 3
c[2] = 5
so c gets the value {1,3,5,2}, as desired!
For fun, here a compacter version:
/* Declarations */
int a[3], b[3], c[4];
int s = 0, t = 0, k, i;
/* Actual algorithm */
for (i = 0; i < 3; i++) { s += (k = a[i]-b[i]); t += k * (a[i]+b[i]); }
t /= s;
c[0] = (s + t) >> 1;
c[3] = (t - s) >> 1;
c[1] = (a[0] == x ? a[1] : a[0]);
c[2] = (a[2] == x ? a[1] : a[2]);
Note that coolly enough if the problem is generalized so that n-1 elements are shared and there is one unique element in both arrays, this is an O(n) algorithm, whereas set intersection and/or union based algorithms in general are O(n log n) :)

Instead of counter1, counter2, counter3:
counter[3];
A lot of things get easier from there. You can refer to everything in loops, to start with.

I'm pretty sure I don't understand the question.
You say:
we are sure that two of the values will be same. we are asked to put these four different values
Which four different values are you referring to? The two that are the same? Because that's what the word "these" refers to.
Do you mean: Take the 4 unique values and put them into an array?
So that:
1, 2, 3
2, 3, 4
Becomes:
1, 2, 3, 4?
That's easy:
int[] c = a.Concat(b).Distinct().ToArray();
This uses the Linq extension methods of .NET 3.5. If you're not on .NET 3.5, you can do this:
Dictionary<int, int> c1 = new Dictionary<int, int>();
foreach (var x in a)
c1[x] = 1;
foreach (var x in b)
c1[x] = 1;
int[] c = new List<int>(c1.Keys).ToArray();
Now, if you need the order to be this:
The first value that only occured once
The first value that occured twice
The second value that occured twice
The second value that only occured once
Then I'm afraid I don't have a one-liner for you, will have to think about it some more.
Might I ask what the context is? Why this requirement?

I came up with this as a first draft, but I think it can need some improvement. It also doesn't fulfill the requirement of having the duplicates at position 1 and 2 and the unique numbers at 0 and 3 in the array. I thought I'd post it anyway, so you can get an idea of how this can look like:
int[] a = { 1, 201, 354 };
int[] b = { 404, 201, 354 };
int[] c = new int[ 4 ];
// Start by just copying over one of the arrays completely.
a.CopyTo( c, 0 );
// Loop through b and compare each number against each
// each number in a.
foreach( int i in b )
{
// Assume that you're not dealing with a duplicate
bool found = true;
foreach( int j in a )
{
// If you find a duplicate, set found to false
if( i == j )
{
found = false;
}
}
// If you haven't found a duplicate this is the
// number you want - add it to the array.
if (found == true)
{
c[3] = i;
}
}

bool isUsed[6]={true, true, true, true, true, true};
int values[6];
int valuesCount = 0;
int i,j;
for( i = 0 ; i < 3 ; i++)
{
bool goodValue = true;
for ( j = 0; j < valuesCount; j++)
{
if(values[j] == a[i])
{
isUsed[j] = false;
goodValue = false;
break;
}
}
if(goodValue)
{
values[valuesCount++]=a[i];
}
}
//same for b[i]
for( i = 0 ; i < valuesCount; i++)
{
if( isUsed[i] ) printf("%i ", values[i]);
}

This part
if (a[0] == b[0]) { counter0++; }
if (a[0] == b[1]) { counter0++; }
if (a[0] == b[2]) { counter0++; }
if (a[1] == b[0]) { counter1++; }
if (a[1] == b[1]) { counter1++; }
if (a[1] == b[2]) { counter1++; }
if (a[2] == b[0]) { counter2++; }
if (a[2] == b[1]) { counter2++; }
if (a[2] == b[2]) { counter2++; }
Could probably be rewritten as
for (i=0; i<3; i++)
{
for (j=0; j<3; j++)
{
switch(i)
{
case 0:
if (a[i] == b[j]) { counter0++; }
break;
case 1:
if (a[i] == b[j]) { counter1++; }
break;
case 2:
if (a[i] == b[j]) { counter2++; }
break;
}
}
}
The other part with the other counters should be written similarly. Then you could maybe refactor this into a separate method and just pass the arrays and counters to it.
Another option could be LINQ, but I'm not sure exactly how to write something like this.
(Haven't tried compiling this, but is the idea clear?)
UPDATE:
If you could put the counters in an array, this might work:
for (i=0; i<3; i++)
{
for (j=0; j<3; j++)
{
if (a[i] == b[j]) { counters[i]++; }
}
}

I am trying to give a short answer. However it assumes that input will be correct.
int c1, c2, i;
c1 = a[0] == b[0] ? 0
: (a[0] == b[1] ? 1 : 2); // index of a[0] in array 'b'
c2 = a[1] == b[0] ? 0
: (a[1] == b[1] ? 1 : 2); // index of a[1] in array 'b'
for(i=0; i<2; i++)
Console.WriteLine(a[i]);
Console.WriteLine(b[3-c1-c2]); // looks quite hacky but it is actually element of 'b' not in array 'a'

Here's some simple code, but it assumes that the values in a and b are always positive.
int[] a = { 1, 201, 354 };
int[] b = { 404, 201, 354 };
int[] c = { -1, -1, -1, -1};
for(int i = 0; i < 3; i++){
int notfound = 1;
for(int j = 0; j < 3; j++){
if(b[j] == -1) continue;
if(a[i] == b[j]){
b[j] = -1;
if(c[1] == -1)
c[1] = a[i];
else
c[2] = a[i];
notfound = 0;
break;
}
}
if(notfound)
c[0] = a[i];
}
int k = 0;
while(b[k++] == -1);
c[3] = b[k];
I haven't tested it, but hopefully you get the idea. This uses very little extra space (just the space for notfound, which could be made a boolean, and the index variables) and should be quite fast.

int[] a = { 204, 534, 1 };
int[] b = { 204, 534, 401 };
int[] c = new int[4];
int x = 3, y = 3, k = 1;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
if (a[i] == b[j]) {
c[k++] = a[i];
x -= i;
y -= j;
break;
}
c[0] = a[x];
c[3] = b[y];

Sapph provided an answer that is about as clean as it gets, but here is one if performance is extremely important. The .NET array bounds checking will probably add some overhead, but in C this compiles down to 64 instructions with no branches.
int[] a = { 204, 534, 1 };
int[] b = { 204, 534, 401 };
int[] c = new int[4];
// pick the value from a that is not in b for c[0]
// a[0] not in b is implied by a[1] in b and a[2] in b
int a1_not_in_b = Convert.ToInt32(a[1] != b[0] & a[1] != b[1] & a[1] != b[2]);
int a2_not_in_b = Convert.ToInt32(a[2] != b[0] & a[2] != b[1] & a[2] != b[2]);
// bitfield of 2 bit values equivalent to the array {0,1,2,0,1}
int idxs = 0 | 1 << 2 | 2 << 4 | 0 << 6 | 1 << 8;
// if a[1] not in b start at 1, if a[2] not in b start at 2, else start at 0
idxs >>= 2*a1_not_in_b | 4*a2_not_in_b;
c[0] = a[(idxs >> 0) & 3];
c[1] = a[(idxs >> 2) & 3];
c[2] = a[(idxs >> 4) & 3];
// pick the value from b that is not in a
// b[0] not in a is implied by b[1] in a and b[2] in a
int b1_not_in_a = Convert.ToInt32(a[0] != b[1] & a[1] != b[1] & a[2] != b[1]);
int b2_not_in_a = Convert.ToInt32(a[0] != b[2] & a[1] != b[2] & a[2] != b[2]);
c[3] = b[b1_not_in_a | 2*b2_not_in_a];

Faster?
using System;
using System.Linq;
using sw = System.Diagnostics.Stopwatch;
class Program
{
static void Main()
{
int[] a = new int[] { 1, 2, 3 }, // try: a={1,2,2} b={2,2,3}
b = new int[] { 4, 2, 3 }, c = new int[4];
sw sw = sw.StartNew();
for (int i = 5000000; i > 0; i--) { dssd1(a, b, c); dssd1(b, a, c); }
Console.Write(sw.ElapsedMilliseconds);
Console.Read();
}
static void dssd0(int[] a, int[] b, int[] c) // 6710 ms.
{
int[] s = a.Intersect(b).ToArray(); // same
int[] d = a.Union(b).Except(s).ToArray(); // diff
c[0] = d[0]; c[1] = s[0]; c[2] = s[1]; c[3] = d[1];
}
static void dssd1(int[] a, int[] b, int[] c) // 61 ms.
{
if (a[0] != b[0] && a[0] != b[1] && a[0] != b[2])
{ c[0] = a[0]; c[1] = a[1]; c[2] = a[2]; goto L0; }
if (a[1] != b[0] && a[1] != b[1] && a[1] != b[2])
{ c[0] = a[1]; c[1] = a[0]; c[2] = a[2]; goto L0; }
c[0] = a[2]; c[1] = a[0]; c[2] = a[1];
L0: if (b[0] != c[1] && b[0] != c[2]) { c[3] = b[0]; return; }
if (b[1] != c[1] && b[1] != c[2]) { c[3] = b[1]; return; }
c[3] = b[2];
}
}
Fastest?
L0: c[3] = b[0] != c[1] && b[0] != c[2] ? b[0] : // 49 ms.
b[1] != c[1] && b[1] != c[2] ? b[1] : b[2];

How about this?
private static int[] FindDuplicates(int[] arrA,int[] arrB)
{
var aList=new List<int>();
Array.Sort(arrA);
Array.Sort(arrB);
for(int i=0;i<arrA.Length;i++)
{
if(arrB.Contains(arrA[i]))
{
aList.Add(arrA[i]);
}
}
return aList.ToArray();
}

Related

Value was either too large or too small for a UInt64.'

My codes are like below.
I just want to try to convert number to binary and summarize binary numbers as if they are decimal ones, e.g. the desired outcome for 3 is 22:
1 -> 1
2 -> 10
3 -> 11
-------
22 == 1 + 10 + 11
But number array is growing and the code blowing :)
static void Main(string[] args)
{
long deger = 1;
for (int i = 0; i < 1000000; i++)
{
deger *= (deger + 1);
int result = solve(deger);
Console.WriteLine(result);
}
}
public static int solve(long a)
{
ulong[] lastValue = new ulong[a];
for (int i = 1; i < a; i++)
{
var binary = Convert.ToString(i, 2);
lastValue[i] = Convert.ToUInt64(binary);// this part gives an error
}
var result = lastValue.Aggregate((t, c) => t + c);
return (int)result;
}
Well, UInt64 is not large enough; you can try either BigInteger or you may sum up strings:
private string MyBinarySum(string left, string right) {
var x = left
.PadLeft(Math.Max(left.Length, right.Length) + 1, '0')
.Reverse()
.Select(c => c - '0')
.ToArray();
var y = right
.PadLeft(Math.Max(left.Length, right.Length) + 1, '0')
.Reverse().Select(c => c - '0')
.ToArray();
StringBuilder sb = new StringBuilder(left.Length);
int shift = 0;
for (int i = 0; i < x.Length; ++i) {
int v = x[i] + y[i] + shift;
shift = v / 2;
v = v % 2;
sb.Append((char)('0' + v));
}
return String.Concat(sb.ToString().TrimEnd('0').Reverse());
}
Then, with a help of Linq
var result = Enumerable
.Range(0, 1000000)
.Select(item => Convert.ToString(item, 2))
.Aggregate((sum, item) => MyBinarySum(sum, item));
Console.Write(result);
Outcome:
111010001101010010010101110011011100000
which is beyond UInt64.MaxValue == 18446744073709551615
Look at UInt64.MaxValue and UInt64.MinValue.
They defined as 18446744073709551615 and 0 corresponding.

Meaning of rational transfer function underlying MATLAB filter or Scipy.signal filter

I have some MATLAB code that filters an input signal using filter:
CUTOFF = 0.05;
FS = 5000;
[b, a] = butter(1, CUTOFF / (FS / 2), 'high');
% b = [0.99996859, -0.99996859]
% a = [1.0, -0.99993717]
dataAfter = filter(b, a, dataBefore);
I'm trying to convert this code to C#. I have already got the butter function to work pretty fast, but now I'm stuck converting the filter function.
I have read the MATLAB filter documentation and Python Scipy.signal filter documentation, but there is a term present in the transfer function definition that I don't understand.
Here is the "rational transfer function" definition from the linked documentation:
b[0] + b[1]z^(-1) + ... + b[M]z^(-M)
Y(z) = _______________________________________ X(z)
a[0] + a[1]z^(-1) + ... + a[N]z^(-N)
Correct me if i'm wrong, but z is the current element of input data, and Y(z) is the output?
If the above this is true, what is X(z) in this equation?
I want to understand this to implement it in C#, if there is an equivalent option then please enlighten me.
In the More About section of the matlab docs as you pointed out, they describe:
The input-output description of the filter operation on a vector in the Z-transform domain is a rational transfer function. A rational transfer function is of the form,
b[0] + b[1]z^(-1) + ... + b[M]z^(-M)
Y(z) = _______________________________________ X(z)
a[0] + a[1]z^(-1) + ... + a[N]z^(-N)
Rearranging:
Y(z) b[0] + b[1]z^(-1) + ... + b[M]z^(-M)
H(z) = ____ = _______________________________________
X(z) a[0] + a[1]z^(-1) + ... + a[N]z^(-N)
Thus, X(z) is the z-domain transform of the input vector x (seeDigital Filter). It is important to mention that, also in the docs they give an alternate representation of the transfer function as a difference equation
Which lends itself better to be ported into code. One possible implementation in C#, could be (using this answer as reference)
public static double[] Filter(double[] b, double[] a, double[] x)
{
// normalize if a[0] != 1.0. TODO: check if a[0] == 0
if(a[0] != 1.0)
{
a = a.Select(el => el / a[0]).ToArray();
b = b.Select(el => el / a[0]).ToArray();
}
double[] result = new double[x.Length];
result[0] = b[0] * x[0];
for (int i = 1; i < x.Length; i++)
{
result[i] = 0.0;
int j = 0;
if ((i < b.Length) && (j < x.Length))
{
result[i] += (b[i] * x[j]);
}
while(++j <= i)
{
int k = i - j;
if ((k < b.Length) && (j < x.Length))
{
result[i] += b[k] * x[j];
}
if ((k < x.Length) && (j < a.Length))
{
result[i] -= a[j] * result[k];
}
}
}
return result;
}
Driver:
static void Main(string[] args)
{
double[] dataBefore = { 1, 2, 3, 4 };
double[] b = { 0.99996859, -0.99996859 };
double[] a = { 1.0, -0.99993717 };
var dataAfter = Filter(b1, a, dataBefore);
}
Output
Matlab dataAfter = [0.99996859 1.999874351973491 2.999717289867956 3.999497407630634]
CSharp dataAfter = [0.99996859 1.9998743519734905 2.9997172898679563 3.999497407630634]
UPDATE
If the coefficient vectors a and b have a fixed length of 2 the filtering function can be simplified to:
public static double[] Filter(double[] b, double[] a, double[] x)
{
// normalize if a[0] != 1.0. TODO: check if a[0] == 0
if (a[0] != 1.0)
{
a = a.Select(el => el / a[0]).ToArray();
b = b.Select(el => el / a[0]).ToArray();
}
int length = x.Length;
double z = 0.0;
double[] y = new double[length]; // output filtered signal
double b0 = b[0];
double b1 = b[1];
double a1 = a[1];
for (int i = 0; i < length; i++)
{
y[i] = b0 * x[i] + z;
z = b1 * x[i] - a1 * y[i];
}
return y;
}

Transform recursive method into non-recursive C#

I'm struggling with dynamic programming and desperately need help! I would very appreciate it. For hours I've been trying to transform a recursive method into a non-recursive one, but was unable to do that. My initial task was to write two algorithms for a recurrent equation. The first method being a recursive method, the other using a loop and storing the data.
There are two integers, n and w, and two integer arrays s[n] and p[n]. Need to find the return value of a recursive method G1(n, w) then create method G2(n, w) which would complete the same task, but it has to use loops instead of recursion.
private static int G1(int k, int r)
{
if (k == 0 || r == 0)
{
return 0;
}
if (s[k - 1] > r)
{
return G1(k - 1, r);
}
return Max(G1(k - 1, r), p[k - 1] + G1(k - 1, r - s[k - 1]));
}
I found a possible solution for C#, but I couldn't apply it for my equation:
A similar task (RECURSION)
A similar task (LOOP)
This is my code and initial data, but I can't get it to work:
n = 3;
w = 3;
s = new List<int>{ 2, 3, 8 };
p = new List<int> { 1, 3, 5 };
private static int G2(int k, int r)
{
List<Tuple<int, int, int>> data = new List<Tuple<int, int, int>>();
data.Add(new Tuple<int, int, int>(0, 0, 0));
do
{
if (data[0].Item1 == 0 || data[0].Item2 == 0)
{
data[0] = new Tuple<int, int, int>(data[0].Item1, data[0].Item2, 0);
}
else
{
if (s[data[0].Item1 - 1] > data[0].Item2)
{
data.Add(new Tuple<int, int, int>(data[0].Item1 - 1, data[0].Item2, data[0].Item3));
}
if (data[0].Item1 + 1 >= k)
{
data.Add(new Tuple<int, int, int>(data[0].Item1 - 1, data[0].Item2, data[0].Item3));
}
if (data[0].Item2 + 1 >= r)
{
data.Add(new Tuple<int, int, int>(data[0].Item1 - 1, data[0].Item2 - s[data[0].Item1 - 1], data[0].Item3 + p[data[0].Item1 - 1]));
}
}
Console.WriteLine($"DEBUG: current k: {data[0].Item1} current r: {data[0].Item2} current result: {data[0].Item3}");
data.RemoveAt(0);
} while (data.Count > 0 && data.Count(entry => entry.Item1 == k && entry.Item2 == r) <= 0);
return data.First(entry => entry.Item1 == k && entry.Item2 == r).Item3;
}
There is a common solution. You should create a 2D arry by the size of k x r. Then, loop on this array in diagonal zigzag order to fill the value (in bottom-up order, like the following image).
At the end of the filling the value of the 2d array, you will have the value of G2(k,r). You can find the implementation of G2(k,r) in the below.
int G2(int k, int r)
{
int[,] values = new int[k + 1,r + 1];
var maxDim = Max(k + 1,r + 1);
for( int h = 1 ; h < maxDim * 2 ; h++ ) {
for( int j = 0 ; j <= h ; j++ ) {
int i = h - j;
if( i <= k && j <= r && i > 0 && j > 0 ) {
if (s[i - 1] > j)
{
values[i,j] = values[i - 1, j];
}
else
{
values[i,j] = Max(values[i - 1, j], p[i - 1] + values[i - 1, j - s[i - 1]]);
}
}
}
}
return values[k , r];
}

Rotating right an array of int in c#?

I've got an homework assignment:
need to implement a function (RotateRight) that gets an array of INT and a number:
int[] res = RotateRight(new int[] { 1, 2, 3, 4, 5, 6 }, 2);
//so then res will be {5,6,1,2,3,4}
and return the array after rotating all of the items to the right according to the number that been given, In our case 2.
And I have to do this efficiently in terms of memory space.
my best idea is:
if the number that been given is x, to use a new int[] tmpArray in the size of x to copy all the last x items to it. then with a for loop to shift all the rest of the int to the right.
And in the end to copy the items in the tmpArray to the begining of the original array.
Thanks in advance for any advice or help
You can use the beauty of the Linq langage to return an IEnumerable without dealing with array size:
/// <summary>
/// Get c = a mod (b) with c in [0, b[ like the mathematical definition
/// </summary>
public static int MathMod(int a, int b)
{
int c = ((a % b) + b) % b;
return c;
}
public static IEnumerable<T> ShiftRight<T>(IList<T> values, int shift)
{
for (int index = 0; index < values.Count; index++)
{
yield return values[MathMod(index - shift, values.Count)];
}
}
Usage :
[TestMethod]
public void TestMethod1()
{
var res = ShiftRight(new [] { 1, 2, 3, 4, 5, 6 }, 2).ToArray();
Assert.IsTrue(res.SequenceEqual(new[] { 5, 6, 1, 2, 3, 4 }));
}
Most memory possible makes no sense, you probably mean as little memory as possible? If so you should swap each item in the array using XOR, i.e:
var a = 2096;
var b = 842390;
a ^= b;
b ^= a;
a ^= b;
would swap these numbers.
EDIT
Code to do the whole thing in place:
public static void RotateRight(int[] input, int right)
{
for (var i = 0; i < right; i += 1)
{
RotateRightOne(input);
}
}
public static void RotateRightOne(int[] input)
{
var last = input.Length - 1;
for (var i = 0; i < last; i += 1)
{
input[i] ^= input[last];
input[last] ^= input[i];
input[i] ^= input[last];
}
}
Usage:
var arr = new[] {1, 2, 3, 4, 5, 6};
RotateRight(arr, 2);
As Servy points out, this is only for integers
Don't know C#, but here are two C++ versions, both in place, the first (rotate) does the minimum possible number of element moves by exploiting the cyclic structure of the rotation permutation, the second (rotate_k) just does 2*n moves for an array of length n. In both versions it's used that rotate right by k is the same as rotate left by n - k % n, so they in fact do the equivalent left rotation.
#include <iostream>
#include <vector>
#include <algorithm>
void
rotate (size_t k, std::vector<int> &a) {
size_t n = a.size();
k = n - k % n;
size_t m = n;
size_t i = 0;
while (m > 0) {
int t = a[i];
size_t j = i;
while (i != (j + k) % n) {
a[j] = a[(j + k) % n];
j = (j + k) % n;
--m;
}
a[j] = t;
--m;
++i;
}
}
void
rotate_k (size_t k, std::vector<int> &a) {
size_t n = a.size();
k = n - k % n;
std::reverse (a.begin(), a.end());
std::reverse (a.begin(), a.begin() + n - k);
std::reverse (a.begin() + n - k, a.end());
}
int
main () {
std::vector<int> a = { 1, 2, 3, 4, 5, 6, 7, 8, 9};
rotate (12, a);
for (auto i : a)
std::cout << i << " ";
std::cout << std::endl;
}
You just need to figure out the final index for each element after rotating it k times rather than actually rotating it k times.
This worked for me:
for(int i=0;i<a.Length;i++){
rotated[(k+i)%(a.Length)]=a[i];
}
Here's a quick sample on rotating an array A right K steps:
var splitPoint=A.Length-(K%A.Length);
var result=new int[A.Length];
int idx=0;
for(var pos=0;pos<A.Length;pos++)
{
if(pos<A.Length-splitPoint)
{
result[pos]=A[splitPoint+pos];
}
else
{
result[pos]=A[idx];
idx++;
}
}
return result;
C# 8 now has Indices and Ranges
Rotate Right...
int[] r = t[1..].Concat(t[0..1]).ToArray();
Rotate Left...
int[] r = t[^1..^0].Concat(t[..^1]).ToArray();
in place of the "1" above, a variable can also be used: int[] r = t[amt..].Concat(t[0..amt]).ToArray();

find set bits positions in a byte

I was tyring to create a sparse octree implementation like the people at nVidia ("Efficient Sparse Voxel Octrees") were doing for their voxel things when I came across this issue:
I have a bitfield of type byte (so 8 bits only) that tells me where the leafs of the octree are (1 says leaf, 0 means no leaf, 8 nodes attached --> 8 bit). What I want to do now is returning an array of the leaf positions. My current implementation is using a while loop to find out if the LSB is set. The input is shifted by 1 afterwards. So here's how I do that:
int leafposition = _leafmask & _validmask;
int[] result = new int[8];
int arrayPosition = 0;
int iteration = 0;
while ( leafposition > 0 )
{
iteration++; //nodes are not zero-indexed ... ?
if ( (leafposition & 1) == 1 ) // LSB set?
{
result.SetValue( iteration, arrayPosition );
arrayPosition++;
};
leafposition = leafposition >> 1;
}
return result;
This is not looking elegant and has two things that are disturbing:
This while loop mimics a for loop
the result array will most likely be smaller that 8 values, but resizing is costly
I expect the result to be like [2,4,6] for 42 (0010 1010).
Can anyone provide a more elegant solution that is still readable?
Result
I am using a function for the octree leaf count I implemented earlier to set the array to an appropriate size.
If you're going after code conciseness, I would use this:
int[] result = new int[8];
byte leafposition = 42;
int arrayPosition = 0;
for (int iteration = 0; iteration < 8; ++iteration)
if ((leafposition & (1 << iteration)) != 0)
result[arrayPosition++] = iteration + 1; // one-indexed
If you're going after performance, I would use a pre-populated array (of 256 entries). You can either generate this statically (at compile-time) or lazily (before calling your method the first time).
int[][] leaves =
{
/* 00000000 */ new int[] { },
/* 00000001 */ new int[] { 1 },
/* 00000010 */ new int[] { 2 },
/* 00000011 */ new int[] { 1, 2 },
/* 00000100 */ new int[] { 3 },
/* 00000101 */ new int[] { 1, 3 },
/* 00000110 */ new int[] { 2, 3 },
/* 00000111 */ new int[] { 1, 2, 3 },
/* 00001000 */ new int[] { 4 },
/* 00001001 */ new int[] { 1, 4 },
/* ... */
};
byte leafposition = 42;
int[] result = leaves[leafposition];
Edit: If you're using the lookup table and can afford a one-time initialization (that will be amortized through many subsequent uses), I would suggest creating it dynamically (rather than bloating your source code). Here's some sample code in LINQ; you can use the loop version instead.
int[][] leaves = new int[256][];
for (int i = 0; i < 256; ++i)
leaves[i] = Enumerable.Range(0, 8)
.Where(b => (i & (1 << b)) != 0)
.Select(b => b + 1)
.ToArray();
Here's a C-style solution that uses __builtin_ffs
int arrayPosition = 0;
unsigned int tmp_bitmap = original_bitfield;
while (tmp_bitmap > 0) {
int leafposition = __builtin_ffs(tmp_bitmap) - 1;
tmp_bitmap &= (tmp_bitmap-1);
result[arrayPosition++] = leafposition;
}
how about,
public static IEnumerable<int> LeafPositions(byte octet)
{
for (var i = 1; octet > 0; octet >>= 1, i++)
{
if ((octet & 1) == 1)
{
yield return i;
}
}
}
or, easier to read in my opinion.
IEnumerable<int> LeafPositions(byte octet)
{
if ((octet & 1) == 1) yield return 1;
if ((octet & 2) == 2) yield return 2;
if ((octet & 4) == 4) yield return 3;
if ((octet & 8) == 8) yield return 4;
if ((octet & 16) == 16) yield return 5;
if ((octet & 32) == 32) yield return 6;
if ((octet & 64) == 64) yield return 7;
if ((octet & 128) == 128) yield return 8;
}
Or, going to extremes
IEnumerable<int> LeafPositions(byte octet)
{
switch (octet)
{
case 1:
yield return 1;
break;
case 2:
yield return 2;
break;
case 3:
yield return 1;
yield return 2;
break;
...
case 255:
yield return 1;
yield return 2;
yield return 3;
yield return 4;
yield return 5;
yield return 6;
yield return 7;
yield return 8;
break;
}
yield break;
}

Categories

Resources