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 2 years ago.
Improve this question
I have a List as follows:
{1, 7, 4, 9, 5}
And I need a sorted List as {1, 4, 5, 7, 9}
I want to find the number of elements swapped to get this sorted list.
After 1st Move: {1, 4, 7, 9, 5}
After 2nd Move: {1, 4, 5, 7, 9}
Answer here would be: 2 Moves
Which is the optimum way to do it?
Using Linq is there a way?
Well, if I've understood you right you want to count deletions / insertions:
Take 7 and put it on 4th place,
Take 9 and put it on 5th place,
Take 5 and put it on 3d place
we have {1, 4, 5, 7, 9} which is sorted with 3 operations. If' it's your case you can
Sort the list:
{1, 7, 4, 9, 5} # initial
| | | | |
{1, 4, 5, 7, 9} # sorted
now build the unordered graph:
nodes: numbers (1, 7, ..., 5)
edges: between numbers in each column (initial and sorted list): 1 - 1, 7 - 4, 4 - 5, 9 - 7, 5 - 9
find out all the loops:
1 - 1 # length == 1
7 - 4 - 5 - 9 # length == 4
Sum all the length - 1 of all loops:
(1 - 1) + (4 - 1) = 3
Edit: In case of insertions (please, note that we don't swap items) only the answer is
|List| - |Longest_Non_Descreasing_Sequence(List)|
were |...| stands for number of items (Count, Length, Size etc). In your case:
|{1, 7, 4, 9, 5}| = 5
|Longest_Non_Descreasing_Sequence({1, 7, 4, 9, 5})| = |{1, 4, 5}| = 3
result = 5 - 3 = 2
Algorithm:
Find out the Longest Non Descreasing Sequence (LNDS), say, with a help of dynamic programming
Insert the rest items into it.
In your case for {1, 7, 4, 9, 5} we have {1, 4, 5} for LNDS and two items {7, 9} to insert:
{1, 7, 4, 9, 5} # initial List {1, 4, 5} is LNDS
{1, 4, 9, 5, 7} # 7 inserted into {1, 4, 5} we have {1, 4, 5, 7} as LNDS
{1, 4, 5, 7, 9} # 9 inserted into {1, 4, 5, 7}
Related
This question already has answers here:
LINQ Zip all elements
(3 answers)
How to Zip two Lists of different size to create a new list that is same as the size of the longest amongst the original lists?
(4 answers)
Closed 9 months ago.
var firstArray = new int[] { 1, 2, 3 };
var secondArray = new int[] { 4, 5, 6, 5, 9, 10};
var sum = Enumerable.Zip(first, second, (a, b) => a + b);
I want the sum to be [5, 7, 9, 5 , 9 , 10] since firstArray only have 3 elements. Any workaround? Would be better if I am using for loop for this?
Lets suppose we have two integer arrays, for example:
var A = new int[] {1, 4, 6, 12, 44};
var B = new int[] {2, 4, 6, 44, 45};
The problem is to describe a transition steps as:
Starting with the array A and continue as following:
STEP 1 : remove index = 0 // result = {4, 6, 12, 44}
STEP 2 : insert index = 0 value = 2 // result = {2, 4, 6, 12, 44}
STEP 3 : remove index = 3 // result = {2, 4, 6, 44}
STEP 4 : insert index = 4 value = 45 // result = {2, 4, 6, 44, 45}
And we now have the array B
My Question is: How can I design this algorithm in any programming language or pseudocode that generates these steps programatically for given array A and B?
common step structure is like :
STEP N : insert/remove index = i [value = v]
Of course removing all elements from A then inserting all elements from B is a solution and like that maybe there will be more than 1 solutions for given A and B, but I am looking for the transition with the fewest steps.
There is the concept of the Levenshtein distance. It is used for comparing two strings (however you can also apply the same principle to integer arrays): minimal number of edits to change one string into another, where one edit is either a deletion, an insertion or a substitution.
The problem can be efficiently solved using dynamic programming. The wiki article shows such an approach.
You can use the same approach for your problem. But since in your case you are not allowed to substitute an element (only remove and insert operations), you can even simplify the the recursion a (tiny) bit:
def edit_distance(s, len_s, t, len_t):
if len_s == 0:
return len_t
if len_t == 0:
return len_s
if s[len_s-1] == t[len_t-1]:
return edit_distance(s, len_s-1, t, len_t-1)
else:
return min(edit_distance(s, len_s-1, t, len_t) + 1,
edit_distance(s, len_s, t, len_t-1) + 1)
The code above is without dynamic programming. To make it efficient, you need to add it.
Also, the code will only compute the number of steps. If you also want to list the steps, you have to store the complete table and backtrack the solution.
Time and memory complexity of the approach: O(len_s * len_t).
Here is an example using your two arrays [1, 4, 6, 12, 44] and [2, 4, 6, 44, 45]. Here is a table that you would get if you apply dynamic programming (e.g. with a bottom first approach) for each of the possible prefix-combination of the strings.
0 1 2 3 4 5
1 2 3 4 5 6
2 3 2 3 4 5
3 4 3 2 3 4
4 5 4 3 4 5
5 6 5 4 3 4
At the bottom right we see that 4 is the optimal number of steps to make both array equal. Now we can backtrack and look at the recursive formula again. Since the last two elements are not equal, it has to be an insert/remove operation. We can see in the table the optimal number of steps for [1, 4, 6, 12], [2, 4, 6, 44, 45] is 5, and for [1, 4, 6, 12, 44], [2, 4, 6, 44] is 3. So the optimal thing here is to remove the last element of the second array, or in other words to insert 45 in the first one.
Now we can thing about the last step that resulted in [1, 4, 6, 12, 44], [2, 4, 6, 44]. Since the last elements are equal, the step is clear. We leave both of them and perform no insert or remove operation.
So what was the last step in [1, 4, 6, 12], [2, 4, 6]? The table shows that the optimal value 3 originated from the position [1, 4, 6], [2, 4, 6], which means a removing 12 in the first array.
And so on.
Interestingly there can be multiple optimal solutions. Here I show you one possible path (which corresponds exactly to your solution):
0-1 2 3 4 5
|
1 2 3 4 5 6
\
2 3 2 3 4 5
\
3 4 3 2 3 4
|
4 5 4 3 4 5
\
5 6 5 4 3-4
I have list that is guaranteed to contain sequential pairs of identical elements. Is there a way to remove half of repeating values in a list (any one element of each pair)?
Example #1:
Take:
{2, 2, 2, 2, 5, 5}
And return:
{2, 2 , 5}
Example #2:
Take:
{8, 8, 1, 1, 5, 5, 1, 1}
And return:
{8, 1, 5, 1}
There is no need to verify if elements actually comes in pairs.
If the sequence is guaranteed to be made of consecutive pairs, then this works:
values.Where((x, n) => n % 2 == 0)
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Let's say I have array which contains unique random numbers (where numbers have small possible range of 0 to 20). For example:
[6, 3, 11, 9, 4, 5]
How can I convert following array to something like this:
[3, 0, 5, 4, 1, 2]
The second array starts from 0 and ends with (array.Length-1), but placement is relative to magnitude in the first array.
How can I implement this in an efficient way in C/C++/C#? (more interested in the method)
I gave just one example. It can be really anything:
[7, 10, 0, 19, 50, 33, 45, 100]
[1, 2, 0, 3, 6, 4, 5, 7]
Smallest number from array A is 0 in array B. Biggest number in array A is (array.Length-1) in array B. Array A can be completely random (just it will never contain two or more identical numbers), but array A have to contain all numbers from 0 to array.Length-1) in same order as in array A.
int[] list1 = new[] { 7, 10, 0, 19, 50, 33, 45, 100 };
var orderedList = list1.OrderBy(x => x).ToList();
int[] list2 = list1.Select(x => orderedList.IndexOf(x)).ToArray();
EDIT
Per #Blorgbeard's request
int[] list1 = new[] { 6, 3, 11, 9, 4, 5 };
var dict = list1.OrderBy(x => x)
.Select((i, inx) => new { i, inx })
.ToDictionary(x => x.i, x => x.inx);
int[] list2 = list1.Select(x => dict[x]).ToArray();
I've tried copying arrays in such a way I can crunch data in an array with threads but obviously without splitting the array into smaller chunks (lets say 1 array -> 4 quarters (4 arrays)).
The only method I can find copies from a specified (int)start point and copies all leading data from the start to the end which if I am using multiple threads to crunch the data its nullifies the point of threading.
Here is pseudo code to show what I wish to do.
int array { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
int split1 { 0, 1, 2, 3 }
int split2 { 4, 5, 6, 7 }
int split3 { 8, 9, 10, 11 }
int split4 { 12, 13, 14, 15 }
or lets say the length of the array cant be split up evenly
int array { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }
int split1 { 0, 1, 2, 3 }
int split2 { 4, 5, 6, 7 }
int split3 { 8, 9, 10, 11 }
int split4 { 12, 13, 14, 15, 16}
The only method I can find copies from a specified (int)start point and copies all leading data from the start to the end which if I am using multiple threads to crunch the data its nullifies the point of threading.
It's a shame you didn't show which method that was. Array.Copy has various overloads for copying part of an array to another array. This one is probably the most helpful:
public static void Copy(
Array sourceArray,
int sourceIndex,
Array destinationArray,
int destinationIndex,
int length
)
Alternatively, look at Buffer.BlockCopy, which has basically the same signature - but the values are all in terms of bytes rather than array indexes. It also only works with arrays of primitives.
Another alternative would be not to create copies of the array at all - if each thread knows which segment of the array it should work with, it can access that directly. You should also look into Parallel.ForEach (and similar methods) as a way of parallelizing operations easily at a higher level.