Verify if two lists share values in C# - c#-4.0

I'd like to know if two lists share values before applying an intersection. Something like bool DoIntersect(listA, listB) would be fabulous!
This is the code I came up with:
// Person is a class with Id and Name properties
List<Person> people1;
List<Person> people2;
// Populate people1 and people2...
// My current solution (pseudocode obviously)...
if (DoIntersect(people1, people2))
{
people1 = people1.Intersect(people2)
}
else
{
/* No shared people */
throw exception;
}
// Continue with the process...

It depends on exactly what you want:
// are there any common values between a and b?
public static bool SharesAnyValueWith<T>(this IEnumerable<T> a, IEnumerable<T> b)
{
return a.Intersect(b).Any();
}
For lists that don't overlap, this will iterate through a and b each once. For lists that overlap, this will iterate all the way through a, then through b until the first overlapping element is found.
// does a contain all of b? (ignores duplicates)
public static bool ContainsAllFrom<T>(this IEnumerable<T> a, IEnumerable<T> b)
{
return !b.Except(a).Any();
}
This will iterate through a once, then will iterate through b, stopping on the first element in b not in a.
// does a contain all of b? (considers duplicates)
public static bool ContainsAllFrom<T>(this IEnumerable<T> a, IEnumerable<T> b)
{
// get the count of each distinct element in a
var counts = a.GroupBy(t => t).ToDictionary(g => g.Key, g => g.Count());
foreach (var t in b) {
int count;
// if t isn't in a or has too few occurrences return false. Otherwise, reduce
// the count by 1
if (!counts.TryGetValue(t, out count) || count == 0) { return false; }
counts[t] = count - 1;
}
return true;
}
Similarly, this will iterate through a once, then will iterate through b, stopping on the first element in b not in a.

I believe without altering the fact that you're using a List you can't get better performance.
However, if you would have 2 sorted lists to begin with (requires overhead when creating them), then you could iterate through them with complexity of O(n) in order to find out if you have shared values.
Edit:
Although original OP doesn't have 2 sorted lists, in case someone will need it, here is the implementation for checking Intersection at O(n):
public Boolean DoIntersect(SortedList<int,String> listA,SortedList<int,String> listB )
{
if (listA == null || listA.Count == 0 || listB == null || listB.Count == 0)
{
return false;
}
var keysA = listA.Keys;
var keysB = listB.Keys;
int i = 0, j = 0;
while (i < listA.Count && j < listB.Count)
{
if (keysA[i] < keysB[j])
{
i++;
}else if (keysA[i] > keysB[j])
{
j++;
}
else
{
return true;
}
}
The above approach can be used also with IEnumerable lists, given that they are sorted, with slight variation - using GetEnumerator and iterating with it.

Related

System.IndexOutOfRangeException: Array index is out of range

public static void get_sum_while (int[] num,int len)
{
int sum2,i=0;
while ( i<len)
{
sum2=sum2+num[i];
i++;
}
Console.WriteLine("The sum of the series by while loop is {0}",sum2);
}
public static int get_sum_recur (int[] num,int len)
{
int sum3;
if (len==0)
return sum3=sum3+num[0];
else
{
return sum3=num[len]+get_sum_recur(num,length-1);
}
}
}
Hello this gives sum of the series from three function the first two are okay but recursive did not give it give exception i don't where i go wrong and is it correct way to get sum by recursion?
The idea of summing a list by recursion is to sum the an element of the list with the sum of the same list without the chosen element.
sum([a,b,c,d,e]) = a + sum([b,c,d,e])
So the initial value of the result have to be set to 0.
Then choose an element, for example the first one, add it to the current result and call sum on the rest of the list with the new result.
When list is empty, end recursion.
In pseudo code, because I don't have a C# compiler, this gives :
public static int get_sum_recur(int result, int[] list) {
if (len(list)==0) {
return result; // end recursion
}
else {
return get_sum_recur(result+list[0], list[1:]);
}
}
public static main {
print(get_sum_recur(0, [1,2,3,4,5,6])
}

How to call multi argument function using ArrayList?

Im trying to call this method from SDK
public ThumborUrlBuilder crop(int top, int left, int bottom, int right) {
if (top < 0) {
throw new IllegalArgumentException("Top must be greater or equal to zero.");
}
if (left < 0) {
throw new IllegalArgumentException("Left must be greater or equal to zero.");
}
if (bottom < 1 || bottom <= top) {
throw new IllegalArgumentException("Bottom must be greater than zero and top.");
}
if (right < 1 || right <= left) {
throw new IllegalArgumentException("Right must be greater than zero and left.");
}
hasCrop = true;
cropTop = top;
cropLeft = left;
cropBottom = bottom;
cropRight = right;
return this;
}
How I can call the method if the parameters are from an Array or Map like this? Is that possible?
ArrayList arrayList = [299, 296, 301, 297]
crop(arraylist)
Java:
No you cant.
you will get this error:
Compilation Errors Detected
...
method crop in class Test cannot be applied to given types;
required: int,int,int,int
found: java.util.ArrayList<java.lang.Integer>
reason: actual and formal argument lists differ in length
Groovy:
Yes you can.
Check the sample code on groovyConsole.
def hello(int a, int b){
println "$a and $b"
}
hello(1, 2)
def param = [1,2]
hello(param)
public ThumborUrlBuilder crop(ArrayList params) {
if (params.size() != 4 ){
throw new IllegalArgumentException(...);
}
int top = params.get(0);
int left = params.get(1);
int bottom = params.get(2);
int right = params.get(3);
...
}
This is not directly possible in Java, because the function crop requires 4 parameters.
Passing the given ArrayList into the crop function would result in an error.
You could write your own function to handle the ArrayList for you like this:
public ThumboUrlBuilder special_crop(ArrayList arraylist){
crop(arraylist.get(0),arraylist.get(1),arraylist.get(2),arraylist.get(3));
}

How to concatWith using information from previous Observable for pagination

Let's say I have a blocking method with is called List<UUID> listOf(int page).
If I want to paginate something like this, one idea is to do something like this:
public Observable<UUID> allOf(int initialPage) {
return fromCallable( () -> listOf(initialPage))
.concatWith( fromCallable( () -> allOf(initialPage + 1)))
.flatMap(x -> from(x));
}
If my service doesn't use the page number but the last element of the list to find next elements, how can I achieve it with RxJava?
I would still like to obtain the effect of doing something like allOf(0).take(20) and obtain, with concatWith, the call to the second Observable when the first one has completed.
But how can I do it when I need information from the previous call?
You could use a subject to send back the next page number to the beginning of a sequence:
List<Integer> service(int index) {
System.out.println("Reading " + index);
List<Integer> list = new ArrayList<>();
for (int i = index; i < index + 20; i++) {
list.add(i);
}
return list;
}
Flowable<List<Integer>> getPage(int index) {
FlowableProcessor<Integer> pager = UnicastProcessor.<Integer>create()
.toSerialized();
pager.onNext(index);
return pager.observeOn(Schedulers.trampoline(), true, 1)
.map(v -> {
List<Integer> list = service(v);
pager.onNext(list.get(list.size() - 1) + 1);
return list;
})
;
}
#Test
public void testPager() {
getPage(0).take(20)
.subscribe(System.out::println, Throwable::printStackTrace);
}

Lock free list remove operation

I have the following problem definition:
Design a lock-free simple linked list with the following operations:
Add(item): add the node to the beginning (head) of the list
Remove(item): remove the given item from the list
Below is shown the code implemented so far:
public class List<T>
{
private readonly T _sentinel;
private readonly Node<T> _head;
public List()
{
_head = new Node<T>();
_sentinel = default(T);
}
public List(T item)
{
_head = new Node<T>(item);
_sentinel = item;
}
public void Add(T item)
{
Node<T> node = new Node<T>(item);
do
{
node.Next = _head.Next;
}
while (!Atomic.CAS(ref _head.Next, node.Next, node));
}
public void Remove(Node<T> item)
{
Node<T> next;
Node<T> oldItem = item;
if (item.Value.Equals(_sentinel))
return;
item.Value = _sentinel;
do
{
next = item.Next;
if (next == null)
{
Atomic.CAS(ref item.Next, null, null);
return;
}
} while (!Atomic.CAS(ref item.Next, next, next.Next));
item.Value = next.Value;
}
}
The head is actually a dummy (sentinel) node kept for ease of use. The practical head is actually _head.Next.
The problem is on the remove operation when trying to remove the last element of the list:
On the remove part there are two cases:
The node has a following not-null next pointer: then do the CAS operation and steal the value data of the next item removing actually the next item
The problematic case is when the element to remove is the last one in the list:
Do Atomically: If (item == oldItem and item.Next == null) then item = null where oldItem is a pointer to the item to remove;
So I want to do is in the case of removing C node:
if(C==old-C-reference and C.Next == null) then C = null => all atomically
The problem is that I have a CAS only on a single object.
How can I solve this problem atomically? Or is there a better way of doing this remove operation that I'm missing out here?
when removing B we do a trick by copying C's contents to B and removing C: B.Next = C.Next (in the loop) and B.Value = C.Value after the move succeeded
So you need to atomically modify two memory locations. CAS in .NET does not support that. You can, however, wrap those two values in another object that can be swapped out atomically:
class ValuePlusNext<T> {
T Value;
Node<T> Next;
}
class Node<T> {
ValuePlusNext<T> Value;
}
Now you can write to both values in one atomic operation. CAS(ref Value, new ValuePlusNext<T>(next.Value, next.Value.Next). Something like that.
It is strange that ValuePlusNext has the same structure that your old Node class had. In a sense you are now managing two physical linked list node for each logical one.
while (true) {
var old = item.Value;
var new = new ValuePlusNext(...);
if (CAS(ref Value, old, new)) break;
}

Comparing String.Index values

Is it possible to compare two String.Index values in Swift? I'm trying to process a string character by character, and several times I need to check if I am at the end of the string. I've tried just doing
while (currentIndex < string.endIndex) {
//do things...
currentIndex = currentIndex.successor()
}
Which complained about type conversions. Then, I tried defining and overload for < as such:
#infix func <(lhs: String.Index, rhs: String.Index) -> Bool {
var ret = true //what goes here?
return ret
}
Which gets rid of compilation errors, but I have no clue what to do in order to compare lhs and rhs properly. Is this the way I should go about using String.Index, or is there a better way to compare them?
The simplest option is the distance() function:
var string = "Hello World"
var currentIndex = string.startIndex
while (distance(currentIndex, string.endIndex) >= 0) {
println("currentIndex: \(currentIndex)")
currentIndex = currentIndex.successor()
}
Beware distance() has O(N) performance, so avoid it for large strings. However, the entire String class doesn't currently handle large strings anyway — you should probably switch to CFString if performance is critical.
Using an operator overload is a bad idea, but just as a learning exercise this is how you'd do it:
var string = "Hello World"
var currentIndex = string.startIndex
#infix func <(lhs: String.Index, rhs: String.Index) -> Bool {
return distance(lhs, rhs) > 0
}
while (currentIndex < string.endIndex) {
currentIndex = currentIndex.successor()
}
String indexes support = and !=. String indexes are an opaque type, not integers and can not be compared like integers.
Use: if (currentIndex != string.endIndex)
var currentIndex = string.startIndex
while (currentIndex != string.endIndex) {
println("currentIndex: \(currentIndex)")
currentIndex = currentIndex.successor()
}
I believe this REPL/Playground example should illuminate what you (and others) need to know about working with the String.Index concept.
// This will be our working example
let exampleString = "this is a string"
// And here we'll call successor a few times to get an index partway through the example
var someIndexInTheMiddle = exampleString.startIndex
for _ in 1...5 {
someIndexInTheMiddle = someIndexInTheMiddle.successor()
}
// And here we will iterate that string and detect when our current index is relative in one of three different possible ways to the character selected previously
println("\n\nsomeIndexInTheMiddle = \(exampleString[someIndexInTheMiddle])")
for var index: String.Index = exampleString.startIndex; index != exampleString.endIndex; index = index.successor() {
println(" - \(exampleString[index])")
if index != exampleString.startIndex && index.predecessor() == someIndexInTheMiddle {
println("current character comes after someIndexInTheMiddle")
} else if index == someIndexInTheMiddle {
println("current character is the one indicated by someIndexInTheMiddle")
} else if index != exampleString.endIndex && index.successor() == someIndexInTheMiddle {
println("Current character comes before someIndexinTheMiddle")
}
}
Hopefully that provides the necessary information.
Whatever way you decide to iterator over a String, you will immediately want to capture the iteration in a function that can be repeatedly invoked while using a closure applied to each string character. As in:
extension String {
func each (f: (Character) -> Void) {
for var index = self.startIndex;
index < self.endIndex;
index = index.successor() {
f (string[index])
}
}
}
Apple already provides these for C-Strings and will for general strings as soon as they get character access solidified.

Resources